Skip to content

Commit 5ff2e3d

Browse files
committed
- Revert cleaning trailing white spaces from markdown file
- Make the changes backward compatible with custom filters - Iterate over nested callbacks in path items
1 parent 97f13fa commit 5ff2e3d

4 files changed

Lines changed: 307 additions & 44 deletions

File tree

docs/customization.md

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,7 @@ Excluding `SupportingFiles`, each of the above options may result in multiple fi
7575
Note that user-defined templates will merge with built-in template definitions. If a supporting file with the sample template file path exists, it will be replaced with the user-defined template, otherwise the user-defined template will be added to the list of template files to compile. If the generator's built-in template is `model_docs.mustache` and you define `model-docs.mustache`, this will result in duplicated model docs (if `destinationFilename` differs) or undefined behavior as whichever template compiles last will overwrite the previous model docs (if `destinationFilename` matches the extension or suffix in the generator's code).
7676

7777
## Custom Generator (and Template)
78-
78+
7979
<a id="creating-a-new-template"></a> If none of the built-in generators suit your needs and you need to do more than just modify the mustache templates to tweak generated code, you can create a brand new generator and its associated templates. OpenAPI Generator can help with this, using the `meta` command:
8080

8181
```sh
@@ -95,7 +95,7 @@ To compile your library, enter the `out/generators/my-codegen` directory, run `m
9595

9696
**NOTE** Running your custom generator requires adding it to the classpath. This differs on [Windows](https://docs.oracle.com/javase/8/docs/technotes/tools/windows/classpath.html) slightly from [unix](https://docs.oracle.com/javase/8/docs/technotes/tools/unix/classpath.html).
9797
If you are running a Windows Subsystem for Linux or a shell such as gitbash, and have issues with the unix variant, try the Windows syntax below.
98-
98+
9999
Now, execute the generator:
100100

101101
```sh
@@ -536,7 +536,7 @@ Another useful option is `inlineSchemaOptions`, which allows you to customize ho
536536
537537
OpenAPI Normalizer transforms the input OpenAPI doc/spec (which may not perfectly conform to the specification) to make it workable with OpenAPI Generator. A few rules are switched on by default since 7.0.0 release:
538538
539-
- SIMPLIFY_ONEOF_ANYOF
539+
- SIMPLIFY_ONEOF_ANYOF
540540
- SIMPLIFY_BOOLEAN_ENUM
541541
- SIMPLIFY_ONEOF_ANYOF_ENUM
542542
- REFACTOR_ALLOF_WITH_PROPERTIES_ONLY
@@ -637,7 +637,7 @@ Example:
637637
java -jar modules/openapi-generator-cli/target/openapi-generator-cli.jar generate -g java -i modules/openapi-generator/src/test/resources/3_0/enableKeepOnlyFirstTagInOperation_test.yaml -o /tmp/java-okhttp/ --openapi-normalizer REMOVE_X_INTERNAL=true
638638
```
639639
640-
- `NORMALIZER_CLASS`: Set to full classname of a class extending the default org.openapitools.codegen.OpenAPINormalizer. It allows customization of the default normalizer.
640+
- `NORMALIZER_CLASS`: Set to full classname of a class extending the default org.openapitools.codegen.OpenAPINormalizer. It allows customization of the default normalizer.
641641
642642
Example:
643643
```
@@ -687,16 +687,16 @@ The `FILTER` parameter allows selective inclusion of API operations based on spe
687687

688688
### Available Filters
689689

690-
- **`operationId`**
690+
- **`operationId`**
691691
When set to `operationId:addPet|getPetById`, operations **not** matching `addPet` or `getPetById` will be marked as internal (`x-internal: true`), and excluded from generation. Matching operations will have `x-internal: false`.
692692

693-
- **`method`**
693+
- **`method`**
694694
When set to `method:get|post`, operations **not** using `GET` or `POST` methods will be marked as internal (`x-internal: true`), preventing their generation.
695695

696-
- **`tag`**
696+
- **`tag`**
697697
When set to `tag:person|basic`, operations **not** tagged with `person` or `basic` will be marked as internal (`x-internal: true`), and will not be generated.
698698

699-
- **`path`**
699+
- **`path`**
700700
When set to `path:/v1|/v2`, operations on paths **not** starting with `/v1` or with `/v2` will be marked as internal (`x-internal: true`), and will not be generated.
701701

702702
### Example Usage

modules/openapi-generator/src/main/java/org/openapitools/codegen/OpenAPINormalizer.java

Lines changed: 64 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -349,10 +349,10 @@ public void processRules(Map<String, String> inputRules) {
349349
* @param openApi Contract used in the filtering (could be used for customization).
350350
* @param input full input value
351351
*
352-
* @return an OperationsFilter containing the parsed filters.
352+
* @return an Filter containing the parsed filters.
353353
*/
354-
protected OperationsFilter createOperationsFilter(OpenAPI openApi, String input) {
355-
return new OperationsFilter(input);
354+
protected Filter createFilter(OpenAPI openApi, String input) {
355+
return new Filter(input);
356356
}
357357

358358
/**
@@ -415,10 +415,10 @@ protected void normalizePaths() {
415415
return;
416416
}
417417

418-
OperationsFilter filter = null;
418+
Filter filter = null;
419419
if (Boolean.TRUE.equals(getRule(FILTER))) {
420420
String filters = inputRules.get(FILTER);
421-
filter = createOperationsFilter(this.openAPI, filters);
421+
filter = createFilter(this.openAPI, filters);
422422
if (!filter.parse()) {
423423
filter = null;
424424
}
@@ -702,7 +702,7 @@ private void cleanupSecuritySchemeReferences(Iterable<String> schemesToClean) {
702702
}
703703
}
704704

705-
// Callbacks
705+
// Callbacks from Components
706706
if (openAPI.getComponents() != null && openAPI.getComponents().getCallbacks() != null) {
707707
Map<String, Callback> callbacks = openAPI.getComponents().getCallbacks();
708708
for (Callback callback : callbacks.values()) {
@@ -714,20 +714,42 @@ private void cleanupSecuritySchemeReferences(Iterable<String> schemesToClean) {
714714
}
715715
}
716716
}
717+
718+
// Path items from Components
719+
if (openAPI.getComponents() != null && openAPI.getComponents().getPathItems() != null) {
720+
Map<String, PathItem> pathItems = openAPI.getComponents().getPathItems();
721+
for (PathItem path : pathItems.values()) {
722+
cleanupPathItemSecuritySchemes(path, schemesToClean);
723+
}
724+
}
717725
}
718726

719727
/**
720-
* Cleans up the references to the security schemes that are removed by the filter in a given PathItem.
721-
* @param path the PathItem to clean up
728+
* Cleans up the references to the security schemes that are removed by the
729+
* filter in a given PathItem.
730+
*
731+
* @param path the PathItem to clean up
722732
* @param schemesToClean the security schemes keys to remove
723733
*/
724734
private void cleanupPathItemSecuritySchemes(PathItem path, Iterable<String> schemesToClean) {
725735
if (path == null || schemesToClean == null) {
726736
return;
727737
}
728738

729-
List<Operation> operations = new ArrayList<>(path.readOperations());
730-
for (Operation operation : operations) {
739+
List<Operation> operations = new LinkedList<>(path.readOperations());
740+
// An infinite loop is impossible here because it is impossible without using
741+
// references from components and we clean up components separately
742+
while (!operations.isEmpty()) {
743+
Operation operation = operations.remove(0);
744+
Map<String, Callback> callbacks = operation.getCallbacks();
745+
if (callbacks != null) {
746+
for (Callback callback : callbacks.values()) {
747+
for (PathItem callbackPath : callback.values()) {
748+
operations.addAll(callbackPath.readOperations());
749+
}
750+
}
751+
}
752+
731753
if (operation.getSecurity() == null) {
732754
continue;
733755
}
@@ -2453,13 +2475,19 @@ protected Logger getLogger() {
24532475
}
24542476
}
24552477

2456-
protected static class OperationsFilter extends BaseFilter {
2478+
// Filter for API operations
2479+
protected static class Filter extends BaseFilter {
24572480
public static final String OPERATION_ID = "operationId";
24582481
public static final String METHOD = "method";
24592482
public static final String TAG = "tag";
24602483
public static final String PATH = "path";
2484+
// Keep next four fields for backward compatibility of custom made filters. New filters should use filteringMethodsMap directly.
2485+
protected Set<String> operationIdFilters = Collections.emptySet();
2486+
protected Set<String> methodFilters = Collections.emptySet();
2487+
protected Set<String> tagFilters = Collections.emptySet();
2488+
protected Set<String> pathStartingWithFilters = Collections.emptySet();
24612489

2462-
protected OperationsFilter(String filters) {
2490+
protected Filter(String filters) {
24632491
super(filters);
24642492
}
24652493

@@ -2472,14 +2500,37 @@ public Set<String> filteringMethods() {
24722500
public String usageMessage() {
24732501
return String.format(Locale.ROOT,
24742502
"FILTER rule must be in the form of `%s:name1|name2|name3` or `%s:get|post|put` or `%s:tag1|tag2|tag3` or `%s:/v1|/v2`.",
2475-
OperationsFilter.OPERATION_ID, OperationsFilter.METHOD, OperationsFilter.TAG, OperationsFilter.PATH);
2503+
Filter.OPERATION_ID, Filter.METHOD, Filter.TAG, Filter.PATH);
24762504
}
24772505

24782506
@Override
24792507
protected void logMatch(String filterName, String subjectId) {
24802508
getLogger().info("Operation `{}` matches the {} filter and remains", subjectId, filterName);
24812509
}
24822510

2511+
// Having that just to fill the fields for backward compatibility of custom made filters
2512+
@Override
2513+
public boolean parse() {
2514+
boolean result = super.parse();
2515+
operationIdFilters = filteringMethodsMap.getOrDefault(OPERATION_ID, Collections.emptySet());
2516+
methodFilters = filteringMethodsMap.getOrDefault(METHOD, Collections.emptySet());
2517+
tagFilters = filteringMethodsMap.getOrDefault(TAG, Collections.emptySet());
2518+
pathStartingWithFilters = filteringMethodsMap.getOrDefault(PATH, Collections.emptySet());
2519+
return result;
2520+
}
2521+
2522+
// Keep next two methods for backward compatibility of custom made filters.
2523+
protected boolean logIfMatch(String filterName, Operation operation, boolean filterMatched) {
2524+
if (filterMatched) {
2525+
logMatch(filterName, operation);
2526+
}
2527+
return filterMatched;
2528+
}
2529+
2530+
protected void logMatch(String filterName, Operation operation) {
2531+
getLogger().info("operation `{}` marked as internal only (x-internal: true) by the {} FILTER", operation.getOperationId(), filterName);
2532+
}
2533+
24832534
/**
24842535
* Test if the OpenAPI contract match an extra filter.
24852536
*

0 commit comments

Comments
 (0)