Skip to content

Commit

Permalink
feat: include property name override before ignore check
Browse files Browse the repository at this point in the history
  • Loading branch information
CarstenWickner committed Oct 31, 2024
1 parent 89128e8 commit c6998a2
Show file tree
Hide file tree
Showing 4 changed files with 36 additions and 12 deletions.
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,18 @@ 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`

### `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
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}
Expand All @@ -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);
}
Expand All @@ -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 extends MemberScope<?, ?>> 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) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -289,13 +289,16 @@ protected boolean shouldIgnoreField(FieldScope field) {
// some kinds of field ignorals are only available via an annotation introspector
Set<String> 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()));
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -44,7 +45,8 @@ public class IgnorePropertyTest {
static Stream<Arguments> 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]")
);
}

Expand Down Expand Up @@ -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";
}
}
}

0 comments on commit c6998a2

Please sign in to comment.