All Downloads are FREE. Search and download functionalities are using the official Maven repository.

edu.rpi.tw.twks.nanopub.NanopublicationBuilder Maven / Gradle / Ivy

There is a newer version: 1.0.4
Show newest version
package edu.rpi.tw.twks.nanopub;

import edu.rpi.tw.twks.uri.Uri;
import edu.rpi.tw.twks.vocabulary.PROV;
import edu.rpi.tw.twks.vocabulary.SIO;
import edu.umd.cs.findbugs.annotations.Nullable;
import org.apache.jena.datatypes.xsd.XSDDateTime;
import org.apache.jena.rdf.model.*;
import org.apache.jena.vocabulary.OWL;
import org.apache.jena.vocabulary.RDF;

import java.util.Calendar;
import java.util.UUID;

import static com.google.common.base.Preconditions.checkNotNull;
import static edu.rpi.tw.twks.vocabulary.Vocabularies.setNsPrefixes;

public final class NanopublicationBuilder {
    private final NanopublicationAssertionBuilder assertionBuilder = new NanopublicationAssertionBuilder();
    // Generate a URI to use for the nanopublication and/or parts whose URIs aren't set explicitly.
    private final Uri generatedUri = Uri.parse("urn:uuid:" + UUID.randomUUID().toString());
    private final NanopublicationProvenanceBuilder provenanceBuilder = new NanopublicationProvenanceBuilder();
    private final NanopublicationPublicationInfoBuilder publicationInfoBuilder = new NanopublicationPublicationInfoBuilder();
    private @Nullable
    Uri uri = null;

    NanopublicationBuilder() {
    }

    public final Nanopublication build() {
        final Uri nanopublicationUri = this.uri != null ? this.uri : this.generatedUri;

        final NanopublicationPart assertion = assertionBuilder.build();
        final Uri headUri = Uri.parse(generatedUri.toString() + "#head");
        final NanopublicationPart provenance = provenanceBuilder.build(assertion.getName());
        final NanopublicationPart publicationInfo = publicationInfoBuilder.build(assertion.getModel(), nanopublicationUri);

        try {
            return NanopublicationFactory.DEFAULT.createNanopublicationFromParts(assertion, headUri, nanopublicationUri, provenance, publicationInfo);
        } catch (final MalformedNanopublicationException e) {
            throw new IllegalStateException(e);
        }
    }

    public final NanopublicationAssertionBuilder getAssertionBuilder() {
        return assertionBuilder;
    }

    public final NanopublicationProvenanceBuilder getProvenanceBuilder() {
        return provenanceBuilder;
    }

    public final NanopublicationPublicationInfoBuilder getPublicationInfoBuilder() {
        return publicationInfoBuilder;
    }

    public final NanopublicationBuilder setUri(@Nullable final Uri uri) {
        this.uri = checkNotNull(uri);
        return this;
    }

    private enum NanopublicationPartType {
        ASSERTION,
        PROVENANCE,
        PUBLICATION_INFO
    }

    public final class NanopublicationAssertionBuilder extends NanopublicationPartBuilder {
        private NanopublicationAssertionBuilder() {
        }

        private NanopublicationPart build() {
            if (!getModel().listStatements().hasNext()) {
                throw new IllegalArgumentException("no assertion statements");
            }

            return new NanopublicationPart(getModel(), getOrGenerateName());
        }

        @Override
        protected final NanopublicationPartType getType() {
            return NanopublicationPartType.ASSERTION;
        }
    }

    private abstract class NanopublicationPartBuilder> {
        private Model model;
        private @Nullable
        Uri name = null;

        private NanopublicationPartBuilder() {
            this.setModel(ModelFactory.createDefaultModel());
        }

        public final Model getModel() {
            return model;
        }

        @SuppressWarnings("unchecked")
        public NanopublicationPartBuilderT setModel(final Model model) {
            this.model = checkNotNull(model);
            setNsPrefixes(model);
            return (NanopublicationPartBuilderT) this;
        }

        public final NanopublicationBuilder getNanopublicationBuilder() {
            return NanopublicationBuilder.this;
        }

        protected final Uri getOrGenerateName() {
            if (this.name != null) {
                return this.name;
            }
            return Uri.parse(NanopublicationBuilder.this.generatedUri.toString() + "#" + getType().name().toLowerCase());
        }

        protected abstract NanopublicationPartType getType();

        @SuppressWarnings("unchecked")
        public final NanopublicationPartBuilderT setName(final Uri name) {
            this.name = checkNotNull(name);
            return (NanopublicationPartBuilderT) this;
        }
    }

    public final class NanopublicationProvenanceBuilder extends NanopublicationPartBuilder {
        private NanopublicationProvenanceBuilder() {
        }

        NanopublicationPart build(final Uri assertionName) {
            final Resource assertionResource = ResourceFactory.createResource(assertionName.toString());
            if (!getModel().listStatements(assertionResource, null, (String) null).hasNext()) {
                getModel().add(assertionResource, PROV.generatedAtTime, ResourceFactory.createTypedLiteral(new XSDDateTime(Calendar.getInstance())));
            }
            return new NanopublicationPart(getModel(), getOrGenerateName());
        }

        @Override
        protected final NanopublicationPartType getType() {
            return NanopublicationPartType.PROVENANCE;
        }
    }

    public final class NanopublicationPublicationInfoBuilder extends NanopublicationPartBuilder {
        private NanopublicationPublicationInfoBuilder() {
        }

        NanopublicationPart build(final Model assertionModel, final Uri nanopublicationUri) {
            final Resource nanopublicationResource = ResourceFactory.createResource(nanopublicationUri.toString());

            // Reproducing Whyis functionality: if the assertions contain a statement of the form (?x a owl:Ontology), the publication info should have a statement (?np sio:isAbout ?x).
            {
                for (final StmtIterator ontologyStatements = assertionModel.listStatements(null, RDF.type, OWL.Ontology); ontologyStatements.hasNext(); ) {
                    final Statement ontologyStatement = ontologyStatements.nextStatement();
                    final Resource ontologyResource = ontologyStatement.getSubject();
                    if (ontologyResource.getURI() == null) {
                        continue;
                    }
                    final StmtIterator isAboutStatements = getModel().listStatements(nanopublicationResource, SIO.isAbout, ontologyResource);
                    if (!isAboutStatements.hasNext()) {
                        getModel().add(nanopublicationResource, SIO.isAbout, ontologyResource);
                    }
                }
            }

            if (!getModel().listStatements(nanopublicationResource, null, (String) null).hasNext()) {
                getModel().add(nanopublicationResource, PROV.generatedAtTime, ResourceFactory.createTypedLiteral(new XSDDateTime(Calendar.getInstance())));
            }


            return new NanopublicationPart(getModel(), getOrGenerateName());
        }

        @Override
        protected final NanopublicationPartType getType() {
            return NanopublicationPartType.PUBLICATION_INFO;
        }
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy