Skip to content

Commit

Permalink
feat: enable test package access from Maven plugin + documentation (#389
Browse files Browse the repository at this point in the history
)

* chore: add documentation for Maven plugin YAML support
* chore(test): include ObjectMapper change in module used by Maven plugin
* feat: support custom module loaded from test classpath
* chore(docs): describe loading Maven plugin module from test classes
  • Loading branch information
CarstenWickner authored Oct 25, 2023
1 parent 42cea4d commit 7341a5d
Show file tree
Hide file tree
Showing 9 changed files with 89 additions and 8 deletions.
11 changes: 11 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,13 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

## [Unreleased]
### `jsonschema-generator`
#### Added
- offer `SchemaGeneratorConfigBuilder.withObjectMapper()`; mainly for use in custom modules in combination with the Maven plugin, where the constructor parameter cannot be used instead

#### Changed
- consider JavaBeans API specification in getter naming convention for field names with the second character being uppercase (e.g., a field `xIndex` has the getter `getxIndex()` according to the specification)
- allow for field names starting with `is` to have getter of the same name (e.g., a field `isBool` may have the getter `isBool()`)
- the default `ObjectMapper` instance now includes the enabled `SerializationFeature.INDENT_OUTPUT`

### `jsonschema-module-jackson`
#### Added
Expand All @@ -23,6 +27,13 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
#### Fixed
- avoid rounding error when taking over the value from `@Schema(multipleOf)`

### `jsonschema-naven-plugin`
### Added
- support custom configuration `Module` being loaded from test classpath elements

### Changed
- a generated schema is now serialized through the configuration's `ObjectMapper` instance (e.g., granting control over pretty printing or even generating YAML instead of JSON files)

## [4.31.1] - 2023-04-28
### `jsonschema-generator`
#### Fixed
Expand Down
7 changes: 7 additions & 0 deletions jsonschema-generator-parent/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,13 @@
<role>Provided PR #314 (adding explicit Java module descriptors)</role>
</roles>
</contributor>
<contributor>
<name>takanuva15</name>
<url>https://github.com/takanuva15</url>
<roles>
<role>Provided PR #388 (allowing configuration of Maven plugin serialization behavior)</role>
</roles>
</contributor>
</contributors>

<properties>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,12 @@ public enum ClasspathType {
/**
* Classes from the project, compile time and runtime dependencies.
*/
WITH_ALL_DEPENDENCIES;
WITH_ALL_DEPENDENCIES,
/**
* Classes from the project (including tests), compile time, runtime and test dependencies.
* Mainly intended for internal use when looking up custom modules.
*/
WITH_ALL_DEPENDENCIES_AND_TESTS;

public Collection<String> getClasspathElements(MavenProject project) {
Collection<String> classpathElements;
Expand All @@ -64,6 +69,13 @@ public Collection<String> getClasspathElements(MavenProject project) {
classpathElements.addAll(project.getRuntimeClasspathElements());
classpathElements.addAll(project.getCompileClasspathElements());
break;
case WITH_ALL_DEPENDENCIES_AND_TESTS:
// to remove duplicates
classpathElements = new HashSet<>();
classpathElements.addAll(project.getRuntimeClasspathElements());
classpathElements.addAll(project.getCompileClasspathElements());
classpathElements.addAll(project.getTestClasspathElements());
break;
default:
throw new IllegalArgumentException("ClasspathType " + this + " not supported");
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -494,7 +494,7 @@ private URLClassLoader getClassLoader() {
if (this.classLoader == null) {
// fix the classpath such that the classloader can get classes from any possible dependency
// this does not affect filtering, as the classgraph library uses its own classloader and allows for caching
List<URL> urls = ClasspathType.WITH_ALL_DEPENDENCIES.getUrls(this.project);
List<URL> urls = ClasspathType.WITH_ALL_DEPENDENCIES_AND_TESTS.getUrls(this.project);
this.classLoader = new URLClassLoader(urls.toArray(new URL[0]),
Thread.currentThread().getContextClassLoader());
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,4 +25,8 @@ public class TestClass {
public TestClass(int anInt) {
this.anInt = anInt;
}

public int getAnInt() {
return this.anInt;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,12 +16,15 @@

package com.github.victools.jsonschema.plugin.maven;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;
import com.github.victools.jsonschema.generator.Module;
import com.github.victools.jsonschema.generator.SchemaGeneratorConfigBuilder;

public class TestModule implements Module {

@Override
public void applyToConfigBuilder(SchemaGeneratorConfigBuilder builder) {
builder.withObjectMapper(new ObjectMapper().disable(SerializationFeature.INDENT_OUTPUT));
}
}
Original file line number Diff line number Diff line change
@@ -1,5 +1 @@
{
"type" : "object",
"description" : "Jackson annotation class",
"additionalProperties" : false
}
{"type":"object","properties":{"anInt":{"type":"integer"},"getAnInt()":{"type":"integer"}},"description":"Jackson annotation class","additionalProperties":false}
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
{
"$schema" : "http://json-schema.org/draft-07/schema#",
"type" : "object",
"properties" : {
"anInt" : {
"type" : "integer"
}
},
"description" : "Jackson annotation class"
}
45 changes: 44 additions & 1 deletion slate-docs/source/includes/_maven-plugin.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,8 @@ The considered `<classpath>` may be further specified as one of four values:
- `WITH_COMPILE_DEPENDENCIES` : `PROJECT_ONLY` and compile dependencies
- `WITH_RUNTIME_DEPENDENCIES` : `PROJECT_ONLY` and runtime dependencies (default, if unspecified)
- `WITH_ALL_DEPENDENCIES` : all of the above

- `WITH_ALL_DEPENDENCIES_AND_TESTS` : all of the above, with the addition of the current project's test files
Note that this requires a different `<phase>` (e.g., `test-compile`) being specified on the `<execution>`.
----

By default, the plugin aborts if the glob pattern does not match any class. If this is not desired, the `<failIfNoClassesMatch>` property can be set to `false`.
Expand Down Expand Up @@ -122,3 +123,45 @@ Through the `<modules>` tag you can include the standard modules – potentially
You can also group any kind of configurations into a Module of your own and include it via its full class name.
Make sure your custom module is on the classpath (considering the project itself as well as all compile and runtime dependencies) and has a default constructor.
It is not possible to configure options for custom modules.

### Altering the format of generated schema files

```java
public class MavenPluginYamlModule implements Module {
@Override
public void applyToConfigBuilder(SchemaGeneratorConfigBuilder builder) {
// Maven plugin should produce YAML files instead of JSON
ObjectMapper mapper = new ObjectMapper(new YAMLFactory());
// set additional serialization options
mapper.getSerializationConfig()
.with(JsonWriteFeature.WRITE_NUMBERS_AS_STRINGS);
mapper.setNodeFactory(JsonNodeFactory.withExactBigDecimals(true));
builder.withObjectMapper(mapper);
}
}
```

One possibility within such a custom Module (as mentioned above) is to configure the format of the generated schema files.
The file contents are being produced by the schema generator's associated `ObjectMapper`.
That default `ObjectMapper` can be replaced, e.g., to opt-out of the default pretty-printing or changing the file format to YAML.
The given example requires the inclusion of the extra `com.fasterxml.jackson.dataformat:jackson-dataformat-yaml` dependency.

### Loading custom Module from test classes

```xml
<executions>
<execution>
<phase>test-compile</phase>
<goals>
<goal>generate</goal>
</goals>
</execution>
</executions>
```

When you're using a custom Module (as mentioned above) for additional configuration options, but don't want to include it among your application code,
you can either package it as separate artifact and include that as dependency of the plugin (not going into further detail here)
or the custom Module class can be included in your test packages.
When you do the latter, the Maven plugin will by default not be able to load that class, since it won't be compiled yet in the Maven phase during which the schema generation is being executed.
The Maven `compile` phase is when the schema generation gets triggered by default.
If you want the test classes (including the custom Module) to be available, a later phase (most likely: `test-compile`) needs to be specified.

0 comments on commit 7341a5d

Please sign in to comment.