Skip to content

Commit 5c95b34

Browse files
committed
Fix extensions problems and improve api
1 parent 3e14c85 commit 5c95b34

File tree

7 files changed

+132
-30
lines changed

7 files changed

+132
-30
lines changed

src/main/java/com/qdesrame/openapi/diff/compare/ExtensionDiff.java

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
package com.qdesrame.openapi.diff.compare;
22

3+
import com.qdesrame.openapi.diff.model.Change;
34
import com.qdesrame.openapi.diff.model.Changed;
45
import com.qdesrame.openapi.diff.model.DiffContext;
56

@@ -11,5 +12,10 @@ public interface ExtensionDiff {
1112

1213
String getName();
1314

14-
Optional<Changed> diff(Object left, Object right, DiffContext context);
15+
Optional<Changed> diff(Change extension, DiffContext context);
16+
17+
default boolean isParentApplicable(Change.Type type, Object object, Object extension, DiffContext context) {
18+
return true;
19+
}
20+
1521
}

src/main/java/com/qdesrame/openapi/diff/compare/ExtensionsDiff.java

Lines changed: 39 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,13 @@
11
package com.qdesrame.openapi.diff.compare;
22

3+
import com.qdesrame.openapi.diff.model.Change;
4+
import com.qdesrame.openapi.diff.model.Changed;
5+
import com.qdesrame.openapi.diff.model.CompatibleChanged;
36
import com.qdesrame.openapi.diff.model.DiffContext;
47
import com.qdesrame.openapi.diff.model.schema.ChangedExtensions;
58

69
import java.util.*;
10+
import java.util.function.Function;
711

812
import static com.qdesrame.openapi.diff.utils.ChangedUtils.isChanged;
913

@@ -21,23 +25,49 @@ public ExtensionsDiff(OpenApiDiff openApiDiff) {
2125
}
2226
}
2327

28+
public boolean isParentApplicable(Change.Type type, Object parent, Map<String, Object> extensions, DiffContext context) {
29+
if (extensions.size() == 0) {
30+
return true;
31+
}
32+
return extensions.entrySet().stream()
33+
.map(entry -> executeExtension(entry.getKey(), extensionDiff -> extensionDiff.isParentApplicable(type, parent, entry.getValue(), context)))
34+
.allMatch(aBoolean -> aBoolean.orElse(true));
35+
}
36+
37+
public Optional<ExtensionDiff> getExtensionDiff(String name) {
38+
return extensionsDiff.stream()
39+
.filter(diff -> ("x-" + diff.getName()).equals(name))
40+
.findFirst();
41+
}
42+
43+
public <T> Optional<T> executeExtension(String name, Function<ExtensionDiff, T> predicate) {
44+
return getExtensionDiff(name)
45+
.map(extensionDiff -> extensionDiff.setOpenApiDiff(openApiDiff))
46+
.map(predicate);
47+
}
48+
2449
public Optional<ChangedExtensions> diff(Map<String, Object> left, Map<String, Object> right, DiffContext context) {
2550
if (null == left) left = new LinkedHashMap<>();
2651
if (null == right) right = new LinkedHashMap<>();
2752
ChangedExtensions changedExtensions = new ChangedExtensions(left, new LinkedHashMap<>(right), context);
28-
changedExtensions.getIncreased().putAll(right);
2953
for (String key : left.keySet()) {
30-
if (changedExtensions.getIncreased().containsKey(key)) {
31-
Optional<ExtensionDiff> extensionDiff = extensionsDiff.stream()
32-
.filter(diff -> ("x-" + diff.getName()).equals(key)).findFirst();
33-
Object leftValue = left.get(key);
34-
Object rightValue = changedExtensions.getIncreased().remove(key);
35-
extensionDiff.ifPresent(diff -> diff.setOpenApiDiff(openApiDiff).diff(leftValue, rightValue, context)
36-
.ifPresent(changed -> changedExtensions.getChanged().put(key, changed)));
54+
Object leftValue = left.get(key);
55+
if (right.containsKey(key)) {
56+
Object rightValue = right.remove(key);
57+
executeExtensionDiff(key, Change.changed(leftValue, rightValue), context)
58+
.ifPresent(changed -> changedExtensions.getChanged().put(key, changed));
3759
} else {
38-
changedExtensions.getMissing().put(key, left.get(key));
60+
executeExtensionDiff(key, Change.removed(leftValue), context)
61+
.ifPresent(changed -> changedExtensions.getMissing().put(key, changed));
3962
}
4063
}
64+
right.forEach((key, value) -> executeExtensionDiff(key, Change.added(value), context)
65+
.ifPresent(changed -> changedExtensions.getIncreased().put(key, changed)));
4166
return isChanged(changedExtensions);
4267
}
68+
69+
private Optional<Changed> executeExtensionDiff(String name, Change change, DiffContext context) {
70+
return executeExtension(name, diff -> diff.setOpenApiDiff(openApiDiff).diff(change, context))
71+
.orElse(Optional.of(CompatibleChanged.compatible(change)));
72+
}
4373
}

src/main/java/com/qdesrame/openapi/diff/compare/schemadiffresult/SchemaDiffResult.java

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

33
import com.qdesrame.openapi.diff.compare.MapKeyDiff;
44
import com.qdesrame.openapi.diff.compare.OpenApiDiff;
5+
import com.qdesrame.openapi.diff.model.Change;
56
import com.qdesrame.openapi.diff.model.ChangedSchema;
67
import com.qdesrame.openapi.diff.model.DiffContext;
78
import com.qdesrame.openapi.diff.model.ListDiff;
@@ -13,9 +14,9 @@
1314
import lombok.Getter;
1415

1516
import java.util.*;
16-
import java.util.stream.Collectors;
1717

1818
import static com.qdesrame.openapi.diff.utils.ChangedUtils.isChanged;
19+
import static java.util.Optional.ofNullable;
1920

2021
@Getter
2122
public class SchemaDiffResult {
@@ -60,8 +61,8 @@ public Optional<ChangedSchema> diff(HashSet<String> refSet, Components leftCompo
6061

6162
compareAdditionalProperties(refSet, left, right, context);
6263

63-
changedSchema.getIncreasedProperties().putAll(filterProperties(propertyDiff.getIncreased(), context));
64-
changedSchema.getMissingProperties().putAll(filterProperties(propertyDiff.getMissing(), context));
64+
changedSchema.getIncreasedProperties().putAll(filterProperties(Change.Type.ADDED, propertyDiff.getIncreased(), context));
65+
changedSchema.getMissingProperties().putAll(filterProperties(Change.Type.REMOVED, propertyDiff.getMissing(), context));
6566
return isApplicable(context);
6667
}
6768

@@ -73,10 +74,19 @@ protected Optional<ChangedSchema> isApplicable(DiffContext context) {
7374
return isChanged(changedSchema);
7475
}
7576

76-
private Map<String, Schema> filterProperties(Map<String, Schema> properties, DiffContext context) {
77-
return properties.entrySet().stream()
78-
.filter(entry -> isPropertyApplicable(entry.getValue(), context))
79-
.collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));
77+
private Map<String, Schema> filterProperties(Change.Type type, Map<String, Schema> properties, DiffContext context) {
78+
Map<String, Schema> result = new LinkedHashMap<>();
79+
for (Map.Entry<String, Schema> entry : properties.entrySet()) {
80+
if (isPropertyApplicable(entry.getValue(), context)
81+
&& openApiDiff.getExtensionsDiff()
82+
.isParentApplicable(
83+
type,
84+
entry.getValue(),
85+
ofNullable(entry.getValue().getExtensions()).orElse(new LinkedHashMap()), context)) {
86+
result.put(entry.getKey(), entry.getValue());
87+
}
88+
}
89+
return result;
8090
}
8191

8292
private boolean isPropertyApplicable(Schema schema, DiffContext context) {
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
package com.qdesrame.openapi.diff.model;
2+
3+
import lombok.Getter;
4+
5+
@Getter
6+
public class Change<T> {
7+
private final T oldValue;
8+
private final T newValue;
9+
private final Type type;
10+
11+
private Change(T oldValue, T newValue, Type type) {
12+
this.oldValue = oldValue;
13+
this.newValue = newValue;
14+
this.type = type;
15+
}
16+
17+
public static <T> Change<T> changed(T oldValue, T newValue) {
18+
return new Change<>(oldValue, newValue, Type.CHANGED);
19+
}
20+
21+
public static <T> Change<T> added(T newValue) {
22+
return new Change<>(null, newValue, Type.ADDED);
23+
}
24+
25+
public static <T> Change<T> removed(T oldValue) {
26+
return new Change<>(oldValue, null, Type.REMOVED);
27+
}
28+
29+
public enum Type {
30+
ADDED,
31+
CHANGED,
32+
REMOVED
33+
}
34+
}
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
package com.qdesrame.openapi.diff.model;
2+
3+
public class CompatibleChanged implements Changed {
4+
private final Object value;
5+
6+
private CompatibleChanged(Object value) {
7+
this.value = value;
8+
}
9+
10+
public static CompatibleChanged compatible(Change change) {
11+
return new CompatibleChanged(change);
12+
}
13+
14+
@Override
15+
public DiffResult isChanged() {
16+
return DiffResult.COMPATIBLE;
17+
}
18+
19+
public Object getValue() {
20+
return value;
21+
}
22+
}

src/main/java/com/qdesrame/openapi/diff/model/schema/ChangedExtensions.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,8 @@ public class ChangedExtensions implements Changed {
1616
private final Map<String, Object> newExtensions;
1717
private final DiffContext context;
1818

19-
private Map<String, Object> increased;
20-
private Map<String, Object> missing;
19+
private Map<String, Changed> increased;
20+
private Map<String, Changed> missing;
2121
private Map<String, Changed> changed;
2222

2323
public ChangedExtensions(Map<String, Object> oldExtensions, Map<String, Object> newExtensions, DiffContext context) {

src/main/java/com/qdesrame/openapi/diff/output/MarkdownRender.java

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -117,7 +117,7 @@ protected String itemResponse(String code, ChangedResponse response) {
117117
}
118118

119119
protected String itemResponse(String title, String code, String description) {
120-
StringBuilder sb = new StringBuilder("");
120+
StringBuilder sb = new StringBuilder();
121121
String status = "";
122122
if (!code.equals("default")) {
123123
status = HttpStatus.getStatusText(Integer.parseInt(code));
@@ -128,7 +128,7 @@ protected String itemResponse(String title, String code, String description) {
128128
}
129129

130130
protected String headers(ChangedHeaders headers) {
131-
StringBuilder sb = new StringBuilder("");
131+
StringBuilder sb = new StringBuilder();
132132
if (headers != null) {
133133
sb.append(listHeader("New header", headers.getIncreased()));
134134
sb.append(listHeader("Deleted header", headers.getMissing()));
@@ -197,7 +197,7 @@ protected String schema(ChangedSchema schema) {
197197
}
198198

199199
protected String oneOfSchema(int deepness, ChangedOneOfSchema schema, String discriminator) {
200-
StringBuilder sb = new StringBuilder("");
200+
StringBuilder sb = new StringBuilder();
201201
schema.getMissingMapping().keySet()
202202
.forEach(key -> sb.append(format("%sDeleted '%s' %s\n", indent(deepness), key, discriminator)));
203203
schema.getIncreasedMapping().forEach((key, sub) ->
@@ -210,7 +210,7 @@ protected String oneOfSchema(int deepness, ChangedOneOfSchema schema, String dis
210210
}
211211

212212
protected String required(int deepness, String title, List<String> required) {
213-
StringBuilder sb = new StringBuilder("");
213+
StringBuilder sb = new StringBuilder();
214214
if (required.size() > 0) {
215215
sb.append(format("%s%s:\n", indent(deepness), title));
216216
required.forEach(s -> sb.append(format("%s- `%s`\n", indent(deepness), s)));
@@ -220,7 +220,7 @@ protected String required(int deepness, String title, List<String> required) {
220220
}
221221

222222
protected String schema(int deepness, ChangedSchema schema) {
223-
StringBuilder sb = new StringBuilder("");
223+
StringBuilder sb = new StringBuilder();
224224
if (schema.isDiscriminatorPropertyChanged()) {
225225
LOGGER.debug("Discriminator property changed");
226226
}
@@ -244,7 +244,7 @@ protected String schema(int deepness, ChangedSchema schema) {
244244
}
245245

246246
protected String schema(int deepness, ComposedSchema schema, DiffContext context) {
247-
StringBuilder sb = new StringBuilder("");
247+
StringBuilder sb = new StringBuilder();
248248
if (schema.getAllOf() != null && schema.getAllOf() != null) {
249249
LOGGER.debug("All of schema");
250250
schema.getAllOf().stream()
@@ -262,7 +262,7 @@ protected String schema(int deepness, ComposedSchema schema, DiffContext context
262262
}
263263

264264
protected String schema(int deepness, Schema schema, DiffContext context) {
265-
StringBuilder sb = new StringBuilder("");
265+
StringBuilder sb = new StringBuilder();
266266
sb.append(listItem(deepness, "Enum", schema.getEnum()));
267267
sb.append(properties(deepness, "Property", schema.getProperties(), true, context));
268268
if (schema instanceof ComposedSchema) {
@@ -274,7 +274,7 @@ protected String schema(int deepness, Schema schema, DiffContext context) {
274274
}
275275

276276
protected String items(int deepness, ChangedSchema schema) {
277-
StringBuilder sb = new StringBuilder("");
277+
StringBuilder sb = new StringBuilder();
278278
String type = type(schema.getNewSchema());
279279
if (schema.isChangedType()) {
280280
type = type(schema.getOldSchema()) + " -> " + type(schema.getNewSchema());
@@ -295,7 +295,7 @@ protected String items(int deepness, String title, String type, String descripti
295295
}
296296

297297
protected String properties(final int deepness, String title, Map<String, Schema> properties, boolean showContent, DiffContext context) {
298-
StringBuilder sb = new StringBuilder("");
298+
StringBuilder sb = new StringBuilder();
299299
if (properties != null) {
300300
properties.forEach((key, value) -> {
301301
sb.append(property(deepness, title, key, resolve(value)));
@@ -335,7 +335,7 @@ protected String listDiff(int deepness, String name, ListDiff listDiff) {
335335
}
336336

337337
protected <T> String listItem(int deepness, String name, List<T> list) {
338-
StringBuilder sb = new StringBuilder("");
338+
StringBuilder sb = new StringBuilder();
339339
if (list != null && list.size() > 0) {
340340
sb.append(format("%s%s value%s:\n\n", indent(deepness), name, list.size() > 1 ? "s" : ""));
341341
list.forEach(p -> sb.append(format("%s* `%s`\n", indent(deepness), p)));
@@ -353,7 +353,7 @@ protected String parameters(ChangedParameters changedParameters) {
353353
}
354354

355355
protected String listParameter(String title, List<Parameter> parameters) {
356-
StringBuilder sb = new StringBuilder("");
356+
StringBuilder sb = new StringBuilder();
357357
parameters.stream().map(p -> itemParameter(title, p)).forEach(sb::append);
358358
return sb.toString();
359359
}

0 commit comments

Comments
 (0)