Skip to content

Commit ddb50e0

Browse files
committed
wrong doc for asset props processor fix #403
1 parent b1bf712 commit ddb50e0

File tree

6 files changed

+100
-18
lines changed

6 files changed

+100
-18
lines changed

jooby-assets/src/main/java/org/jooby/assets/Props.java

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,8 @@
2020

2121
import java.util.Arrays;
2222
import java.util.List;
23+
import java.util.regex.Matcher;
24+
import java.util.regex.Pattern;
2325

2426
import org.jooby.Env;
2527
import org.jooby.MediaType;
@@ -71,6 +73,8 @@
7173
*/
7274
public class Props extends AssetProcessor {
7375

76+
private static Pattern POS = Pattern.compile("at\\s(\\d+):(\\d+)");
77+
7478
{
7579
set("delims", Arrays.asList("${", "}"));
7680
}
@@ -83,9 +87,20 @@ public boolean matches(final MediaType type) {
8387
@Override
8488
public String process(final String filename, final String source, final Config conf)
8589
throws Exception {
90+
try {
8691
Env env = Env.DEFAULT.build(conf);
8792
List<String> delims = get("delims");
8893
return env.resolve(source, delims.get(0), delims.get(1));
94+
} catch (Exception cause) {
95+
int line = -1;
96+
int column = -1;
97+
Matcher matcher = POS.matcher(cause.getMessage());
98+
if (matcher.find()) {
99+
line = Integer.parseInt(matcher.group(1));
100+
column = Integer.parseInt(matcher.group(2));
101+
}
102+
throw new AssetException(name(), new AssetProblem(filename, line, column, cause.getMessage(), null));
103+
}
89104
}
90105

91106
}

jooby-assets/src/test/java/org/jooby/assets/PropsTest.java

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
import static org.junit.Assert.assertEquals;
44
import static org.junit.Assert.assertTrue;
5+
import static org.junit.Assert.fail;
56

67
import java.util.Arrays;
78

@@ -36,4 +37,21 @@ public void shouldSupportCustomDelimiters() throws Exception {
3637
.empty().withValue("app.url", ConfigValueFactory.fromAnyRef("http://foo.com"))));
3738
}
3839

40+
@Test
41+
public void missingProp() throws Exception {
42+
try {
43+
new Props().process("/j.s", "$.ajax(${cpath}/service);", ConfigFactory.empty());
44+
fail();
45+
} catch (AssetException ex) {
46+
assertEquals("[/j.s:1:8: No configuration setting found for key 'cpath' at 1:8]", ex.getMessage());
47+
}
48+
49+
try {
50+
new Props().process("/j.s", "$.ajax(\n\n ${cpath}/service);", ConfigFactory.empty());
51+
fail();
52+
} catch (AssetException ex) {
53+
assertEquals("[/j.s:3:4: No configuration setting found for key 'cpath' at 3:4]", ex.getMessage());
54+
}
55+
}
56+
3957
}

jooby/src/main/java/org/jooby/Env.java

Lines changed: 19 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -23,11 +23,12 @@
2323

2424
import java.util.List;
2525
import java.util.Locale;
26+
import java.util.NoSuchElementException;
2627
import java.util.Optional;
28+
import java.util.function.BiFunction;
2729
import java.util.function.Predicate;
2830
import java.util.function.Supplier;
2931

30-
import com.google.common.base.CharMatcher;
3132
import com.google.common.base.Splitter;
3233
import com.google.common.base.Strings;
3334
import com.google.common.collect.ImmutableList;
@@ -242,24 +243,37 @@ default String resolve(final String text, final Config source) {
242243
default String resolve(final String text, final Config source,
243244
final String startDelimiter, final String endDelimiter) {
244245
requireNonNull(text, "Text is required.");
245-
requireNonNull(source, "A config source is required.");
246+
requireNonNull(source, "Config source is required.");
246247
checkArgument(!Strings.isNullOrEmpty(startDelimiter), "Start delimiter is required.");
247248
checkArgument(!Strings.isNullOrEmpty(endDelimiter), "End delimiter is required.");
248249
if (text.length() == 0) {
249250
return "";
250251
}
252+
253+
BiFunction<Integer, BiFunction<Integer, Integer, RuntimeException>, RuntimeException> err = (
254+
start, ex) -> {
255+
String snapshot = text.substring(0, start);
256+
int line = Splitter.on('\n').splitToList(snapshot).size();
257+
int column = start - snapshot.lastIndexOf('\n');
258+
return ex.apply(line, column);
259+
};
260+
251261
StringBuilder buffer = new StringBuilder();
252262
int offset = 0;
253263
int start = text.indexOf(startDelimiter);
254264
while (start >= 0) {
255265
int end = text.indexOf(endDelimiter, start + startDelimiter.length());
256266
if (end == -1) {
257-
throw new IllegalArgumentException("Unclosed placeholder: "
258-
+ Splitter.on(CharMatcher.WHITESPACE)
259-
.split(text.subSequence(start, text.length())).iterator().next());
267+
throw err.apply(start, (line, column) -> new IllegalArgumentException(
268+
"found '" + startDelimiter + "' expecting '" + endDelimiter + "' at " + line + ":"
269+
+ column));
260270
}
261271
buffer.append(text.substring(offset, start));
262272
String key = text.substring(start + startDelimiter.length(), end);
273+
if (!source.hasPath(key)) {
274+
throw err.apply(start, (line, column) -> new NoSuchElementException(
275+
"No configuration setting found for key '" + key + "' at " + line + ":" + column));
276+
}
263277
buffer.append(source.getAnyRef(key));
264278
offset = end + endDelimiter.length();
265279
start = text.indexOf(startDelimiter, offset);

jooby/src/main/resources/org/jooby/jooby.conf

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -206,3 +206,9 @@ cors {
206206
err.java.lang.IllegalArgumentException = 400
207207
err.java.util.NoSuchElementException = 400
208208
err.java.io.FileNotFoundException = 404
209+
210+
###################################################################################################
211+
#! alias
212+
###################################################################################################
213+
214+
contextPath = ${application.path}

jooby/src/test/java/org/jooby/EnvTest.java

Lines changed: 42 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
import static org.junit.Assert.assertEquals;
44
import static org.junit.Assert.fail;
55

6+
import java.util.NoSuchElementException;
67
import java.util.Optional;
78

89
import org.junit.Test;
@@ -105,7 +106,7 @@ public void unclosedDelimiterWithSpace() {
105106
env.resolve(env.resolve("function ($) {$.ajax(\"${contextPath /api\")"));
106107
fail();
107108
} catch (IllegalArgumentException ex) {
108-
assertEquals("Unclosed placeholder: ${contextPath", ex.getMessage());
109+
assertEquals("found '${' expecting '}' at 1:23", ex.getMessage());
109110
}
110111
}
111112

@@ -116,7 +117,46 @@ public void unclosedDelimiter() {
116117
env.resolve(env.resolve("function ($) {$.ajax(\"${contextPath/api\")"));
117118
fail();
118119
} catch (IllegalArgumentException ex) {
119-
assertEquals("Unclosed placeholder: ${contextPath/api\")", ex.getMessage());
120+
assertEquals("found '${' expecting '}' at 1:23", ex.getMessage());
121+
}
122+
}
123+
124+
@Test
125+
public void noSuchKey() {
126+
Env env = Env.DEFAULT.build(ConfigFactory.empty());
127+
try {
128+
env.resolve(env.resolve("${key}"));
129+
fail();
130+
} catch (NoSuchElementException ex) {
131+
assertEquals("No configuration setting found for key 'key' at 1:1", ex.getMessage());
132+
}
133+
134+
try {
135+
env.resolve(env.resolve(" ${key}"));
136+
fail();
137+
} catch (NoSuchElementException ex) {
138+
assertEquals("No configuration setting found for key 'key' at 1:5", ex.getMessage());
139+
}
140+
141+
try {
142+
env.resolve(env.resolve(" \n ${key}"));
143+
fail();
144+
} catch (NoSuchElementException ex) {
145+
assertEquals("No configuration setting found for key 'key' at 2:3", ex.getMessage());
146+
}
147+
148+
try {
149+
env.resolve(env.resolve(" \n ${key}"));
150+
fail();
151+
} catch (NoSuchElementException ex) {
152+
assertEquals("No configuration setting found for key 'key' at 2:3", ex.getMessage());
153+
}
154+
155+
try {
156+
env.resolve(env.resolve(" \n \n ${key}"));
157+
fail();
158+
} catch (NoSuchElementException ex) {
159+
assertEquals("No configuration setting found for key 'key' at 3:2", ex.getMessage());
120160
}
121161
}
122162

md/doc/assets-props/assets-props.md

Lines changed: 0 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -4,17 +4,6 @@ Replace ```${expressions}``` with a value from ```application.conf```.
44

55
{{assets-require.md}}
66

7-
## dependency
8-
9-
```xml
10-
<dependency>
11-
<groupId>org.jooby</groupId>
12-
<artifactId>jooby-assets-props</artifactId>
13-
<version>{{version}}</version>
14-
<scope>provided</scope>
15-
</dependency>
16-
```
17-
187
## usage
198

209
```

0 commit comments

Comments
 (0)