Skip to content

Commit 28eb441

Browse files
Merge pull request #35 from victools/consider-sub-types
2 parents 3f28640 + 8f90589 commit 28eb441

26 files changed

+1309
-442
lines changed

CHANGELOG.md

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,13 +5,18 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
55
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
66

77
## [Unreleased]
8+
### Added
9+
- Enable declaration of subtypes through `withSubtypeResolver(SubtypeResolver)` on `forTypesInGeneral()` (#24)
10+
11+
### Changed
12+
- Move custom definitions and type attribute overrides into `forTypesInGeneral()` (while preserving delegate setters on config builder)
813

914
## [4.3.0] - 2020-02-28
1015
### Changed
11-
- limit collected type attributes by declared "type" (prior to any `TypeAttributeOverride`!)
16+
- Limit collected type attributes by declared "type" (prior to any `TypeAttributeOverride`!)
1217

1318
### Fixed
14-
- not declare any "type" for `Object.class` by default
19+
- Not declare any "type" for `Object.class` by default
1520

1621
## [4.2.0] - 2020-02-27
1722
### Added
@@ -25,15 +30,15 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
2530

2631
## [4.1.0] - 2020-02-18
2732
### Added
28-
- new `Option.FLATTENED_ENUMS_FROM_TOSTRING`, using `toString()` instead of `name()` as per `Option.FLATTENED_ENUMS`
33+
- New `Option.FLATTENED_ENUMS_FROM_TOSTRING`, using `toString()` instead of `name()` as per `Option.FLATTENED_ENUMS`
2934

3035
## [4.0.2] - 2020-01-30
3136
### Fixed
32-
- avoid further characters in definition keys that are not URI-compatible (#19)
37+
- Avoid further characters in definition keys that are not URI-compatible (#19)
3338

3439
## [4.0.1] - 2020-01-29
3540
### Fixed
36-
- avoid white-spaces in definition keys
41+
- Avoid white-spaces in definition keys
3742

3843
## [4.0.0] - 2020-01-03
3944
### Added

README.md

Lines changed: 23 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -151,29 +151,30 @@ configBuilder.forTypesInGeneral()
151151
| 1 | `$schema` | Fixed to "http://json-schema.org/draft-07/schema#" – can be toggled on/off via `Option.SCHEMA_VERSION_INDICATOR`. |
152152
| 2 | `definitions` | Filled with sub-schemas to support circular references – via `Option.DEFINITIONS_FOR_ALL_OBJECTS` it can be configured whether only sub-schemas appearing more than once are included or all. |
153153
| 3 | `$ref` | Used with relative references to sub-schemas in `definitions`. |
154-
| 4 | `type` | Differentiating between `boolean`/`string`/`integer`/`number` for primitive/known types. `null` is added if a property is deemed nullable according to configuration (`SchemaGeneratorConfigPart.withNullableCheck()`). Arrays and sub-types of `Collection<?>` are treated as `array`, everything else as `object`. A declared type may be interpreted as another type according to configuration (`SchemaGeneratorConfigPart.withTargetTypeOverrideResolver()`). |
154+
| 4 | `type` | Differentiating between `boolean`/`string`/`integer`/`number` for primitive/known types. `null` is added if a property is deemed nullable according to configuration (`SchemaGeneratorConfigPart.withNullableCheck()`). Arrays and subtypes of `Collection<?>` are treated as `array`, everything else as `object`. A declared type may be interpreted as another type according to configuration (`SchemaGeneratorConfigPart.withTargetTypeOverrideResolver()`). |
155155
| 5 | `properties` | Listing all detected fields and/or methods in an `object`. Which ones are being included can be steered by various `Option`s or via one of the provided `OptionPreset`s as well as by ignoring individual ones via configuration (`SchemaGeneratorConfigPart.withIgnoreCheck()`). Names can be altered via configuration (`SchemaGeneratorConfigPart.withPropertyNameOverrideResolver()`). |
156156
| 6 | `items` | Indicating the type of `array`/`Collection` elements. |
157157
| 7 | `required` | Listing the names of fields/methods that are deemed mandatory according to configuration (`SchemaGeneratorConfigPart.withRequiredCheck()`). |
158158
| 8 | `allOf` | Used to combine general attributes derived from the type itself with attributes collected in the respective context of the associated field/method. |
159-
| 9 | `oneOf` | Used to indicate when a particular field/method can be of `type` `null`. |
160-
| 10 | `title` | Collected value according to configuration (`SchemaGeneratorConfigPart.withTitleResolver()`). |
161-
| 11 | `description` | Collected value according to configuration (`SchemaGeneratorConfigPart.withDescriptionResolver()`). |
162-
| 12 | `const` | Collected value according to configuration (`SchemaGeneratorConfigPart.withEnumResolver()`) if only a single value was found. |
163-
| 13 | `enum` | Collected value according to configuration (`SchemaGeneratorConfigPart.withEnumResolver()`) if multiple values were found. |
164-
| 14 | `default` | Collected value according to configuration (`SchemaGeneratorConfigPart.withDefaultResolver()`). |
165-
| 15 | `additionalProperties` | Collected value according to configuration (`SchemaGeneratorConfigPart.withAdditionalPropertiesResolver()`). |
166-
| 16 | `patternProperties` | Collected value(s) according to configuration (`SchemaGeneratorConfigPart.withPatternPropertiesResolver()`). |
167-
| 17 | `minLength` | Collected value according to configuration (`SchemaGeneratorConfigPart.withStringMinLengthResolver()`). |
168-
| 18 | `maxLength` | Collected value according to configuration (`SchemaGeneratorConfigPart.withStringMaxLengthResolver()`). |
169-
| 19 | `format` | Collected value according to configuration (`SchemaGeneratorConfigPart.withStringFormatResolver()`). |
170-
| 20 | `pattern` | Collected value according to configuration (`SchemaGeneratorConfigPart.withStringPatternResolver()`). |
171-
| 21 | `minimum` | Collected value according to configuration (`SchemaGeneratorConfigPart.withNumberInclusiveMinimumResolver()`). |
172-
| 22 | `exclusiveMinimum` | Collected value according to configuration (`SchemaGeneratorConfigPart.withNumberExclusiveMinimumResolver()`). |
173-
| 23 | `maximum` | Collected value according to configuration (`SchemaGeneratorConfigPart.withNumberInclusiveMaximumResolver()`). |
174-
| 24 | `exclusiveMaximum` | Collected value according to configuration (`SchemaGeneratorConfigPart.withNumberExclusiveMaximumResolver()`). |
175-
| 25 | `multipleOf` | Collected value according to configuration (`SchemaGeneratorConfigPart.withNumberMultipleOfResolver()`). |
176-
| 26 | `minItems` | Collected value according to configuration (`SchemaGeneratorConfigPart.withArrayMinItemsResolver()`). |
177-
| 27 | `maxItems` | Collected value according to configuration (`SchemaGeneratorConfigPart.withArrayMaxItemsResolver()`). |
178-
| 28 | `uniqueItems` | Collected value according to configuration (`SchemaGeneratorConfigPart.withArrayUniqueItemsResolver()`). |
179-
| 29 | any other | You can directly manipulate the generated `ObjectNode` of a sub-schema – e.g. setting additional attributes – via configuration based on a given type in general (`SchemaGeneratorConfigBuilder.with(TypeAttributeOverride)`) and/or in the context of a particular field/method (`SchemaGeneratorConfigPart.withInstanceAttributeOverride()`). |
159+
| 9 | `anyOf` | Used to list alternatives according to configuration (`SchemaGeneratorGeneralConfigPart.withSubtypeResolver()`). |
160+
| 10 | `oneOf` | Used to indicate when a particular field/method can be of `type` `null`. |
161+
| 11 | `title` | Collected value according to configuration (`SchemaGeneratorConfigPart.withTitleResolver()`). |
162+
| 12 | `description` | Collected value according to configuration (`SchemaGeneratorConfigPart.withDescriptionResolver()`). |
163+
| 13 | `const` | Collected value according to configuration (`SchemaGeneratorConfigPart.withEnumResolver()`) if only a single value was found. |
164+
| 14 | `enum` | Collected value according to configuration (`SchemaGeneratorConfigPart.withEnumResolver()`) if multiple values were found. |
165+
| 15 | `default` | Collected value according to configuration (`SchemaGeneratorConfigPart.withDefaultResolver()`). |
166+
| 16 | `additionalProperties` | Collected value according to configuration (`SchemaGeneratorConfigPart.withAdditionalPropertiesResolver()`). |
167+
| 17 | `patternProperties` | Collected value(s) according to configuration (`SchemaGeneratorConfigPart.withPatternPropertiesResolver()`). |
168+
| 18 | `minLength` | Collected value according to configuration (`SchemaGeneratorConfigPart.withStringMinLengthResolver()`). |
169+
| 19 | `maxLength` | Collected value according to configuration (`SchemaGeneratorConfigPart.withStringMaxLengthResolver()`). |
170+
| 20 | `format` | Collected value according to configuration (`SchemaGeneratorConfigPart.withStringFormatResolver()`). |
171+
| 21 | `pattern` | Collected value according to configuration (`SchemaGeneratorConfigPart.withStringPatternResolver()`). |
172+
| 22 | `minimum` | Collected value according to configuration (`SchemaGeneratorConfigPart.withNumberInclusiveMinimumResolver()`). |
173+
| 23 | `exclusiveMinimum` | Collected value according to configuration (`SchemaGeneratorConfigPart.withNumberExclusiveMinimumResolver()`). |
174+
| 24 | `maximum` | Collected value according to configuration (`SchemaGeneratorConfigPart.withNumberInclusiveMaximumResolver()`). |
175+
| 25 | `exclusiveMaximum` | Collected value according to configuration (`SchemaGeneratorConfigPart.withNumberExclusiveMaximumResolver()`). |
176+
| 26 | `multipleOf` | Collected value according to configuration (`SchemaGeneratorConfigPart.withNumberMultipleOfResolver()`). |
177+
| 27 | `minItems` | Collected value according to configuration (`SchemaGeneratorConfigPart.withArrayMinItemsResolver()`). |
178+
| 28 | `maxItems` | Collected value according to configuration (`SchemaGeneratorConfigPart.withArrayMaxItemsResolver()`). |
179+
| 29 | `uniqueItems` | Collected value according to configuration (`SchemaGeneratorConfigPart.withArrayUniqueItemsResolver()`). |
180+
| 30 | any other | You can directly manipulate the generated `ObjectNode` of a sub-schema – e.g. setting additional attributes – via configuration based on a given type in general (`SchemaGeneratorConfigBuilder.with(TypeAttributeOverride)`) and/or in the context of a particular field/method (`SchemaGeneratorConfigPart.withInstanceAttributeOverride()`). |

pom.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88

99
<groupId>com.github.victools</groupId>
1010
<artifactId>jsonschema-generator</artifactId>
11-
<version>4.3.1-SNAPSHOT</version>
11+
<version>4.4.0-SNAPSHOT</version>
1212
<packaging>jar</packaging>
1313

1414
<licenses>

src/main/java/com/github/victools/jsonschema/generator/SchemaGenerationContext.java

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,13 @@
2424
*/
2525
public interface SchemaGenerationContext {
2626

27+
/**
28+
* Getter for the applicable configuration.
29+
*
30+
* @return configuration defined for this context
31+
*/
32+
SchemaGeneratorConfig getGeneratorConfig();
33+
2734
/**
2835
* Getter for the type resolution/introspection context in use.
2936
*

src/main/java/com/github/victools/jsonschema/generator/SchemaGeneratorConfig.java

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,15 @@ public interface SchemaGeneratorConfig {
9595
CustomDefinition getCustomDefinition(ResolvedType javaType, SchemaGenerationContext context,
9696
CustomDefinitionProviderV2 ignoredDefinitionProvider);
9797

98+
/**
99+
* Look-up a declared type's subtypes in order to list those specifically (in an "{@value SchemaConstants#TAG_ANYOF}").
100+
*
101+
* @param javaType declared type to look-up subtypes for
102+
* @param context generation context (including a reference to the {@code TypeContext} for deriving a {@link ResolvedType} from a {@link Class})
103+
* @return subtypes to list as possible alternatives for the declared type (may be empty)
104+
*/
105+
List<ResolvedType> resolveSubtypes(ResolvedType javaType, SchemaGenerationContext context);
106+
98107
/**
99108
* Getter for the applicable type attribute overrides.
100109
*

src/main/java/com/github/victools/jsonschema/generator/SchemaGeneratorConfigBuilder.java

Lines changed: 5 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -18,11 +18,9 @@
1818

1919
import com.fasterxml.jackson.databind.ObjectMapper;
2020
import com.github.victools.jsonschema.generator.impl.SchemaGeneratorConfigImpl;
21-
import java.util.ArrayList;
2221
import java.util.EnumSet;
2322
import java.util.HashMap;
2423
import java.util.LinkedHashMap;
25-
import java.util.List;
2624
import java.util.Map;
2725
import java.util.Objects;
2826
import java.util.Set;
@@ -37,11 +35,9 @@ public class SchemaGeneratorConfigBuilder {
3735
private final OptionPreset preset;
3836

3937
private final Map<Option, Boolean> options = new HashMap<>();
40-
private final SchemaGeneratorTypeConfigPart<TypeScope> typesInGeneralConfigPart = new SchemaGeneratorTypeConfigPart<>();
38+
private final SchemaGeneratorGeneralConfigPart typesInGeneralConfigPart = new SchemaGeneratorGeneralConfigPart();
4139
private final SchemaGeneratorConfigPart<FieldScope> fieldConfigPart = new SchemaGeneratorConfigPart<>();
4240
private final SchemaGeneratorConfigPart<MethodScope> methodConfigPart = new SchemaGeneratorConfigPart<>();
43-
private final List<CustomDefinitionProviderV2> customDefinitions = new ArrayList<>();
44-
private final List<TypeAttributeOverride> typeAttributeOverrides = new ArrayList<>();
4541

4642
/**
4743
* Constructor of an empty configuration builder. This is equivalent to calling:<br>
@@ -91,17 +87,15 @@ public SchemaGeneratorConfig build() {
9187
enabledOptions,
9288
this.typesInGeneralConfigPart,
9389
this.fieldConfigPart,
94-
this.methodConfigPart,
95-
this.customDefinitions,
96-
this.typeAttributeOverrides);
90+
this.methodConfigPart);
9791
}
9892

9993
/**
10094
* Get the part of this configuration builder dedicated to custom attribute look-ups for types in general, independent of the declaration context.
10195
*
10296
* @return configuration part responsible for handling types regardless of their declaration context
10397
*/
104-
public SchemaGeneratorTypeConfigPart<TypeScope> forTypesInGeneral() {
98+
public SchemaGeneratorGeneralConfigPart forTypesInGeneral() {
10599
return this.typesInGeneralConfigPart;
106100
}
107101

@@ -166,7 +160,7 @@ public SchemaGeneratorConfigBuilder with(Module module) {
166160
* @return this builder instance (for chaining)
167161
*/
168162
public SchemaGeneratorConfigBuilder with(CustomDefinitionProviderV2 definitionProvider) {
169-
this.customDefinitions.add(definitionProvider);
163+
this.typesInGeneralConfigPart.withCustomDefinitionProvider(definitionProvider);
170164
return this;
171165
}
172166

@@ -177,7 +171,7 @@ public SchemaGeneratorConfigBuilder with(CustomDefinitionProviderV2 definitionPr
177171
* @return this builder instance (for chaining)
178172
*/
179173
public SchemaGeneratorConfigBuilder with(TypeAttributeOverride override) {
180-
this.typeAttributeOverrides.add(override);
174+
this.typesInGeneralConfigPart.withTypeAttributeOverride(override);
181175
return this;
182176
}
183177

src/main/java/com/github/victools/jsonschema/generator/SchemaGeneratorConfigPart.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -141,9 +141,13 @@ public Boolean isNullable(M member) {
141141

142142
/**
143143
* Setter for target type resolver, expecting the respective member and the default type as inputs.
144+
* <br>
145+
* For generally replacing one type with one or multiple of its subtypes, you may want to consider adding a {@link SubtypeResolver} via
146+
* {@link SchemaGeneratorConfigBuilder#forTypesInGeneral() forTypesInGeneral()} instead.
144147
*
145148
* @param resolver how to determine the alternative target type
146149
* @return this config part (for chaining)
150+
* @see SchemaGeneratorGeneralConfigPart#withSubtypeResolver(SubtypeResolver)
147151
*/
148152
public SchemaGeneratorConfigPart<M> withTargetTypeOverrideResolver(ConfigFunction<M, ResolvedType> resolver) {
149153
this.targetTypeOverrideResolvers.add(resolver);

0 commit comments

Comments
 (0)