Skip to content

Commit 620c75d

Browse files
committed
- add path filter with replace query and path paramters
- better format for table output (long description column) - ref #3820
1 parent af49d46 commit 620c75d

File tree

20 files changed

+241
-72
lines changed

20 files changed

+241
-72
lines changed

modules/jooby-openapi/src/main/java/io/jooby/internal/openapi/OpenAPIExt.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -243,7 +243,7 @@ public OperationExt findOperationById(String operationId) {
243243
}
244244

245245
public OperationExt findOperation(String method, String pattern) {
246-
Predicate<OperationExt> filter = op -> op.getPattern().equals(pattern);
246+
Predicate<OperationExt> filter = op -> op.getPath().equals(pattern);
247247
if (method != null) {
248248
filter = filter.and(op -> op.getMethod().equals(method));
249249
}

modules/jooby-openapi/src/main/java/io/jooby/internal/openapi/OperationExt.java

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ public class OperationExt extends io.swagger.v3.oas.models.Operation {
2727

2828
@JsonIgnore private final MethodNode node;
2929
@JsonIgnore private String method;
30-
@JsonIgnore private final String pattern;
30+
@JsonIgnore private final String path;
3131
@JsonIgnore private Boolean hidden;
3232
@JsonIgnore private LinkedList<String> produces = new LinkedList<>();
3333
@JsonIgnore private LinkedList<String> consumes = new LinkedList<>();
@@ -41,10 +41,10 @@ public class OperationExt extends io.swagger.v3.oas.models.Operation {
4141
@JsonIgnore private ClassNode controller;
4242

4343
public OperationExt(
44-
MethodNode node, String method, String pattern, List arguments, ResponseExt response) {
44+
MethodNode node, String method, String path, List arguments, ResponseExt response) {
4545
this.node = node;
4646
this.method = method.toUpperCase();
47-
this.pattern = pattern;
47+
this.path = path;
4848
setParameters(arguments);
4949
this.defaultResponse = response;
5050
setResponses(apiResponses(Collections.singletonList(response)));
@@ -87,8 +87,8 @@ public void setMethod(String method) {
8787
this.method = method;
8888
}
8989

90-
public String getPattern() {
91-
return pattern;
90+
public String getPath() {
91+
return path;
9292
}
9393

9494
public List<String> getProduces() {
@@ -120,7 +120,7 @@ public void setHidden(Boolean hidden) {
120120
}
121121

122122
public String toString() {
123-
return getMethod() + " " + getPattern();
123+
return getMethod() + " " + getPath();
124124
}
125125

126126
public Parameter getParameter(int i) {
@@ -267,4 +267,8 @@ public OperationExt copy(String pattern) {
267267
copy.setPathExtensions(getPathExtensions());
268268
return copy;
269269
}
270+
271+
public String getPath(Map<String, Object> pathParams) {
272+
return Router.reverse(getPath(), pathParams);
273+
}
270274
}

modules/jooby-openapi/src/main/java/io/jooby/internal/openapi/RouteParser.java

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,7 @@ public List<OperationExt> parse(ParserContext ctx, OpenAPIExt openapi) {
7575

7676
List<OperationExt> result = new ArrayList<>();
7777
for (OperationExt operation : operations) {
78-
List<String> patterns = Router.expandOptionalVariables(operation.getPattern());
78+
List<String> patterns = Router.expandOptionalVariables(operation.getPath());
7979
if (patterns.size() == 1) {
8080
result.add(operation);
8181
} else {
@@ -112,8 +112,7 @@ private static void addJavaDoc(
112112
if (operation.getController() == null) {
113113
javaDoc
114114
.flatMap(
115-
doc ->
116-
doc.getScript(operation.getMethod(), operation.getPattern().substring(offset)))
115+
doc -> doc.getScript(operation.getMethod(), operation.getPath().substring(offset)))
117116
.ifPresent(
118117
scriptDoc -> {
119118
if (scriptDoc.getPath() != null) {
@@ -249,8 +248,7 @@ private void uniqueOperationId(List<OperationExt> operations) {
249248
private String operationId(OperationExt operation) {
250249
return Optional.ofNullable(operation.getOperationId())
251250
.orElseGet(
252-
() ->
253-
operation.getMethod().toLowerCase() + patternToOperationId(operation.getPattern()));
251+
() -> operation.getMethod().toLowerCase() + patternToOperationId(operation.getPath()));
254252
}
255253

256254
private String patternToOperationId(String pattern) {

modules/jooby-openapi/src/main/java/io/jooby/internal/openapi/asciidoc/Functions.java

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ public List<String> getArgumentNames() {
2424
@Override
2525
public Object execute(
2626
Map<String, Object> args, PebbleTemplate self, EvaluationContext context, int lineNumber) {
27-
args.put("method", name());
27+
args.put("identifier", name());
2828
return operation.execute(args, self, context, lineNumber);
2929
}
3030
},
@@ -37,7 +37,7 @@ public List<String> getArgumentNames() {
3737
@Override
3838
public Object execute(
3939
Map<String, Object> args, PebbleTemplate self, EvaluationContext context, int lineNumber) {
40-
args.put("method", name());
40+
args.put("identifier", name());
4141
return operation.execute(args, self, context, lineNumber);
4242
}
4343
},
@@ -50,7 +50,7 @@ public List<String> getArgumentNames() {
5050
@Override
5151
public Object execute(
5252
Map<String, Object> args, PebbleTemplate self, EvaluationContext context, int lineNumber) {
53-
args.put("method", name());
53+
args.put("identifier", name());
5454
return operation.execute(args, self, context, lineNumber);
5555
}
5656
},
@@ -63,7 +63,7 @@ public List<String> getArgumentNames() {
6363
@Override
6464
public Object execute(
6565
Map<String, Object> args, PebbleTemplate self, EvaluationContext context, int lineNumber) {
66-
args.put("method", name());
66+
args.put("identifier", name());
6767
return operation.execute(args, self, context, lineNumber);
6868
}
6969
},
@@ -76,7 +76,7 @@ public List<String> getArgumentNames() {
7676
@Override
7777
public Object execute(
7878
Map<String, Object> args, PebbleTemplate self, EvaluationContext context, int lineNumber) {
79-
args.put("method", name());
79+
args.put("identifier", name());
8080
return operation.execute(args, self, context, lineNumber);
8181
}
8282
},

modules/jooby-openapi/src/main/java/io/jooby/internal/openapi/asciidoc/OperationFilters.java

Lines changed: 93 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
import com.google.common.base.Predicate;
1616
import com.google.common.base.Splitter;
1717
import com.google.common.collect.*;
18+
import com.google.common.net.UrlEscapers;
1819
import edu.umd.cs.findbugs.annotations.NonNull;
1920
import edu.umd.cs.findbugs.annotations.Nullable;
2021
import io.jooby.MediaType;
@@ -46,13 +47,8 @@ protected String doApply(
4647
int lineNumber)
4748
throws Exception {
4849
var options = args(args);
49-
var method =
50-
Optional.of(options.removeAll("-X"))
51-
.map(Collection::iterator)
52-
.filter(Iterator::hasNext)
53-
.map(Iterator::next)
54-
.orElse(operation.getMethod())
55-
.toUpperCase();
50+
var method = removeOption(options, "-X", operation.getMethod()).toUpperCase();
51+
var language = removeOption(options, "language", "");
5652
/* Accept/Content-Type: */
5753
var addAccept = true;
5854
var addContentType = true;
@@ -111,11 +107,21 @@ protected String doApply(
111107
.collect(Collectors.joining("&", "?", ""));
112108
}
113109
options.put("-X", method + " '" + url + "'");
114-
var optionString = toString(options);
115-
snippetContext.put("options", optionString);
110+
var optionsString = toString(options);
111+
snippetContext.put("options", optionsString);
112+
snippetContext.put("language", language);
116113
return resolver.apply(id(), snippetContext);
117114
}
118115

116+
@NonNull private static String removeOption(
117+
Multimap<String, String> options, String name, String defaultValue) {
118+
return Optional.of(options.removeAll(name))
119+
.map(Collection::iterator)
120+
.filter(Iterator::hasNext)
121+
.map(Iterator::next)
122+
.orElse(defaultValue);
123+
}
124+
119125
@NonNull private static Stream<Map.Entry<String, String>> encodeUrlParameter(List<Parameter> query) {
120126
return query.stream()
121127
.flatMap(
@@ -272,6 +278,49 @@ protected String doApply(
272278
return resolver.apply(id(), snippetContext);
273279
}
274280
},
281+
path {
282+
@Override
283+
protected String doApply(
284+
SnippetResolver resolver,
285+
OperationExt operation,
286+
Map<String, Object> snippetContext,
287+
Map<String, Object> args,
288+
PebbleTemplate self,
289+
EvaluationContext context,
290+
int lineNumber) {
291+
var namedArgs = positionalArgs(args);
292+
// Path
293+
var path = parameters(operation, p -> "path".equals(p.getIn()));
294+
var pathParams = new HashMap<String, Object>();
295+
path.forEach(
296+
p -> {
297+
pathParams.put(
298+
p.getName(), namedArgs.getOrDefault(p.getName(), "{" + p.getName() + "}"));
299+
});
300+
// QueryString
301+
var query =
302+
parameters(
303+
operation,
304+
p ->
305+
"query".equals(p.getIn())
306+
&& (namedArgs.isEmpty() || namedArgs.containsKey(p.getName())));
307+
var queryString =
308+
query.isEmpty()
309+
? ""
310+
: query.stream()
311+
.map(
312+
it -> {
313+
var value =
314+
namedArgs.getOrDefault(
315+
it.getName(), SchemaData.shemaType(it.getSchema()));
316+
return it.getName()
317+
+ "="
318+
+ UrlEscapers.urlFragmentEscaper().escape(value.toString());
319+
})
320+
.collect(Collectors.joining("&", "?", ""));
321+
return operation.getPath(pathParams) + queryString;
322+
}
323+
},
275324
pathParameters {
276325
@Override
277326
protected String doApply(
@@ -406,7 +455,7 @@ protected final String id() {
406455

407456
@Override
408457
public List<String> getArgumentNames() {
409-
return List.of("code");
458+
return null;
410459
}
411460

412461
protected abstract String doApply(
@@ -465,10 +514,10 @@ protected ResponseExt responseByStatusCode(
465514

466515
protected Map<String, Object> newSnippetContext(String serverUrl, OperationExt operation) {
467516
Map<String, Object> map = new HashMap<>();
468-
map.put("pattern", operation.getPattern());
469-
map.put("path", operation.getPattern());
517+
map.put("pattern", operation.getPath());
518+
map.put("path", operation.getPath());
470519
map.put("method", operation.getMethod());
471-
map.put("url", serverUrl + operation.getPattern());
520+
map.put("url", serverUrl + operation.getPath());
472521
var requestHeaders = ArrayListMultimap.<String, String>create();
473522
var responseHeaders = ArrayListMultimap.<String, String>create();
474523
var headerParams =
@@ -524,14 +573,17 @@ protected List<Map<String, String>> schemaToTable(Schema<?> schema, EvaluationCo
524573
return fields;
525574
}
526575

576+
protected List<Parameter> parameters(OperationExt operation, Predicate<Parameter> predicate) {
577+
return Optional.ofNullable(operation.getParameters()).orElse(List.of()).stream()
578+
.filter(predicate)
579+
.sorted(Comparator.comparing(Parameter::getName))
580+
.toList();
581+
}
582+
527583
protected List<Map<String, String>> parametersToTable(
528584
OperationExt operation, Predicate<Parameter> predicate) {
529585
List<Map<String, String>> fields = new ArrayList<>();
530-
var parameters =
531-
Optional.ofNullable(operation.getParameters()).orElse(List.of()).stream()
532-
.filter(predicate)
533-
.sorted(Comparator.comparing(Parameter::getName))
534-
.toList();
586+
var parameters = parameters(operation, predicate);
535587
parameters.forEach(
536588
it -> {
537589
var schema = it.getSchema();
@@ -601,27 +653,36 @@ protected Multimap<CharSequence, String> parseHeaders(Collection<String> headers
601653
protected static final Set<String> READ_METHODS = Set.of("GET", "HEAD");
602654

603655
protected String toString(Multimap<String, String> options) {
604-
if (options.isEmpty()) {
605-
return "";
606-
}
607656
var sb = new StringBuilder();
608657
var separator = "\\\n";
609658
var tabSize = id().length() + 1;
610-
options.forEach(
611-
(k, v) -> {
612-
if (!sb.isEmpty()) {
613-
sb.append(" ".repeat(tabSize));
614-
}
615-
sb.append(k);
616-
if (v != null && !v.isEmpty()) {
617-
sb.append(" ").append(v);
618-
}
619-
sb.append(separator);
620-
});
659+
for (Map.Entry<String, String> entry : options.entries()) {
660+
var k = entry.getKey();
661+
var v = entry.getValue();
662+
if (!sb.isEmpty()) {
663+
sb.append(" ".repeat(tabSize));
664+
}
665+
sb.append(k);
666+
if (v != null && !v.isEmpty()) {
667+
sb.append(" ").append(v);
668+
}
669+
sb.append(separator);
670+
}
621671
sb.setLength(sb.length() - separator.length());
622672
return sb.toString();
623673
}
624674

675+
protected Map<String, Object> positionalArgs(Map<String, Object> args) {
676+
var optionList = new ArrayList<>(args.values());
677+
Map<String, Object> result = new LinkedHashMap<>();
678+
for (int i = 0; i < optionList.size(); i += 2) {
679+
var key = optionList.get(i).toString();
680+
var value = optionList.get(i + 1);
681+
result.put(key, value);
682+
}
683+
return result;
684+
}
685+
625686
protected Multimap<String, String> args(Map<String, Object> args) {
626687
Multimap<String, String> result = LinkedHashMultimap.create();
627688
var optionList = new ArrayList<>(args.values());

modules/jooby-openapi/src/main/java/io/jooby/openapi/OpenAPIGenerator.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -265,7 +265,7 @@ public OpenAPIGenerator() {}
265265
Map<String, Tag> globalTags = new LinkedHashMap<>();
266266
Paths paths = new Paths();
267267
for (OperationExt operation : operations) {
268-
String pattern = operation.getPattern();
268+
String pattern = operation.getPath();
269269
if (!includes(pattern) || excludes(pattern)) {
270270
log.debug("skipping {}", pattern);
271271
continue;

modules/jooby-openapi/src/main/resources/io/jooby/openapi/templates/asciidoc/default-cookie-parameters.snippet

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
[cols="1,3"]
12
|===
23
|Parameter|Description
34
{% for cookie in cookies %}
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
[source,bash]
1+
[source{% if language %}, ${language}{%endif%}]
22
----
33
curl ${options}
44
----

modules/jooby-openapi/src/main/resources/io/jooby/openapi/templates/asciidoc/default-form-parameters.snippet

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
[cols="1,1,3"]
12
|===
23
|Parameter|Type|Description
34
{% for parameter in parameters %}

modules/jooby-openapi/src/main/resources/io/jooby/openapi/templates/asciidoc/default-path-parameters.snippet

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
[cols="1,1,3"]
12
|===
23
|Parameter|Type|Description
34
{% for parameter in parameters %}

0 commit comments

Comments
 (0)