Search in sources :

Example 1 with Shacl2JavaConfig

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());
}
Also used : PropertyPath(won.shacl2java.annotation.PropertyPath) PathVisitorBase(org.apache.jena.sparql.path.PathVisitorBase) RDF(org.apache.jena.vocabulary.RDF) java.util(java.util) com.squareup.javapoet(com.squareup.javapoet) BuildableClassNames(won.shacl2java.sourcegen.typegen.mapping.BuildableClassNames) Modifier(javax.lang.model.element.Modifier) LoggerFactory(org.slf4j.LoggerFactory) org.apache.jena.graph(org.apache.jena.graph) ShapeTargetClasses(won.shacl2java.sourcegen.typegen.mapping.ShapeTargetClasses) PropertyShape(org.apache.jena.shacl.parser.PropertyShape) P_Link(org.apache.jena.sparql.path.P_Link) Path(org.apache.jena.sparql.path.Path) ShapeUtils(won.shacl2java.util.ShapeUtils) ToRdfUtils(won.shacl2java.runtime.ToRdfUtils) TypesPostprocessor(won.shacl2java.sourcegen.typegen.TypesPostprocessor) IndividualPropertySpec(won.shacl2java.sourcegen.typegen.support.IndividualPropertySpec) ClassConstraint(org.apache.jena.shacl.engine.constraint.ClassConstraint) Shape(org.apache.jena.shacl.parser.Shape) NameUtils(won.shacl2java.util.NameUtils) URI(java.net.URI) Method(java.lang.reflect.Method) TypeSpecNames(won.shacl2java.sourcegen.typegen.mapping.TypeSpecNames) PropertySpec(won.shacl2java.constraints.PropertySpec) P_Inverse(org.apache.jena.sparql.path.P_Inverse) Logger(org.slf4j.Logger) SHACL(org.apache.jena.shacl.vocabulary.SHACL) MethodHandles(java.lang.invoke.MethodHandles) CLASS(com.squareup.javapoet.TypeSpec.Kind.CLASS) ShapeTypeSpecs(won.shacl2java.sourcegen.typegen.mapping.ShapeTypeSpecs) CollectionUtils(won.shacl2java.util.CollectionUtils) Collectors(java.util.stream.Collectors) Consumer(java.util.function.Consumer) TypegenUtils(won.shacl2java.sourcegen.typegen.support.TypegenUtils) Individual(won.shacl2java.annotation.Individual) Literal(org.apache.jena.rdf.model.Literal) ProducerConsumerMap(won.shacl2java.sourcegen.typegen.support.ProducerConsumerMap) Shacl2JavaConfig(won.shacl2java.Shacl2JavaConfig) RDFDatatype(org.apache.jena.datatypes.RDFDatatype) Shapes(org.apache.jena.shacl.Shapes) PropertyShape(org.apache.jena.shacl.parser.PropertyShape) PropertyShape(org.apache.jena.shacl.parser.PropertyShape) Shape(org.apache.jena.shacl.parser.Shape) IndividualPropertySpec(won.shacl2java.sourcegen.typegen.support.IndividualPropertySpec) PropertySpec(won.shacl2java.constraints.PropertySpec) PropertyPath(won.shacl2java.annotation.PropertyPath) Path(org.apache.jena.sparql.path.Path)

Example 2 with Shacl2JavaConfig

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);
    }
}
Also used : Shacl2JavaConfig(won.shacl2java.Shacl2JavaConfig) SourceGenerator(won.shacl2java.sourcegen.SourceGenerator) Shapes(org.apache.jena.shacl.Shapes) File(java.io.File) TypeSpec(com.squareup.javapoet.TypeSpec)

Aggregations

Shapes (org.apache.jena.shacl.Shapes)2 Shacl2JavaConfig (won.shacl2java.Shacl2JavaConfig)2 com.squareup.javapoet (com.squareup.javapoet)1 TypeSpec (com.squareup.javapoet.TypeSpec)1 CLASS (com.squareup.javapoet.TypeSpec.Kind.CLASS)1 File (java.io.File)1 MethodHandles (java.lang.invoke.MethodHandles)1 Method (java.lang.reflect.Method)1 URI (java.net.URI)1 java.util (java.util)1 Consumer (java.util.function.Consumer)1 Collectors (java.util.stream.Collectors)1 Modifier (javax.lang.model.element.Modifier)1 RDFDatatype (org.apache.jena.datatypes.RDFDatatype)1 org.apache.jena.graph (org.apache.jena.graph)1 Literal (org.apache.jena.rdf.model.Literal)1 ClassConstraint (org.apache.jena.shacl.engine.constraint.ClassConstraint)1 PropertyShape (org.apache.jena.shacl.parser.PropertyShape)1 Shape (org.apache.jena.shacl.parser.Shape)1 SHACL (org.apache.jena.shacl.vocabulary.SHACL)1