use of won.shacl2java.Shacl2JavaConfig in project webofneeds by researchstudio-sat.
the class MainTypesPostprocessor method configureTypeWithNodeShapes.
private void configureTypeWithNodeShapes(TypeSpec.Builder typeBuilder, String name, Set<Shape> relevantShapes, Shapes shapes, Shacl2JavaConfig config) {
// first,prepare a methodbuilder for the toRdf method
// we will add statements to it while processing the relevant shapes
MethodSpec.Builder toRdfBuilderDelegating = MethodSpec.methodBuilder("toRdf").addModifiers(PUBLIC).addAnnotation(Override.class).addParameter(ParameterizedTypeName.get(Consumer.class, Triple.class), "tripleConsumer").addStatement("toRdf(tripleConsumer, true)");
typeBuilder.addMethod(toRdfBuilderDelegating.build());
MethodSpec.Builder toRdfBuilder = MethodSpec.methodBuilder("toRdf").addModifiers(PUBLIC).addParameter(ParameterizedTypeName.get(Consumer.class, Triple.class), "tripleConsumer").addParameter(ClassName.BOOLEAN, "includeIndividuals").addStatement("$T obj = null", Node.class).addStatement("$T entityNode = getNodeCreateIfNecessary()", Node.class).beginControlFlow("if (getGraph() == null)").addStatement("additionalTriplesToRdf(tripleConsumer)");
generateRequiredRdfTypeStatements(toRdfBuilder, relevantShapes);
// we want each type to have a .builder() method returning a builder for the
// type
TypeName typeName = ClassName.get(config.getPackageName(), name);
ClassName builderTypeName = ClassName.get(config.getPackageName(), name + ".Builder");
TypeSpec.Builder builderBuilder = generateBuilderBuilder(typeBuilder, typeName, builderTypeName);
// for the clone() method, we prepare another builder
// we will add statements to it while processing the relevant shapes
MethodSpec.Builder cloneBuilder = MethodSpec.methodBuilder("clone").addModifiers(PUBLIC).returns(ClassName.OBJECT).addAnnotation(Override.class).addStatement("$T clone = ($T) super.clone()", typeName, typeName);
for (Shape relevantShape : relevantShapes) {
Set<PropertyShape> propertyShapes = new HashSet();
propertyShapes.addAll(relevantShape.getPropertyShapes());
propertyShapes.addAll(ShapeUtils.getShPropertyShapes(relevantShape));
// remember all fields we generate for the same path for this type, so we can
// add a common interface
// and a getter for the union of all these fields:
Map<Path, Set<FieldSpec>> fieldsPerPath = new HashMap<>();
Map<Path, Set<PropertySpec>> propSpecsPerPath = propertyShapes.stream().collect(Collectors.toMap(s -> s.getPath(), s -> (Set<PropertySpec>) ShapeUtils.getPropertySpecs(s), (left, right) -> {
Set union = new HashSet(left);
union.addAll(right);
return union;
}));
for (Path path : propSpecsPerPath.keySet()) {
Optional<String> propertyName = NameUtils.propertyNameForPath(path);
if (!propertyName.isPresent()) {
continue;
}
logger.debug("generating property '{}' of {}", propertyName.get(), NameUtils.nameForShape(relevantShape));
Set<PropertySpec> propertySpecs = propSpecsPerPath.get(path);
if (logger.isDebugEnabled()) {
for (PropertySpec propertySpec : propertySpecs) {
logger.debug("\tfound property spec: {}", propertySpec);
}
}
boolean addTypeSuffix = propertySpecs.size() > 1;
for (PropertySpec propertySpec : propertySpecs) {
addFieldWithPropertySpec(shapes, propertyName.get(), path, propertySpec, typeBuilder, builderBuilder, builderTypeName, toRdfBuilder, cloneBuilder, fieldsPerPath, config, addTypeSuffix);
}
}
// add union getter
fieldsPerPath.entrySet().stream().forEach(pathToFields -> {
Set<FieldSpec> fieldSpecs = pathToFields.getValue();
if (fieldSpecs.size() < 2) {
return;
}
Path path = pathToFields.getKey();
Optional<String> fieldName = propertyNameForPath(path);
if (fieldName.isPresent()) {
addUnionGetter(fieldName.get(), path, typeBuilder, fieldSpecs, config);
}
});
}
//
relevantShapes.stream().flatMap(s -> checkShapeForIndividuals(s).stream()).collect(Collectors.toMap(s -> new Object[] { s.getPredicate(), s.getClassName() }, s -> s, (left, right) -> IndividualPropertySpec.merge(left, right))).values().stream().forEach(spec -> addFieldWithIndividualPropertySpec(spec, typeBuilder, toRdfBuilder, cloneBuilder, config));
// finish toRdf method
toRdfBuilder.nextControlFlow("else").addStatement("super.toRdf(tripleConsumer)").endControlFlow();
// finish clone method
cloneBuilder.addStatement("return clone");
typeBuilder.addType(builderBuilder.build());
typeBuilder.addMethod(toRdfBuilder.build());
typeBuilder.addMethod(cloneBuilder.build());
}
use of won.shacl2java.Shacl2JavaConfig in project webofneeds by researchstudio-sat.
the class Shacl2JavaTestSourcesGenerator method generateInDir.
private static void generateInDir(File inputDirFile, File outputDirFile) throws IOException {
outputDirFile.mkdirs();
File[] testfolders = inputDirFile.listFiles((FileFilter) DirectoryFileFilter.INSTANCE);
for (int i = 0; i < Objects.requireNonNull(testfolders).length; i++) {
logger.debug("Processing test folder {}", testfolders[i]);
String packageName = testfolders[i].getName();
Shapes shapes = loadShapes(new File(testfolders[i], "shapes.ttl").toURI().toURL());
Shacl2JavaConfig config = Shacl2JavaConfig.builder().packageName(packageName).classNameRegexReplace("(Property)?Shape$", "").abbreviateTypeIndicators(false).alwaysAddTypeIndicator(false).addVisitorClass(URI.create("https://w3id.org/won/auth#TreeExpressionShape")).outputDir(outputDirFile.getAbsolutePath()).build();
SourceGenerator gen = new SourceGenerator();
Set<TypeSpec> typeSpecs = gen.generateTypes(shapes, config);
SourceGenerator.writeClasses(typeSpecs, config);
logger.debug("wrote classes to {} ", outputDirFile);
}
}
Aggregations