Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Consider subtypes when encountering supertype #35

Merged
merged 5 commits into from
Mar 2, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 10 additions & 5 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,18 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## [Unreleased]
### Added
- Enable declaration of subtypes through `withSubtypeResolver(SubtypeResolver)` on `forTypesInGeneral()` (#24)

### Changed
- Move custom definitions and type attribute overrides into `forTypesInGeneral()` (while preserving delegate setters on config builder)

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

### Fixed
- not declare any "type" for `Object.class` by default
- Not declare any "type" for `Object.class` by default

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

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

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

## [4.0.1] - 2020-01-29
### Fixed
- avoid white-spaces in definition keys
- Avoid white-spaces in definition keys

## [4.0.0] - 2020-01-03
### Added
Expand Down
45 changes: 23 additions & 22 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -151,29 +151,30 @@ configBuilder.forTypesInGeneral()
| 1 | `$schema` | Fixed to "http://json-schema.org/draft-07/schema#" – can be toggled on/off via `Option.SCHEMA_VERSION_INDICATOR`. |
| 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. |
| 3 | `$ref` | Used with relative references to sub-schemas in `definitions`. |
| 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()`). |
| 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()`). |
| 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()`). |
| 6 | `items` | Indicating the type of `array`/`Collection` elements. |
| 7 | `required` | Listing the names of fields/methods that are deemed mandatory according to configuration (`SchemaGeneratorConfigPart.withRequiredCheck()`). |
| 8 | `allOf` | Used to combine general attributes derived from the type itself with attributes collected in the respective context of the associated field/method. |
| 9 | `oneOf` | Used to indicate when a particular field/method can be of `type` `null`. |
| 10 | `title` | Collected value according to configuration (`SchemaGeneratorConfigPart.withTitleResolver()`). |
| 11 | `description` | Collected value according to configuration (`SchemaGeneratorConfigPart.withDescriptionResolver()`). |
| 12 | `const` | Collected value according to configuration (`SchemaGeneratorConfigPart.withEnumResolver()`) if only a single value was found. |
| 13 | `enum` | Collected value according to configuration (`SchemaGeneratorConfigPart.withEnumResolver()`) if multiple values were found. |
| 14 | `default` | Collected value according to configuration (`SchemaGeneratorConfigPart.withDefaultResolver()`). |
| 15 | `additionalProperties` | Collected value according to configuration (`SchemaGeneratorConfigPart.withAdditionalPropertiesResolver()`). |
| 16 | `patternProperties` | Collected value(s) according to configuration (`SchemaGeneratorConfigPart.withPatternPropertiesResolver()`). |
| 17 | `minLength` | Collected value according to configuration (`SchemaGeneratorConfigPart.withStringMinLengthResolver()`). |
| 18 | `maxLength` | Collected value according to configuration (`SchemaGeneratorConfigPart.withStringMaxLengthResolver()`). |
| 19 | `format` | Collected value according to configuration (`SchemaGeneratorConfigPart.withStringFormatResolver()`). |
| 20 | `pattern` | Collected value according to configuration (`SchemaGeneratorConfigPart.withStringPatternResolver()`). |
| 21 | `minimum` | Collected value according to configuration (`SchemaGeneratorConfigPart.withNumberInclusiveMinimumResolver()`). |
| 22 | `exclusiveMinimum` | Collected value according to configuration (`SchemaGeneratorConfigPart.withNumberExclusiveMinimumResolver()`). |
| 23 | `maximum` | Collected value according to configuration (`SchemaGeneratorConfigPart.withNumberInclusiveMaximumResolver()`). |
| 24 | `exclusiveMaximum` | Collected value according to configuration (`SchemaGeneratorConfigPart.withNumberExclusiveMaximumResolver()`). |
| 25 | `multipleOf` | Collected value according to configuration (`SchemaGeneratorConfigPart.withNumberMultipleOfResolver()`). |
| 26 | `minItems` | Collected value according to configuration (`SchemaGeneratorConfigPart.withArrayMinItemsResolver()`). |
| 27 | `maxItems` | Collected value according to configuration (`SchemaGeneratorConfigPart.withArrayMaxItemsResolver()`). |
| 28 | `uniqueItems` | Collected value according to configuration (`SchemaGeneratorConfigPart.withArrayUniqueItemsResolver()`). |
| 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()`). |
| 9 | `anyOf` | Used to list alternatives according to configuration (`SchemaGeneratorGeneralConfigPart.withSubtypeResolver()`). |
| 10 | `oneOf` | Used to indicate when a particular field/method can be of `type` `null`. |
| 11 | `title` | Collected value according to configuration (`SchemaGeneratorConfigPart.withTitleResolver()`). |
| 12 | `description` | Collected value according to configuration (`SchemaGeneratorConfigPart.withDescriptionResolver()`). |
| 13 | `const` | Collected value according to configuration (`SchemaGeneratorConfigPart.withEnumResolver()`) if only a single value was found. |
| 14 | `enum` | Collected value according to configuration (`SchemaGeneratorConfigPart.withEnumResolver()`) if multiple values were found. |
| 15 | `default` | Collected value according to configuration (`SchemaGeneratorConfigPart.withDefaultResolver()`). |
| 16 | `additionalProperties` | Collected value according to configuration (`SchemaGeneratorConfigPart.withAdditionalPropertiesResolver()`). |
| 17 | `patternProperties` | Collected value(s) according to configuration (`SchemaGeneratorConfigPart.withPatternPropertiesResolver()`). |
| 18 | `minLength` | Collected value according to configuration (`SchemaGeneratorConfigPart.withStringMinLengthResolver()`). |
| 19 | `maxLength` | Collected value according to configuration (`SchemaGeneratorConfigPart.withStringMaxLengthResolver()`). |
| 20 | `format` | Collected value according to configuration (`SchemaGeneratorConfigPart.withStringFormatResolver()`). |
| 21 | `pattern` | Collected value according to configuration (`SchemaGeneratorConfigPart.withStringPatternResolver()`). |
| 22 | `minimum` | Collected value according to configuration (`SchemaGeneratorConfigPart.withNumberInclusiveMinimumResolver()`). |
| 23 | `exclusiveMinimum` | Collected value according to configuration (`SchemaGeneratorConfigPart.withNumberExclusiveMinimumResolver()`). |
| 24 | `maximum` | Collected value according to configuration (`SchemaGeneratorConfigPart.withNumberInclusiveMaximumResolver()`). |
| 25 | `exclusiveMaximum` | Collected value according to configuration (`SchemaGeneratorConfigPart.withNumberExclusiveMaximumResolver()`). |
| 26 | `multipleOf` | Collected value according to configuration (`SchemaGeneratorConfigPart.withNumberMultipleOfResolver()`). |
| 27 | `minItems` | Collected value according to configuration (`SchemaGeneratorConfigPart.withArrayMinItemsResolver()`). |
| 28 | `maxItems` | Collected value according to configuration (`SchemaGeneratorConfigPart.withArrayMaxItemsResolver()`). |
| 29 | `uniqueItems` | Collected value according to configuration (`SchemaGeneratorConfigPart.withArrayUniqueItemsResolver()`). |
| 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()`). |
2 changes: 1 addition & 1 deletion pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@

<groupId>com.github.victools</groupId>
<artifactId>jsonschema-generator</artifactId>
<version>4.3.1-SNAPSHOT</version>
<version>4.4.0-SNAPSHOT</version>
<packaging>jar</packaging>

<licenses>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,13 @@
*/
public interface SchemaGenerationContext {

/**
* Getter for the applicable configuration.
*
* @return configuration defined for this context
*/
SchemaGeneratorConfig getGeneratorConfig();

/**
* Getter for the type resolution/introspection context in use.
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,15 @@ public interface SchemaGeneratorConfig {
CustomDefinition getCustomDefinition(ResolvedType javaType, SchemaGenerationContext context,
CustomDefinitionProviderV2 ignoredDefinitionProvider);

/**
* Look-up a declared type's subtypes in order to list those specifically (in an "{@value SchemaConstants#TAG_ANYOF}").
*
* @param javaType declared type to look-up subtypes for
* @param context generation context (including a reference to the {@code TypeContext} for deriving a {@link ResolvedType} from a {@link Class})
* @return subtypes to list as possible alternatives for the declared type (may be empty)
*/
List<ResolvedType> resolveSubtypes(ResolvedType javaType, SchemaGenerationContext context);

/**
* Getter for the applicable type attribute overrides.
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,9 @@

import com.fasterxml.jackson.databind.ObjectMapper;
import com.github.victools.jsonschema.generator.impl.SchemaGeneratorConfigImpl;
import java.util.ArrayList;
import java.util.EnumSet;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
Expand All @@ -37,11 +35,9 @@ public class SchemaGeneratorConfigBuilder {
private final OptionPreset preset;

private final Map<Option, Boolean> options = new HashMap<>();
private final SchemaGeneratorTypeConfigPart<TypeScope> typesInGeneralConfigPart = new SchemaGeneratorTypeConfigPart<>();
private final SchemaGeneratorGeneralConfigPart typesInGeneralConfigPart = new SchemaGeneratorGeneralConfigPart();
private final SchemaGeneratorConfigPart<FieldScope> fieldConfigPart = new SchemaGeneratorConfigPart<>();
private final SchemaGeneratorConfigPart<MethodScope> methodConfigPart = new SchemaGeneratorConfigPart<>();
private final List<CustomDefinitionProviderV2> customDefinitions = new ArrayList<>();
private final List<TypeAttributeOverride> typeAttributeOverrides = new ArrayList<>();

/**
* Constructor of an empty configuration builder. This is equivalent to calling:<br>
Expand Down Expand Up @@ -91,17 +87,15 @@ public SchemaGeneratorConfig build() {
enabledOptions,
this.typesInGeneralConfigPart,
this.fieldConfigPart,
this.methodConfigPart,
this.customDefinitions,
this.typeAttributeOverrides);
this.methodConfigPart);
}

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

Expand Down Expand Up @@ -166,7 +160,7 @@ public SchemaGeneratorConfigBuilder with(Module module) {
* @return this builder instance (for chaining)
*/
public SchemaGeneratorConfigBuilder with(CustomDefinitionProviderV2 definitionProvider) {
this.customDefinitions.add(definitionProvider);
this.typesInGeneralConfigPart.withCustomDefinitionProvider(definitionProvider);
return this;
}

Expand All @@ -177,7 +171,7 @@ public SchemaGeneratorConfigBuilder with(CustomDefinitionProviderV2 definitionPr
* @return this builder instance (for chaining)
*/
public SchemaGeneratorConfigBuilder with(TypeAttributeOverride override) {
this.typeAttributeOverrides.add(override);
this.typesInGeneralConfigPart.withTypeAttributeOverride(override);
return this;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -141,9 +141,13 @@ public Boolean isNullable(M member) {

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