diff --git a/CHANGELOG.md b/CHANGELOG.md index f59fffa6..23e2ba4f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] ### `jsonschema-generator` +#### Changed +- apply property name overrides before triggering the ignore check (i.e., provide both the declared and overridden property names if there is one) +- update various (runtime/test/build-time) dependencies + #### Fixed - avoid exception when trying to collect supported enum values from raw `Enum` type (i.e., missing type parameter) - avoid exception when trying to find type with annotation when given type is `null` @@ -13,6 +17,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### `jsonschema-module-jackson` #### Fixed - avoid exception in subtype resolution, when targeting void method +- check for ignored properties excluded fields when a property name override makes it conflict with a non-conventional getter method ### `jsonschema-maven-plugin` ### Added diff --git a/jsonschema-generator/src/main/java/com/github/victools/jsonschema/generator/impl/MemberCollectionContextImpl.java b/jsonschema-generator/src/main/java/com/github/victools/jsonschema/generator/impl/MemberCollectionContextImpl.java index 19fbfbbc..d44a2265 100644 --- a/jsonschema-generator/src/main/java/com/github/victools/jsonschema/generator/impl/MemberCollectionContextImpl.java +++ b/jsonschema-generator/src/main/java/com/github/victools/jsonschema/generator/impl/MemberCollectionContextImpl.java @@ -127,6 +127,7 @@ private void collectStaticMembers(HierarchicType singleHierarchy) { private void collectFields(ResolvedField[] fields, MemberScope.DeclarationDetails declarationDetails) { Stream.of(fields) .map(declaredField -> this.typeContext.createFieldScope(declaredField, declarationDetails)) + .map(this::getMemberWithNameOverride) .filter(fieldScope -> !this.generatorConfig.shouldIgnore(fieldScope)) .forEach(this::collect); } @@ -140,6 +141,7 @@ private void collectFields(ResolvedField[] fields, MemberScope.DeclarationDetail private void collectMethods(ResolvedMethod[] methods, MemberScope.DeclarationDetails declarationDetails) { Stream.of(methods) .map(declaredMethod -> this.typeContext.createMethodScope(declaredMethod, declarationDetails)) + .map(this::getMemberWithNameOverride) .filter(methodScope -> !this.generatorConfig.shouldIgnore(methodScope)) .forEach(this::collect); } @@ -150,27 +152,26 @@ private void collectMethods(ResolvedMethod[] methods, MemberScope.DeclarationDet * @param member field/method to add */ public void collect(MemberScope member) { + String propertyName = member.getSchemaPropertyName(); if (member.isFakeContainerItemScope()) { - this.collectedProperties.put(member.getSchemaPropertyName(), member); + this.collectedProperties.put(propertyName, member); return; } - MemberScope memberWithNameOverride = this.getMemberWithNameOverride(member); - this.registerIfRequired(memberWithNameOverride); - String propertyName = memberWithNameOverride.getSchemaPropertyName(); + this.registerIfRequired(member); if (this.collectedProperties.containsKey(propertyName)) { - logger.debug("ignoring overridden {}.{}", memberWithNameOverride.getDeclaringType(), memberWithNameOverride.getDeclaredName()); + logger.debug("ignoring overridden {}.{}", member.getDeclaringType(), member.getDeclaredName()); } else { - this.collectedProperties.put(propertyName, memberWithNameOverride); + this.collectedProperties.put(propertyName, member); } } - private MemberScope getMemberWithNameOverride(MemberScope member) { + private > M getMemberWithNameOverride(M member) { String propertyNameOverride = member.getContext().performActionOnMember(member, this.generatorConfig::resolvePropertyNameOverride, this.generatorConfig::resolvePropertyNameOverride); if (propertyNameOverride == null) { return member; } - return member.withOverriddenName(propertyNameOverride); + return (M) member.withOverriddenName(propertyNameOverride); } private void registerIfRequired(MemberScope member) { diff --git a/jsonschema-module-jackson/src/main/java/com/github/victools/jsonschema/module/jackson/JacksonModule.java b/jsonschema-module-jackson/src/main/java/com/github/victools/jsonschema/module/jackson/JacksonModule.java index 1d887605..fef0fda2 100644 --- a/jsonschema-module-jackson/src/main/java/com/github/victools/jsonschema/module/jackson/JacksonModule.java +++ b/jsonschema-module-jackson/src/main/java/com/github/victools/jsonschema/module/jackson/JacksonModule.java @@ -289,13 +289,16 @@ protected boolean shouldIgnoreField(FieldScope field) { // some kinds of field ignorals are only available via an annotation introspector Set ignoredProperties = this.objectMapper.getSerializationConfig().getAnnotationIntrospector() .findPropertyIgnoralByName(null, beanDescription.getClassInfo()).getIgnored(); - String fieldName = field.getName(); - if (ignoredProperties.contains(fieldName)) { + String declaredName = field.getDeclaredName(); + if (ignoredProperties.contains(declaredName)) { return true; } + // @since 4.37.0 also consider overridden property name as it may match the getter method + String fieldName = field.getName(); // other kinds of field ignorals are handled implicitly, i.e. are only available by way of being absent return beanDescription.findProperties().stream() - .noneMatch(propertyDefinition -> fieldName.equals(propertyDefinition.getInternalName())); + .noneMatch(propertyDefinition -> declaredName.equals(propertyDefinition.getInternalName()) + || fieldName.equals(propertyDefinition.getInternalName())); } /** diff --git a/jsonschema-module-jackson/src/test/java/com/github/victools/jsonschema/module/jackson/IgnorePropertyTest.java b/jsonschema-module-jackson/src/test/java/com/github/victools/jsonschema/module/jackson/IgnorePropertyTest.java index 2077d9ea..c41c99b1 100644 --- a/jsonschema-module-jackson/src/test/java/com/github/victools/jsonschema/module/jackson/IgnorePropertyTest.java +++ b/jsonschema-module-jackson/src/test/java/com/github/victools/jsonschema/module/jackson/IgnorePropertyTest.java @@ -19,6 +19,7 @@ import com.fasterxml.jackson.annotation.JsonBackReference; import com.fasterxml.jackson.annotation.JsonIgnore; import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.JsonNode; import com.github.victools.jsonschema.generator.Option; @@ -44,7 +45,8 @@ public class IgnorePropertyTest { static Stream parametersForTestJsonIgnoreProperties() { return Stream.of( Arguments.of(SubType.class, "[includedChildField, includedParentField1, includedParentField2]"), - Arguments.of(SuperType.class, "[ignoredParentField2, includedParentField1]") + Arguments.of(SuperType.class, "[ignoredParentField2, includedParentField1]"), + Arguments.of(TypeWithUnderscoreField.class, "[import]") ); } @@ -84,4 +86,17 @@ private static class SuperType { @JsonBackReference public String ignoredParentField3; } + + private static class TypeWithUnderscoreField { + @JsonProperty("import") + private int _import; + + public int getImport() { + return this._import; + } + + public String getIgnoredValue() { + return "method being ignored, because there is no matching field"; + } + } }