Skip to content

Commit

Permalink
Resolving allOf() at the top of JSON schemas for property inclusion
Browse files Browse the repository at this point in the history
  • Loading branch information
kebernet committed Aug 17, 2024
1 parent 1830503 commit 680fa08
Show file tree
Hide file tree
Showing 3 changed files with 54 additions and 14 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -68,8 +68,10 @@ public void run(File source, File output, String packageName, JsonGenerationConf
switch (mimeType) {
case "application/json" -> {
var extractor = new SchemaObjectExtractor(jsonMapper, createTempDirectory());
extractor.extract(schema.getComponents().getSchemas().getAdditionalProperties());
var resolved = extractor.resolveAllOfInTheBaseTypes(source.toURI(), schema, schema.getComponents().getSchemas().getAdditionalProperties());
extractor.extract(resolved);
extractor.render(jsonGenerationConfig);

}
default -> throw new IllegalArgumentException("Unsupported mime type: " + mimeType);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import com.fasterxml.jackson.databind.ObjectMapper;
import com.sun.codemodel.JCodeModel;
import com.thoughtworks.asyncapi.util.ReferenceResolver;
import org.jsonschema2pojo.GenerationConfig;
import org.jsonschema2pojo.Jackson2Annotator;
import org.jsonschema2pojo.SchemaGenerator;
Expand All @@ -11,13 +12,16 @@

import java.io.File;
import java.io.IOException;
import java.net.URI;
import java.nio.file.Files;
import java.util.Arrays;
import java.util.Map;
import java.util.Objects;
import java.util.List;

public class SchemaObjectExtractor {

public static final String ALL_OF = "allOf";
private final ObjectMapper mapper;
private final File tmpDir;
public SchemaObjectExtractor(ObjectMapper mapper, File tmpDir) {
Expand All @@ -26,13 +30,37 @@ public SchemaObjectExtractor(ObjectMapper mapper, File tmpDir) {
//noinspection ResultOfMethodCallIgnored
this.tmpDir.mkdirs();
}
@SuppressWarnings("unchecked")
public Map<String, Object> resolveAllOfInTheBaseTypes(URI baseUri, Object definition, Map<String, Object> target){
target.values()
.forEach(e->{
if(e instanceof Map entryMap){
if(entryMap.containsKey(ALL_OF)){
var allOf = (List<?>) entryMap.get(ALL_OF);
allOf.stream().map(o-> {
Map<String, Object> r = ReferenceResolver.resolveReference(baseUri, definition, (Map<String, Object>) o);

return r;
}
)
.forEach(m->{
if(entryMap.containsKey("properties")&& m.containsKey("properties")){
var properties = (Map<String, Object>) entryMap.get("properties");
properties.putAll((Map<? extends String, ?>) m.get("properties"));
}
});
}
}
});
return target;
}

public void extract(Map<String, Object> parsedSchemaObjects) {
parsedSchemaObjects.forEach((key, value) -> {
try {
File file = new File(tmpDir, key);
File file = new File(tmpDir, key+".json");
var string = mapper.writeValueAsString(value);
string = string.replace("\"#/components/schemas/", "\"./");
string = string.replaceAll("\"#/components/schemas/(\\w*)\"", "\"./$1.json\"") ;
Files.write(file.toPath(), string.getBytes());
} catch (Exception e) {
throw new SchemaExtractorException("Failed to write schema object to file", e);
Expand All @@ -46,15 +74,15 @@ public void render(GenerationConfig config) {
Arrays.stream(Objects.requireNonNull(source))
.filter(f-> !f.isDirectory())
.forEach(file -> {
JCodeModel codeModel = new JCodeModel();
SchemaMapper schemaMapper = new SchemaMapper(new RuleFactory(config, new Jackson2Annotator(config), new SchemaStore()), new SchemaGenerator());
try {
schemaMapper.generate(codeModel, file.getName(), config.getTargetPackage()+".model", file.toURI().toURL());
codeModel.build(config.getTargetDirectory());
} catch (IOException e) {
throw new SchemaExtractorException("Failed to process file: " + file.getName(), e);
}
});
JCodeModel codeModel = new JCodeModel();
SchemaMapper schemaMapper = new SchemaMapper(new RuleFactory(config, new Jackson2Annotator(config), new SchemaStore()), new SchemaGenerator());
try {
schemaMapper.generate(codeModel, file.getName(), config.getTargetPackage()+".model", file.toURI().toURL());
codeModel.build(config.getTargetDirectory());
} catch (IOException e) {
throw new SchemaExtractorException("Failed to process file: " + file.getName(), e);
}
});

} catch (Exception e) {
throw new SchemaExtractorException("Failed to render schema object", e);
Expand All @@ -67,4 +95,4 @@ public SchemaExtractorException(String message, Throwable cause) {
super(message, cause);
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,10 @@ void testExtractAndRender() throws IOException {
var jsonMapper = new ObjectMapper();
var schema = yamlMapper.readValue(SchemaObjectExtractorTest.class.getResource("/schema.yaml"), AsyncAPI.class);
var instance = new SchemaObjectExtractor(jsonMapper, output);
instance.extract(schema.getComponents().getSchemas().getAdditionalProperties());

var types= instance.resolveAllOfInTheBaseTypes(null, schema, schema.getComponents().getSchemas().getAdditionalProperties());

instance.extract(types);
var config = new DefaultGenerationConfig() {
@Override
public String getTargetPackage() {
Expand All @@ -36,4 +39,11 @@ public File getTargetDirectory() {

}

@Test
void testRegex(){
var value = "{\"$ref\":\"#/components/schemas/OrderDetails\"}";
var result = value.replaceAll("\"#/components/schemas/(.*)\"", "\"$1.json\"");
System.out.println(result);
}

}

0 comments on commit 680fa08

Please sign in to comment.