Skip to content

Commit

Permalink
Document usage of external references and avoid deprecated jackson API (
Browse files Browse the repository at this point in the history
#168)

* chore(docs): add faq entry

* chore: mention jackson version update in changelog

* chore: replace deprecated jackson API usage as per version 2.12.0
  • Loading branch information
CarstenWickner committed Feb 20, 2021
1 parent 1d03856 commit 040515b
Show file tree
Hide file tree
Showing 5 changed files with 41 additions and 10 deletions.
7 changes: 7 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,17 @@ 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]
### `jsonschema-generator`
#### Changed
- Increase of Jackson dependency version to 2.12.1

### `jsonschema-module-jackson`
#### Added
- New `JacksonOption.RESPECT_JSONPROPERTY_REQUIRED` to set a field as "required" based on `@JsonProperty` annotations

#### Changed
- Replace deprecated Jackson API usage, resulting in MINIMUM Jackson version 2.12.0

## [4.17.0] - 2020-12-24
### `jsonschema-module-jakarta-validation`
#### Added
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,13 +16,11 @@

package com.github.victools.jsonschema.generator.naming;

import com.github.victools.jsonschema.generator.naming.SchemaDefinitionNamingStrategy;
import com.fasterxml.classmate.ResolvedType;
import com.fasterxml.jackson.databind.PropertyNamingStrategy;
import com.fasterxml.jackson.databind.PropertyNamingStrategy.PropertyNamingStrategyBase;
import com.fasterxml.jackson.databind.PropertyNamingStrategies;
import com.fasterxml.jackson.databind.PropertyNamingStrategies.NamingBase;
import com.github.victools.jsonschema.generator.SchemaGenerationContext;
import com.github.victools.jsonschema.generator.TypeContext;
import com.github.victools.jsonschema.generator.naming.DefaultSchemaDefinitionNamingStrategy;
import com.github.victools.jsonschema.generator.impl.DefinitionKey;
import com.github.victools.jsonschema.generator.impl.SchemaCleanUpUtils;
import com.github.victools.jsonschema.generator.impl.TypeContextFactory;
Expand Down Expand Up @@ -61,7 +59,7 @@ public void setUp() {
}

public Object[] parametersForTestExampleStrategy() {
PropertyNamingStrategyBase jacksonSnakeCase = new PropertyNamingStrategy.SnakeCaseStrategy();
NamingBase jacksonSnakeCase = (NamingBase) PropertyNamingStrategies.SNAKE_CASE;
SchemaDefinitionNamingStrategy snakeCase = new DefaultSchemaDefinitionNamingStrategy() {
@Override
public String getDefinitionNameForKey(DefinitionKey key, SchemaGenerationContext generationContext) {
Expand All @@ -70,7 +68,7 @@ public String getDefinitionNameForKey(DefinitionKey key, SchemaGenerationContext
.replaceAll(", _", ",");
}
};
PropertyNamingStrategyBase jacksonDotCase = new PropertyNamingStrategy.LowerDotCaseStrategy();
NamingBase jacksonDotCase = (NamingBase) PropertyNamingStrategies.LOWER_DOT_CASE;
SchemaDefinitionNamingStrategy dotCase = new DefaultSchemaDefinitionNamingStrategy() {
@Override
public String getDefinitionNameForKey(DefinitionKey key, SchemaGenerationContext generationContext) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -243,7 +243,7 @@ protected boolean shouldIgnoreField(FieldScope field) {
BeanDescription beanDescription = this.getBeanDescriptionForClass(field.getDeclaringType());
// some kinds of field ignorals are only available via an annotation introspector
Set<String> ignoredProperties = this.objectMapper.getSerializationConfig().getAnnotationIntrospector()
.findPropertyIgnorals(beanDescription.getClassInfo()).getIgnored();
.findPropertyIgnoralByName(null, beanDescription.getClassInfo()).getIgnored();
String fieldName = field.getName();
if (ignoredProperties.contains(fieldName)) {
return true;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
import com.fasterxml.jackson.annotation.JsonClassDescription;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.annotation.JsonPropertyDescription;
import com.fasterxml.jackson.databind.PropertyNamingStrategy;
import com.fasterxml.jackson.databind.PropertyNamingStrategies;
import com.fasterxml.jackson.databind.annotation.JsonNaming;
import com.github.victools.jsonschema.generator.ConfigFunction;
import com.github.victools.jsonschema.generator.FieldScope;
Expand Down Expand Up @@ -265,7 +265,7 @@ public void testDescriptionForTypeResolver(String fieldName, String expectedDesc
Assert.assertEquals(expectedDescription, description);
}

@JsonNaming(PropertyNamingStrategy.KebabCaseStrategy.class)
@JsonNaming(PropertyNamingStrategies.KebabCaseStrategy.class)
private static class TestClassForPropertyNameOverride {

Integer unannotatedField;
Expand Down
28 changes: 27 additions & 1 deletion slate-docs/source/includes/_faq.md
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ Enums are a special construct for which there are multiple options:
1. `Option.FLATTENED_ENUMS` (which is part of the `OptionPreset.PLAIN_JSON`)
* This defines an enum as `{ "type": "string", "enum": ["VALUE1", "VALUE2"] }` with the `name()` method being called on each possible enum value.
* If there is only one enum value, it will be set as `"const"` instead.
* Such an enum representation will always be in-lined and not moved into the `"definitions"`.
* Such an enum representation will always be in-lined and not moved into the `"definitions"`/`"$defs"`.
2. `Option.SIMPLIFIED_ENUMS`(which is part of the `OptionPreset.JAVA_OBJECT` and `OptionPreset.FULL_DOCUMENTATION`)
* This treats enums like any other class but hiding some methods and listing the possible enum values as `"enum"`/`"const"` on the `name()` method.
3. Using neither of the two `Option`s above will let them be handled like any other class (unless there are further configurations taking care of enums).
Expand Down Expand Up @@ -134,3 +134,29 @@ The exact details depend on how the `default` value can be determined.

1. If the `default` value is explicitly stated via some kind of annotation, it might be as simple as "Example 1" on the right.
2. If the `default` value is only set in code, and you cannot or don't want to maintain that piece of information twice this can get a bit more advanced. Here assuming your own classes all have a default no-args constructor and conventional getters as in "Example 2" on the right.

## How to reference a separate schema/file?

```java
configBuilder.forTypesInGeneral()
.withCustomDefinitionProvider((javaType, context) -> {
if (javaType.getErasedType() != MyExternalType.class) {
// other types should be treated normally
return null;
}
// define your custom reference value
String refValue = "./" + javaType.getErasedType().getSimpleName();
// produce the sub-schema that only contains your custom reference
ObjectNode customNode = context.getGeneratorConfig().createObjectNode()
.put(context.getKeyword(SchemaKeyword.TAG_REF), refValue);
return new CustomDefinition(customNode,
// avoid the creation of a reference to your custom reference schema
CustomDefinition.DefinitionType.INLINE,
// still allow for collected schema attributes to be added
CustomDefinition.AttributeInclusion.YES);
});
```

By using `withCustomDefinitionProvider()` – one of the [advanced configurations](#generator-advanced-configurations) – you can fully control the contents of a type's sub-schema.
Simply create a node that only contains your custom/external reference instead of the actual schema.
It is recommended to mark the custom definition as "to be inlined", in order to avoid an extra entry in the `"definitions"`/`"$defs"`.

0 comments on commit 040515b

Please sign in to comment.