Skip to content

Commit b69aba7

Browse files
committed
#34 - Multi-platform matrix parameter support
1 parent 7a0510c commit b69aba7

File tree

14 files changed

+248
-84
lines changed

14 files changed

+248
-84
lines changed

controller/src/main/java/io/dinject/controller/PathSegment.java

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ public class PathSegment {
1515

1616
private final String val;
1717

18-
private Map<String, String> metricValues;
18+
private Map<String, String> matrixValues;
1919

2020
/**
2121
* Create with a given value that may contain matrix parameters.
@@ -31,11 +31,11 @@ public PathSegment(String value) {
3131
String[] vals = value.split(";");
3232
this.val = vals[0];
3333
if (vals.length > 1) {
34-
metricValues = new HashMap<>();
34+
matrixValues = new HashMap<>();
3535
for (String val : vals) {
3636
String[] keyVal = val.split("=");
3737
if (keyVal.length == 2) {
38-
metricValues.put(keyVal[0], keyVal[1]);
38+
matrixValues.put(keyVal[0], keyVal[1]);
3939
}
4040
}
4141
}
@@ -66,8 +66,8 @@ public String val() {
6666
* @param key The metric key
6767
* @return The metric value if supplied or null
6868
*/
69-
public String metric(String key) {
70-
return metricValues == null ? null : metricValues.get(key);
69+
public String matrix(String key) {
70+
return matrixValues == null ? null : matrixValues.get(key);
7171
}
7272

7373
}

controller/src/test/java/io/dinject/controller/PathSegmentTest.java

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ public void simple() {
1313
PathSegment seg = PathSegment.of("simple");
1414

1515
assertEquals("simple", seg.val());
16-
assertNull(seg.metric("foo"));
16+
assertNull(seg.matrix("foo"));
1717
}
1818

1919

@@ -23,8 +23,8 @@ public void singleMetric() {
2323
PathSegment seg = new PathSegment("simple;k=v");
2424

2525
assertEquals("simple", seg.val());
26-
assertEquals("v", seg.metric("k"));
27-
assertNull(seg.metric("foo"));
26+
assertEquals("v", seg.matrix("k"));
27+
assertNull(seg.matrix("foo"));
2828
}
2929

3030
@Test
@@ -33,9 +33,9 @@ public void singleMultiMetric() {
3333
PathSegment seg = PathSegment.of("simple;k=v;l=m");
3434

3535
assertEquals("simple", seg.val());
36-
assertEquals("v", seg.metric("k"));
37-
assertEquals("m", seg.metric("l"));
38-
assertNull(seg.metric("foo"));
36+
assertEquals("v", seg.matrix("k"));
37+
assertEquals("m", seg.matrix("l"));
38+
assertNull(seg.matrix("foo"));
3939
}
4040

4141
@Test
@@ -44,8 +44,8 @@ public void emptyStringMetrics() {
4444
PathSegment seg = new PathSegment("simple;k=;l=");
4545

4646
assertEquals("simple", seg.val());
47-
assertNull(seg.metric("k"));
48-
assertNull(seg.metric("l"));
49-
assertNull(seg.metric("foo"));
47+
assertNull(seg.matrix("k"));
48+
assertNull(seg.matrix("l"));
49+
assertNull(seg.matrix("foo"));
5050
}
5151
}

generator-core/src/main/java/io/dinject/webroutegen/ElementReader.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -225,7 +225,7 @@ private boolean setValue(Append writer, PathSegments segments, String shortType)
225225
if (impliedParamType) {
226226
PathSegments.Segment segment = segments.segment(varName);
227227
if (segment != null) {
228-
// path or metric parameter
228+
// path or matrix parameter
229229
boolean requiredParam = segment.isRequired(varName);
230230
String asMethod = (typeHandler == null) ? null : (requiredParam) ? typeHandler.asMethod() : typeHandler.toMethod();
231231
if (asMethod != null) {

generator-core/src/main/java/io/dinject/webroutegen/PathSegments.java

Lines changed: 39 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -28,12 +28,12 @@ static PathSegments parse(String fullPath) {
2828
if (section.startsWith(":")) {
2929
Segment segment = createSegment(section.substring(1));
3030
segments.add(segment);
31-
path.append(segment.path(section));
31+
path.append(segment.path(section, ":", ""));
3232

3333
} else if ((section.startsWith("{") && (section.endsWith("}")))) {
3434
Segment segment = createSegment(section.substring(1, section.length() - 1));
3535
segments.add(segment);
36-
path.append(segment.path(section));
36+
path.append(segment.path(section, "{", "}"));
3737

3838
} else {
3939
path.append(section);
@@ -46,21 +46,19 @@ static PathSegments parse(String fullPath) {
4646
}
4747

4848
private static Segment createSegment(String val) {
49-
50-
String[] metricSplit = val.split(";");
51-
if (metricSplit.length == 1) {
52-
return new Segment(metricSplit[0]);
49+
String[] matrixSplit = val.split(";");
50+
if (matrixSplit.length == 1) {
51+
return new Segment(matrixSplit[0]);
5352
}
54-
55-
Set<String> metrics = new HashSet<>(Arrays.asList(metricSplit).subList(1, metricSplit.length));
56-
return new Segment(metricSplit[0], metrics);
53+
Set<String> matrixKeys = new HashSet<>(Arrays.asList(matrixSplit).subList(1, matrixSplit.length));
54+
return new Segment(matrixSplit[0], matrixKeys);
5755
}
5856

5957
private final String fullPath;
6058

6159
private final Set<Segment> segments;
6260

63-
private final List<Segment> withMetrics = new ArrayList<>();
61+
private final List<Segment> withMatrixs = new ArrayList<>();
6462

6563
private final Set<String> allNames = new HashSet<>();
6664

@@ -69,8 +67,8 @@ private PathSegments(String fullPath, Set<Segment> segments) {
6967
this.segments = segments;
7068
for (Segment segment : segments) {
7169
segment.addNames(allNames);
72-
if (segment.hasMetrics()) {
73-
withMetrics.add(segment);
70+
if (segment.hasMatrixParams()) {
71+
withMatrixs.add(segment);
7472
}
7573
}
7674
}
@@ -80,8 +78,8 @@ boolean contains(String varName) {
8078
return allNames.contains(varName);
8179
}
8280

83-
List<Segment> metricSegments() {
84-
return withMetrics;
81+
List<Segment> matrixSegments() {
82+
return withMatrixs;
8583
}
8684

8785
Segment segment(String varName) {
@@ -103,96 +101,94 @@ static class Segment {
103101
private final String name;
104102

105103
/**
106-
* Metric keys.
104+
* Matrix keys.
107105
*/
108-
private final Set<String> metrics;
106+
private final Set<String> matrixKeys;
109107

110108
/**
111-
* Variable names the metrics map to (Java method param names).
109+
* Variable names the matrix map to (Java method param names).
112110
*/
113-
private final Set<String> metricVarNames;
111+
private final Set<String> matrixVarNames;
114112

115113
Segment(String name) {
116114
this.name = name;
117-
this.metrics = null;
118-
this.metricVarNames = null;
115+
this.matrixKeys = null;
116+
this.matrixVarNames = null;
119117
}
120118

121-
Segment(String name, Set<String> metrics) {
119+
Segment(String name, Set<String> matrixKeys) {
122120
this.name = name;
123-
this.metrics = metrics;
124-
this.metricVarNames = new HashSet<>();
125-
for (String key : metrics) {
126-
metricVarNames.add(combine(name, key));
121+
this.matrixKeys = matrixKeys;
122+
this.matrixVarNames = new HashSet<>();
123+
for (String key : matrixKeys) {
124+
matrixVarNames.add(combine(name, key));
127125
}
128126
}
129127

130128
void addNames(Set<String> allNames) {
131129
allNames.add(name);
132130
}
133131

134-
boolean hasMetrics() {
135-
return metrics != null && !metrics.isEmpty();
132+
boolean hasMatrixParams() {
133+
return matrixKeys != null && !matrixKeys.isEmpty();
136134
}
137135

138136
private String combine(String name, String key) {
139137
return name + Character.toUpperCase(key.charAt(0)) + key.substring(1);
140138
}
141139

142-
Set<String> metrics() {
143-
return metrics;
140+
Set<String> matrixKeys() {
141+
return matrixKeys;
144142
}
145143

146144
String name() {
147145
return name;
148146
}
149147

150148
boolean isPathParameter(String varName) {
151-
return name.equals(varName) || (metrics != null && (metricVarNames.contains(varName) || metrics.contains(varName)));
149+
return name.equals(varName) || (matrixKeys != null && (matrixVarNames.contains(varName) || matrixKeys.contains(varName)));
152150
}
153151

154152
/**
155153
* Reading the value from a segment (rather than directly from pathParam).
156154
*/
157155
void writeGetVal(Append writer, String varName, PlatformAdapter platform) {
158-
if (!hasMetrics()) {
156+
if (!hasMatrixParams()) {
159157
platform.writeReadParameter(writer, ParamType.PATHPARAM, name);
160158
} else {
161-
// TODO: platform read segment handling ...
162159
writer.append("%s_segment.", name);
163160
if (name.equals(varName)) {
164161
writer.append("val()");
165162
} else {
166-
writer.append("metric(\"%s\")", metricKey(varName));
163+
writer.append("matrix(\"%s\")", matrixKey(varName));
167164
}
168165
}
169166
}
170167

171-
private String metricKey(String varName) {
172-
168+
private String matrixKey(String varName) {
173169
if (!varName.startsWith(name)) {
174170
return varName;
175171
}
176-
177172
String key = varName.substring(name.length());
178173
return Character.toLowerCase(key.charAt(0)) + key.substring(1);
179174
}
180175

181-
void writeCreateSegment(Append writer) {
182-
// TODO: platform read segment handling ...
183-
writer.append(" PathSegment %s_segment = PathSegment.of(ctx.pathParam(\"%s_segment\"));", name, name).eol();
176+
void writeCreateSegment(Append writer, PlatformAdapter platform) {
177+
writer.append(platform.indent());
178+
writer.append(" PathSegment %s_segment = PathSegment.of(", name);
179+
platform.writeReadParameter(writer, ParamType.PATHPARAM, name + "_segment");
180+
writer.append(");").eol();
184181
}
185182

186183
boolean isRequired(String varName) {
187184
return name.equals(varName);
188185
}
189186

190-
String path(String section) {
191-
if (!hasMetrics()) {
187+
String path(String section, String prefix, String suffix) {
188+
if (!hasMatrixParams()) {
192189
return section;
193190
}
194-
// TODO: platform read segment handling ...=
195-
return ":" + name + "_segment";
191+
return prefix + name + "_segment" + suffix;
196192
}
197193
}
198194
}

generator-core/src/test/java/io/dinject/webroutegen/PathSegmentsTest.java

Lines changed: 36 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -66,24 +66,41 @@ public void parse_empty() {
6666
}
6767

6868
@Test
69-
public void pathParams() {
69+
public void pathMatrixParams_colonPrefix() {
7070

7171
PathSegments segments = PathSegments.parse("/:id;key;other/:foo;baz");
7272

73-
List<PathSegments.Segment> metricSegments = segments.metricSegments();
74-
assertThat(metricSegments).hasSize(2);
73+
List<PathSegments.Segment> matrixSegments = segments.matrixSegments();
74+
assertThat(matrixSegments).hasSize(2);
7575

76-
assertThat(metricSegments.get(0).name()).isEqualTo("id");
77-
assertThat(metricSegments.get(0).metrics()).containsOnly("key", "other");
76+
assertThat(matrixSegments.get(0).name()).isEqualTo("id");
77+
assertThat(matrixSegments.get(0).matrixKeys()).containsOnly("key", "other");
7878

79-
assertThat(metricSegments.get(1).name()).isEqualTo("foo");
80-
assertThat(metricSegments.get(1).metrics()).containsOnly("baz");
79+
assertThat(matrixSegments.get(1).name()).isEqualTo("foo");
80+
assertThat(matrixSegments.get(1).matrixKeys()).containsOnly("baz");
8181

8282
assertEquals("/:id_segment/:foo_segment", segments.fullPath());
8383
}
8484

8585
@Test
86-
public void pathParams_fullPath() {
86+
public void pathMatrixParams_normalised() {
87+
88+
PathSegments segments = PathSegments.parse("/{id;key;other}/{foo;baz}");
89+
90+
List<PathSegments.Segment> matrixSegments = segments.matrixSegments();
91+
assertThat(matrixSegments).hasSize(2);
92+
93+
assertThat(matrixSegments.get(0).name()).isEqualTo("id");
94+
assertThat(matrixSegments.get(0).matrixKeys()).containsOnly("key", "other");
95+
96+
assertThat(matrixSegments.get(1).name()).isEqualTo("foo");
97+
assertThat(matrixSegments.get(1).matrixKeys()).containsOnly("baz");
98+
99+
assertEquals("/{id_segment}/{foo_segment}", segments.fullPath());
100+
}
101+
102+
@Test
103+
public void pathMatrixParams_fullPath() {
87104

88105
PathSegments segments = PathSegments.parse("/start/:id;key;other/:foo;baz/end");
89106
assertEquals("/start/:id_segment/:foo_segment/end", segments.fullPath());
@@ -92,4 +109,15 @@ public void pathParams_fullPath() {
92109

93110
assertEquals("/start/:id_segment/middle/:foo_segment/end", segments.fullPath());
94111
}
112+
113+
@Test
114+
public void pathMatrixParams_fullPath_normalised() {
115+
116+
PathSegments segments = PathSegments.parse("/start/{id;key;other}/{foo;baz}/end");
117+
assertEquals("/start/{id_segment}/{foo_segment}/end", segments.fullPath());
118+
119+
segments = PathSegments.parse("/start/{id;key;other}/middle/{foo;baz}/end");
120+
assertEquals("/start/{id_segment}/middle/{foo_segment}/end", segments.fullPath());
121+
}
122+
95123
}

generator-helidon/src/main/java/io/dinject/webroutegen/ControllerMethodWriter.java

Lines changed: 12 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -12,11 +12,13 @@ class ControllerMethodWriter {
1212
private final MethodReader method;
1313
private final Append writer;
1414
private final WebMethod webMethod;
15+
private final ProcessingContext ctx;
1516

16-
ControllerMethodWriter(MethodReader method, Append writer) {
17+
ControllerMethodWriter(MethodReader method, Append writer, ProcessingContext ctx) {
1718
this.method = method;
1819
this.writer = writer;
1920
this.webMethod = method.getWebMethod();
21+
this.ctx = ctx;
2022
}
2123

2224
void writeRule() {
@@ -43,13 +45,12 @@ void writeHandler() {
4345
if (!method.isVoid()) {
4446
writeContextReturn();
4547
}
46-
final PathSegments segments = method.getPathSegments();
47-
// writer.append(" ctx.status(%s);", method.getStatusCode()).eol();
4848

49-
// List<PathSegments.Segment> metricSegments = segments.metricSegments();
50-
// for (PathSegments.Segment metricSegment : metricSegments) {
51-
// metricSegment.writeCreateSegment(writer);
52-
// }
49+
final PathSegments segments = method.getPathSegments();
50+
List<PathSegments.Segment> matrixSegments = segments.matrixSegments();
51+
for (PathSegments.Segment matrixSegment : matrixSegments) {
52+
matrixSegment.writeCreateSegment(writer, ctx.platform());
53+
}
5354

5455
final List<MethodParam> params = method.getParams();
5556
for (MethodParam param : params) {
@@ -103,13 +104,13 @@ private void writeContextReturn() {
103104
if (produces == null) {
104105
// let it be automatically set
105106
} else if (MediaType.APPLICATION_JSON.equalsIgnoreCase(produces)) {
106-
writer.append("res.writerContext().contentType(io.helidon.common.http.MediaType.APPLICATION_JSON);").eol();
107+
writer.append(" res.writerContext().contentType(io.helidon.common.http.MediaType.APPLICATION_JSON);").eol();
107108
} else if (MediaType.TEXT_HTML.equalsIgnoreCase(produces)) {
108-
writer.append("res.writerContext().contentType(io.helidon.common.http.MediaType.TEXT_HTML);").eol();
109+
writer.append(" res.writerContext().contentType(io.helidon.common.http.MediaType.TEXT_HTML);").eol();
109110
} else if (MediaType.TEXT_PLAIN.equalsIgnoreCase(produces)) {
110-
writer.append("res.writerContext().contentType(io.helidon.common.http.MediaType.TEXT_PLAIN);").eol();
111+
writer.append(" res.writerContext().contentType(io.helidon.common.http.MediaType.TEXT_PLAIN);").eol();
111112
} else {
112-
writer.append("res.writerContext().contentType(io.helidon.common.http.MediaType.parse(\"%s\"));", produces).eol();
113+
writer.append( "res.writerContext().contentType(io.helidon.common.http.MediaType.parse(\"%s\"));", produces).eol();
113114
}
114115
}
115116

0 commit comments

Comments
 (0)