-
Notifications
You must be signed in to change notification settings - Fork 59
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
Can maven plugin generate schemas which externally reference each other? #246
Comments
Thanks for raising this. I'll have to ponder it a bit. The Maven plugin is somewhat limited in scope, as it's not my main focus to be honest. Someone else already found a way to identify whether or not a given type is the main type or not by populating a separate variable inside a TypeAttributeOverride or CustomDefinitionProvider: #59 (comment) I'm unsure when I'd get to try this out myself, unfortunately. Too much to do right now. 😅 |
As mentioned before, if it is acceptable that the target package is defined in the module code, you could use something like the following: public class ExternalRefPluginModule implements Module {
private static final String PACKAGE_FOR_EXTERNAL_REFS = "com.github.victools.example";
private static final String ID_PREFIX = "http://foo.bar/";
private static final String ID_SUFFIX = ".json";
private Class<?> mainType;
@Override
public void applyToConfigBuilder(SchemaGeneratorConfigBuilder builder) {
builder.forTypesInGeneral()
.withCustomDefinitionProvider(this::provideCustomSchemaDefinition)
.withIdResolver(this::resolveMainTypeId)
.withTypeAttributeOverride(this::overrideTypeAttributes);
}
private CustomDefinition provideCustomSchemaDefinition(ResolvedType javaType, SchemaGenerationContext context) {
Class<?> erasedType = javaType.getErasedType();
if (this.mainType == null) {
this.mainType = erasedType;
} else if (this.mainType != erasedType
&& erasedType.getPackage() != null
&& erasedType.getPackage().getName().startsWith(PACKAGE_FOR_EXTERNAL_REFS)) {
ObjectNode externalRef = context.getGeneratorConfig().createObjectNode()
.put(context.getKeyword(SchemaKeyword.TAG_REF), ID_PREFIX + erasedType.getName()+ ID_SUFFIX);
return new CustomDefinition(externalRef, CustomDefinition.DefinitionType.INLINE, CustomDefinition.AttributeInclusion.YES);
}
return null;
}
private String resolveMainTypeId(TypeScope scope) {
if (this.mainType == scope.getType().getErasedType()) {
return ID_PREFIX + this.mainType.getName()+ ID_SUFFIX;
}
return null;
}
private void overrideTypeAttributes(ObjectNode collectedTypeAttributes, TypeScope scope, SchemaGenerationContext context) {
if (this.mainType == scope.getType().getErasedType()) {
this.mainType = null;
}
}
} |
@CarstenWickner apologies for slow response I've been out this week. This approach does seem to do the job, neat trick to cache the base class like that. Thanks so much for taking the time to respond, please let me know if there is anything I can do to help the project in return. |
That's very kind of you to offer. There are occasional feature request and questions coming up as Issues here. Feel free to watch the repository and provide answers or a PR where you feel comfortable. Either way, happy to help – no strings attached. 😉 |
Hi, thanks for the great work on this project.
I struggled to come up with a good title for this question but let me expand by borrowing the answer from #167 which starts with this setup:
This works specifically for the Person class, but what if we also wanted to generate the schema for Address? Currently that would result in a schema which is just a
$ref
pointing to itself.Now say I have a whole package of schemas, what I'm trying to do is use the Maven plugin to generate all the schemas for the package, using external
$refs
to each other as appropriate. So e.g. if we hadThen I would want to see three schemas along these lines:
At first glance I though this would be easy using a Module with an IdResolver and a CustomDefintiionProvider but I quickly ran into trouble:
And in the POM:
This almost works except I still haven't solved the original replacement issue so any instance of the class witll be replaced with it's
$ref
including the root schema for the type.So possibly this question boils down to
How can I disambiguate the root schema defintion for a class from any subsequent references to the class?
If I could do that then I could conditonally return null from the . Given jsonSchema is stateless and fractal I kind of suspect that is not going to be possible so maybe I'm just going the wrong way altogether in which case the question is a more general
Can can I achieve generation of multiple schemas which reference each other?
Thanks for taking the time to read this somewhat long question, any advice appreciated.
The text was updated successfully, but these errors were encountered: