Skip to content

Commit

Permalink
Precompile and reuse regular expressions (#33)
Browse files Browse the repository at this point in the history
* Bump up JUnit version

* Reuse precompiled regex patterns
  • Loading branch information
c00ler authored Nov 23, 2022
1 parent a279af3 commit 82cf585
Show file tree
Hide file tree
Showing 5 changed files with 27 additions and 26 deletions.
2 changes: 1 addition & 1 deletion pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@

<javadoc.dir>docs/javadoc</javadoc.dir>

<junit.version>4.12</junit.version>
<junit.version>4.13.2</junit.version>

<maven.source.plugin>3.0.1</maven.source.plugin>
<maven.javadoc.plugin>3.2.0</maven.javadoc.plugin>
Expand Down
2 changes: 1 addition & 1 deletion src/main/java/io/github/cdimascio/dotenv/Dotenv.java
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ static Dotenv load() {
Set<DotenvEntry> entries();

/**
* Returns the set of {@link DotenvEntry}s matching the the filter
* Returns the set of {@link DotenvEntry}s matching the filter
* @param filter the filter e.g. {@link Dotenv.Filter}
* @return the set of {@link DotenvEntry}s for environment variables matching the {@link Dotenv.Filter}
*/
Expand Down
12 changes: 6 additions & 6 deletions src/main/java/io/github/cdimascio/dotenv/DotenvBuilder.java
Original file line number Diff line number Diff line change
Expand Up @@ -85,17 +85,17 @@ static class DotenvImpl implements Dotenv {
private final Map<String, String> envVars;
private final Set<DotenvEntry> set;
private final Set<DotenvEntry> setInFile;
private final Map<String, String> envVarsInFile;
public DotenvImpl(List<DotenvEntry> envVars) {
this.envVarsInFile = envVars.stream().collect(toMap(DotenvEntry::getKey, DotenvEntry::getValue));
this.envVars = new HashMap<>(this.envVarsInFile);
System.getenv().forEach(this.envVars::put);
Map<String, String> envVarsInFile = envVars.stream()
.collect(toMap(DotenvEntry::getKey, DotenvEntry::getValue));
this.envVars = new HashMap<>(envVarsInFile);
this.envVars.putAll(System.getenv());

this.set =this.envVars.entrySet().stream()
this.set = this.envVars.entrySet().stream()
.map(it -> new DotenvEntry(it.getKey(), it.getValue()))
.collect(collectingAndThen(toSet(), Collections::unmodifiableSet));

this.setInFile =this.envVarsInFile.entrySet().stream()
this.setInFile = envVarsInFile.entrySet().stream()
.map(it -> new DotenvEntry(it.getKey(), it.getValue()))
.collect(collectingAndThen(toSet(), Collections::unmodifiableSet));
}
Expand Down
33 changes: 18 additions & 15 deletions src/main/java/io/github/cdimascio/dotenv/internal/DotenvParser.java
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
import java.util.ArrayList;
import java.util.List;
import java.util.function.Function;
import java.util.function.Predicate;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

Expand All @@ -16,14 +17,18 @@
* (Internal) Parses .env file
*/
public class DotenvParser {

private static final Pattern WHITE_SPACE_REGEX = Pattern.compile("^\\s*$"); // ^\s*${'$'}
private static final Pattern DOTENV_ENTRY_REGEX = Pattern.compile("^\\s*([\\w.\\-]+)\\s*(=)\\s*(.*)?\\s*$"); // ^\s*([\w.\-]+)\s*(=)\s*(.*)?\s*$

private final DotenvReader reader;
private final boolean throwIfMissing;
private final boolean throwIfMalformed;

private final Function<String, Boolean> isWhiteSpace = s -> matches("^\\s*$", s); // ^\s*${'$'}
private final Function<String, Boolean> isComment = s -> s.startsWith("#") || s.startsWith("////");
private final Function<String, Boolean> isQuoted = s -> s.startsWith("\"") && s.endsWith("\"");
private final Function<String, DotenvEntry> parseLine = s -> matchEntry("^\\s*([\\w.\\-]+)\\s*(=)\\s*(.*)?\\s*$", s); // ^\s*([\w.\-]+)\s*(=)\s*(.*)?\s*$
private final Predicate<String> isWhiteSpace = s -> matches(WHITE_SPACE_REGEX, s);
private final Predicate<String> isComment = s -> s.startsWith("#") || s.startsWith("////");
private final Predicate<String> isQuoted = s -> s.startsWith("\"") && s.endsWith("\"");
private final Function<String, DotenvEntry> parseLine = s -> matchEntry(DOTENV_ENTRY_REGEX, s);

/**
* Creates a dotenv parser
Expand All @@ -46,11 +51,11 @@ public List<DotenvEntry> parse() throws DotenvException {
List<DotenvEntry> entries = new ArrayList<>();
for (String line : lines()) {
String l = line.trim();
if (isWhiteSpace.apply(l) || isComment.apply(l) || isBlank(l)) continue;
if (isWhiteSpace.test(l) || isComment.test(l) || isBlank(l)) continue;

DotenvEntry entry = parseLine.apply(l);
if (entry == null) {
if (throwIfMalformed) throw new DotenvException("Malformed entry "+ l);
if (throwIfMalformed) throw new DotenvException("Malformed entry " + l);
continue;
}
String key = entry.getKey();
Expand All @@ -73,26 +78,24 @@ private List<String> lines() throws DotenvException {

private String normalizeValue(String value) {
String tr = value.trim();
return isQuoted.apply(tr)
? tr.substring(1, value.length() -1)
return isQuoted.test(tr)
? tr.substring(1, value.length() - 1)
: tr;
}

private static boolean matches(String regex, String text) {
Pattern pattern = Pattern.compile(regex);
Matcher matcher = pattern.matcher(text);
private static boolean matches(Pattern regex, String text) {
Matcher matcher = regex.matcher(text);
return matcher.matches();
}

private static DotenvEntry matchEntry(String regex, String text) {
Pattern pattern = Pattern.compile(regex);
Matcher matcher = pattern.matcher(text);
private static DotenvEntry matchEntry(Pattern regex, String text) {
Matcher matcher = regex.matcher(text);
boolean result = matcher.matches();
if (!result || matcher.groupCount() < 3) return null;
return new DotenvEntry(matcher.group(1), matcher.group(3));
}

private boolean isBlank(String s) {
private static boolean isBlank(String s) {
return s == null || s.trim().isEmpty();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -47,9 +47,7 @@ public List<String> read() throws DotenvException, IOException {
: Paths.get(location);

if (Files.exists(path)) {
return Files
.lines(path)
.collect(Collectors.toList());
return Files.readAllLines(path);
}

try {
Expand Down

0 comments on commit 82cf585

Please sign in to comment.