Skip to content

Commit dc1cf9d

Browse files
committed
Add exceptions for unbalanced braces
1 parent b875326 commit dc1cf9d

File tree

3 files changed

+123
-6
lines changed

3 files changed

+123
-6
lines changed
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
package org.codehaus.plexus.languages.java.jpms;
2+
3+
import java.util.ArrayList;
4+
import java.util.List;
5+
import java.util.stream.Collectors;
6+
7+
public class ModuleSourcePathSupport {
8+
9+
/**
10+
*
11+
*
12+
* @param segments the list of segments, as split by the path-separator
13+
* @return all possible combinations
14+
*/
15+
public List<String> expand(List<String> segments) {
16+
SegmentParser parser = new SegmentParser();
17+
18+
List<String> result = new ArrayList<>();
19+
20+
for (String segment : segments) {
21+
try {
22+
result.addAll(parser.expandBraces(segment));
23+
} catch (RuntimeException e) {
24+
throw new IllegalArgumentException("Failed to parse " + segment + ": " + e.getMessage());
25+
}
26+
}
27+
28+
return segments.stream().flatMap(e -> parser.expandBraces(e).stream()).collect(Collectors.toList());
29+
}
30+
}

plexus-java/src/main/java/org/codehaus/plexus/languages/java/jpms/SegmentParser.java

Lines changed: 50 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
import java.util.Arrays;
66
import java.util.Deque;
77
import java.util.List;
8+
import java.util.NoSuchElementException;
89
import java.util.function.Consumer;
910
import java.util.stream.Collectors;
1011

@@ -16,9 +17,35 @@
1617
*/
1718
class SegmentParser {
1819

20+
private static final char MODULENAME_MARKER = '*';
21+
1922
private Consumer<Element> nextAction;
2023

21-
protected List<String> findAll(String segment) {
24+
/**
25+
* Each segment containing curly braces of the form
26+
*
27+
* <code>string1{alt1 ( ,alt2 )* } string2</code>
28+
*
29+
* is considered to be replaced by a series of segments formed by "expanding" the braces:
30+
*
31+
* <ul>
32+
* <li><code>string1 alt1 string2</code></li>
33+
* <li><code>string1 alt2 string2</code></li>
34+
* </ul>
35+
* and so on...
36+
* <p>
37+
* The braces may be nested.
38+
* </p>
39+
* <p>
40+
* This rule is applied for all such usages of braces.
41+
* </p>
42+
*
43+
* @param segment the segment to expand
44+
* @return all expanded segments
45+
* @throws IllegalArgumentException if braces are unbalanced
46+
* @see <a href="https://docs.oracle.com/en/java/javase/23/docs/specs/man/javac.html#the-module-source-path-option">https://docs.oracle.com/en/java/javase/23/docs/specs/man/javac.html#the-module-source-path-option</a>
47+
*/
48+
protected List<String> expandBraces(String segment) {
2249
StringBuilder value = new StringBuilder();
2350

2451
Root root = new Root();
@@ -56,9 +83,13 @@ protected List<String> findAll(String segment) {
5683
case '}': {
5784
nextAction.accept(new Value(value.toString()));
5885

59-
Block b = blocks.poll();
86+
try {
87+
Block b = blocks.pop();
6088

61-
nextAction = b::tail;
89+
nextAction = b::tail;
90+
} catch (NoSuchElementException e) {
91+
throw new IllegalArgumentException("Unbalanced braces, missing {");
92+
}
6293

6394
value = new StringBuilder();
6495

@@ -71,6 +102,10 @@ protected List<String> findAll(String segment) {
71102
}
72103
}
73104

105+
if (blocks.size() > 0) {
106+
throw new IllegalArgumentException("Unbalanced braces, missing }");
107+
}
108+
74109
if (value.length() > 0) {
75110
nextAction.accept(new Value(value.toString()));
76111
}
@@ -80,6 +115,8 @@ protected List<String> findAll(String segment) {
80115

81116
private interface Element {
82117
List<String> resolvePaths(List<String> bases);
118+
119+
boolean hasModuleNameMarker();
83120
}
84121

85122
private final class Value implements Element {
@@ -95,6 +132,11 @@ public List<String> resolvePaths(List<String> bases) {
95132
return bases.stream().map(b -> b + value).collect(Collectors.toList());
96133
}
97134

135+
@Override
136+
public boolean hasModuleNameMarker() {
137+
return value.indexOf(MODULENAME_MARKER) >= 0;
138+
}
139+
98140
@Override
99141
public String toString() {
100142
return "Value [value=" + value + "]";
@@ -141,6 +183,11 @@ public List<String> resolvePaths(List<String> bases) {
141183
}
142184
}
143185

186+
@Override
187+
public boolean hasModuleNameMarker() {
188+
return value.indexOf(MODULENAME_MARKER) >= 0;
189+
}
190+
144191
@Override
145192
public String toString() {
146193
return "Block [value=" + value + ", elements=" + elements + ", tail=" + tail + "]";

plexus-java/src/test/java/org/codehaus/plexus/languages/java/jpms/SegmentParserTest.java

Lines changed: 43 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
package org.codehaus.plexus.languages.java.jpms;
22

3+
import java.nio.file.Path;
34
import java.util.stream.Stream;
45

56
import org.junit.jupiter.params.ParameterizedTest;
@@ -13,12 +14,12 @@ class SegmentParserTest {
1314

1415
@ParameterizedTest
1516
@MethodSource
16-
void findAll(String segment, String... expectedValues) {
17+
void expandBraces(String segment, String... expectedValues) {
1718
SegmentParser parser = new SegmentParser();
18-
assertThat(parser.findAll(segment)).containsExactlyInAnyOrder(expectedValues);
19+
assertThat(parser.expandBraces(segment)).containsExactlyInAnyOrder(expectedValues);
1920
}
2021

21-
static Stream<Arguments> findAll() {
22+
static Stream<Arguments> expandBraces() {
2223
return Stream.of(
2324
Arguments.of("foo", new String[] {"foo"}),
2425
Arguments.of("foo/{bar,baz}", new String[] {"foo/bar", "foo/baz"}),
@@ -36,4 +37,43 @@ static Stream<Arguments> findAll() {
3637
}),
3738
Arguments.of("{foo/{bar},zzz}", new String[] {"foo/bar", "zzz"}));
3839
}
40+
41+
@ParameterizedTest
42+
@MethodSource
43+
void expandBraces_exceptions(String segment, String exceptionMessage) {
44+
SegmentParser parser = new SegmentParser();
45+
IllegalArgumentException e = assertThrows(IllegalArgumentException.class, () -> parser.expandBraces(segment));
46+
assertThat(e.getMessage()).isEqualTo(exceptionMessage);
47+
}
48+
49+
static Stream<Arguments> expandBraces_exceptions() {
50+
return Stream.of(
51+
Arguments.of("{", "Unbalanced braces, missing }"), Arguments.of("}", "Unbalanced braces, missing {"));
52+
}
53+
54+
void bla() {
55+
String seg = "";
56+
int markStart = 0;
57+
58+
Path prefix;
59+
if (markStart == 0) {
60+
prefix = getPath("");
61+
} else if (isSeparator(seg.charAt(markStart - 1))) {
62+
prefix = getPath(seg.substring(0, markStart - 1));
63+
} else {
64+
throw new IllegalArgumentException("illegal use of " + MARKER + " in " + seg);
65+
}
66+
67+
prefix.compareTo(null);
68+
}
69+
70+
static String MARKER;
71+
72+
Path getPath(String s) {
73+
return null;
74+
}
75+
76+
boolean isSeparator(char c) {
77+
return true;
78+
}
3979
}

0 commit comments

Comments
 (0)