Package org.openbel.framework.tools.rdf

Source Code of org.openbel.framework.tools.rdf.RDFExporter

/**
* Copyright (C) 2012-2013 Selventa, Inc.
*
* This file is part of the OpenBEL Framework.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* The OpenBEL Framework is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
* License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with the OpenBEL Framework. If not, see <http://www.gnu.org/licenses/>.
*
* Additional Terms under LGPL v3:
*
* This license does not authorize you and you are prohibited from using the
* name, trademarks, service marks, logos or similar indicia of Selventa, Inc.,
* or, in the discretion of other licensors or authors of the program, the
* name, trademarks, service marks, logos or similar indicia of such authors or
* licensors, in any marketing or advertising materials relating to your
* distribution of the program or any covered product. This restriction does
* not waive or limit your obligation to keep intact all copyright notices set
* forth in the program as delivered to you.
*
* If you distribute the program in whole or in part, or any modified version
* of the program, and you assume contractual liability to the recipient with
* respect to the program or modified version, then you will indemnify the
* authors and licensors of the program for any liabilities that these
* contractual assumptions directly impose on those licensors and authors.
*/
package org.openbel.framework.tools.rdf;

import static org.openbel.framework.common.BELUtilities.hasItems;
import static org.openbel.framework.common.BELUtilities.nulls;
import static org.openbel.framework.tools.rdf.KAMVocabulary.AnnotationDefinition;
import static org.openbel.framework.tools.rdf.KAMVocabulary.BelDocument;
import static org.openbel.framework.tools.rdf.KAMVocabulary.KAM;
import static org.openbel.framework.tools.rdf.KAMVocabulary.KAMEdge;
import static org.openbel.framework.tools.rdf.KAMVocabulary.KAMNode;
import static org.openbel.framework.tools.rdf.KAMVocabulary.Namespace;
import static org.openbel.framework.tools.rdf.KAMVocabulary.Parameter;
import static org.openbel.framework.tools.rdf.KAMVocabulary.Statement;
import static org.openbel.framework.tools.rdf.KAMVocabulary.Term;
import static org.openbel.framework.tools.rdf.KAMVocabulary.composedOf;
import static org.openbel.framework.tools.rdf.KAMVocabulary.definedBy;
import static org.openbel.framework.tools.rdf.KAMVocabulary.defines;
import static org.openbel.framework.tools.rdf.KAMVocabulary.hasAnnotation;
import static org.openbel.framework.tools.rdf.KAMVocabulary.hasArguments;
import static org.openbel.framework.tools.rdf.KAMVocabulary.hasAuthor;
import static org.openbel.framework.tools.rdf.KAMVocabulary.hasContactInfo;
import static org.openbel.framework.tools.rdf.KAMVocabulary.hasCopyright;
import static org.openbel.framework.tools.rdf.KAMVocabulary.hasDescription;
import static org.openbel.framework.tools.rdf.KAMVocabulary.hasDisclaimer;
import static org.openbel.framework.tools.rdf.KAMVocabulary.hasFunction;
import static org.openbel.framework.tools.rdf.KAMVocabulary.hasId;
import static org.openbel.framework.tools.rdf.KAMVocabulary.hasLabel;
import static org.openbel.framework.tools.rdf.KAMVocabulary.hasLicense;
import static org.openbel.framework.tools.rdf.KAMVocabulary.hasList;
import static org.openbel.framework.tools.rdf.KAMVocabulary.hasName;
import static org.openbel.framework.tools.rdf.KAMVocabulary.hasNamespace;
import static org.openbel.framework.tools.rdf.KAMVocabulary.hasObjectNode;
import static org.openbel.framework.tools.rdf.KAMVocabulary.hasObjectTerm;
import static org.openbel.framework.tools.rdf.KAMVocabulary.hasPattern;
import static org.openbel.framework.tools.rdf.KAMVocabulary.hasPrefix;
import static org.openbel.framework.tools.rdf.KAMVocabulary.hasRelationship;
import static org.openbel.framework.tools.rdf.KAMVocabulary.hasResourceLocation;
import static org.openbel.framework.tools.rdf.KAMVocabulary.hasSubjectNode;
import static org.openbel.framework.tools.rdf.KAMVocabulary.hasSubjectTerm;
import static org.openbel.framework.tools.rdf.KAMVocabulary.hasType;
import static org.openbel.framework.tools.rdf.KAMVocabulary.hasURL;
import static org.openbel.framework.tools.rdf.KAMVocabulary.hasUsage;
import static org.openbel.framework.tools.rdf.KAMVocabulary.hasValue;
import static org.openbel.framework.tools.rdf.KAMVocabulary.hasVersion;
import static org.openbel.framework.tools.rdf.KAMVocabulary.isRepresentedBy;
import static org.openbel.framework.tools.rdf.KAMVocabulary.resourceForFunction;
import static org.openbel.framework.tools.rdf.KAMVocabulary.resourceForRelationship;

import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStream;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.UUID;

import org.apache.commons.lang.StringUtils;
import org.openbel.framework.api.Kam;
import org.openbel.framework.api.Kam.KamEdge;
import org.openbel.framework.api.Kam.KamNode;
import org.openbel.framework.api.internal.KAMCatalogDao.KamInfo;
import org.openbel.framework.api.internal.KAMStoreDaoImpl.Annotation;
import org.openbel.framework.api.internal.KAMStoreDaoImpl.AnnotationType;
import org.openbel.framework.api.internal.KAMStoreDaoImpl.BelDocumentInfo;
import org.openbel.framework.api.internal.KAMStoreDaoImpl.BelStatement;
import org.openbel.framework.api.internal.KAMStoreDaoImpl.BelTerm;
import org.openbel.framework.api.internal.KAMStoreDaoImpl.Namespace;
import org.openbel.framework.api.internal.KAMStoreDaoImpl.TermParameter;
import org.openbel.framework.api.KAMStore;
import org.openbel.framework.api.KAMStoreException;
import org.openbel.framework.common.InvalidArgument;
import org.openbel.framework.common.enums.FunctionEnum;

import com.hp.hpl.jena.ontology.OntModel;
import com.hp.hpl.jena.rdf.model.AnonId;
import com.hp.hpl.jena.rdf.model.Model;
import com.hp.hpl.jena.rdf.model.ModelFactory;
import com.hp.hpl.jena.rdf.model.RDFList;
import com.hp.hpl.jena.rdf.model.Resource;
import com.hp.hpl.jena.vocabulary.RDF;

/**
* RDFExporter builds an RDF object model from the KAM data using the
* Jena framework and then serializes it to RDF in N3 format.
*
* Data left to capture:
* TODO Support nested terms in a Term's arguments.  Currently only support Parameter resources.
* TODO Support nested statement as a statement's object.  Currently only support object Term.
*
* @see <a href="http://jena.sourceforge.net/">http://jena.sourceforge.net/</a>
* @author Anthony Bargnesi {@code <abargnesi@selventa.com>}
*/
public final class RDFExporter {

    /**
     * Jena format {@link String} for N3 notation.
     */
    private static final String N3_FORMAT = "N3";

    private static final InputStream kvis;
    static {
        kvis = RDFExporter.class.getResourceAsStream("kam.rdf");
    }

    /**
     * Private constructor to prevent instantiation.
     */
    private RDFExporter() {
    }

    /**
     * Exports an rdf {@link Model} from the KAM data.
     *
     * @param kam {@link Kam} the kam, which cannot be null
     * @param kamInfo {@link KamInfo} the kam info, which cannot be null
     * @param kAMStore {@link KAMStore} the kamstore, which cannot be null
     * @param outPath {@link String} the output path to write XGMML file to,
     * which can be null, in which case the kam's name will be used and it will
     * be written to the current directory (user.dir).
     * @throws IOException Thrown if an IO error occurred while writing the RDF
     * @throws KAMStoreException Thrown if an error occurred pulling data from
     * the kam store
     * @throws InvalidArgument Thrown if either the kam, kamInfo, kamStore, or
     * outputPath arguments were null
     */
    public static void exportRdf(final Kam kam, KamInfo kamInfo,
            final KAMStore kAMStore,
            String outputPath) throws IOException, InvalidArgument,
            KAMStoreException {
        if (nulls(kam, kamInfo, kAMStore, outputPath)) {
            throw new InvalidArgument("argument(s) were null");
        }

        // create new ontology model and read in KAM Vocabulary model
        OntModel model = ModelFactory.createOntologyModel();
        model.read(kvis, null, "RDF/XML");

        // add kam resource
        Resource kamResource =
                model.createResource(new AnonId(UUID.randomUUID().toString()));

        // kam type KAM
        kamResource.addProperty(RDF.type, KAM);

        // kam hasName "kam"^^xsd:string
        kamResource.addProperty(hasName,
                model.createTypedLiteral(kamInfo.getName()));

        // kam hasDescription "kam"^^xsd:string
        kamResource.addProperty(hasDescription,
                model.createTypedLiteral(kamInfo.getDescription()));

        Map<Integer, Resource> documents = new HashMap<Integer, Resource>();
        Map<Integer, Resource> annotationDefinitions =
                new HashMap<Integer, Resource>();
        Map<Integer, Resource> annotations = new HashMap<Integer, Resource>();

        List<BelDocumentInfo> docs = kAMStore.getBelDocumentInfos(kamInfo);
        for (BelDocumentInfo doc : docs) {
            Resource docResource =
                    model.createResource(new AnonId(UUID.randomUUID()
                            .toString()));
            docResource.addProperty(RDF.type, BelDocument);

            // handle document fields
            if (doc.getAuthors() != null) {
                docResource.addProperty(hasAuthor,
                        model.createTypedLiteral(doc.getAuthors()));
            }

            if (doc.getContactInfo() != null) {
                docResource.addProperty(hasContactInfo,
                        model.createTypedLiteral(doc.getContactInfo()));
            }

            if (doc.getCopyright() != null) {
                docResource.addProperty(hasCopyright,
                        model.createTypedLiteral(doc.getCopyright()));
            }

            if (doc.getDescription() != null) {
                docResource.addProperty(hasDescription,
                        model.createTypedLiteral(doc.getDescription()));
            }

            if (doc.getDisclaimer() != null) {
                docResource.addProperty(hasDisclaimer,
                        model.createTypedLiteral(doc.getDisclaimer()));
            }

            if (doc.getLicenseInfo() != null) {
                docResource.addProperty(hasLicense,
                        model.createTypedLiteral(doc.getLicenseInfo()));
            }

            if (doc.getName() != null) {
                docResource.addProperty(hasName,
                        model.createTypedLiteral(doc.getName()));
            }

            if (doc.getVersion() != null) {
                docResource.addProperty(hasVersion,
                        model.createTypedLiteral(doc.getVersion()));
            }

            List<Namespace> namespaces = doc.getNamespaces();
            for (Namespace namespace : namespaces) {
                // add namespace resource by it's URL
                Resource namespaceResource = model.createResource(namespace
                        .getResourceLocation());
                namespaceResource.addProperty(RDF.type, Namespace);

                // associate prefix and resource location
                namespaceResource.addProperty(hasPrefix,
                        model.createTypedLiteral(namespace.getPrefix()));
                namespaceResource.addProperty(hasResourceLocation,
                        model.createTypedLiteral(namespace
                                .getResourceLocation()));

                // associate document with namespace as a defines relationship
                docResource.addProperty(defines, namespaceResource);
            }

            List<AnnotationType> annotationTypes = doc.getAnnotationTypes();
            for (AnnotationType annotationType : annotationTypes) {
                final Resource annotationDefResource;

                switch (annotationType.getAnnotationDefinitionType()) {
                case ENUMERATION:
                    annotationDefResource =
                            model
                                    .createResource(new AnonId(UUID
                                            .randomUUID().toString()));

                    // associate metadata of annotation type
                    annotationDefResource.addProperty(hasName,
                            model.createTypedLiteral(annotationType.getName()));
                    if (StringUtils.isNotBlank(annotationType.getDescription())) {
                        annotationDefResource.addProperty(hasDescription, model
                                .createTypedLiteral(annotationType
                                        .getDescription()));
                    }
                    annotationDefResource.addProperty(hasType, model
                            .createTypedLiteral(annotationType
                                    .getAnnotationDefinitionType()
                                    .getDisplayValue()));

                    if (StringUtils.isNotBlank(annotationType.getDescription())) {
                        annotationDefResource.addProperty(hasUsage, model
                                .createTypedLiteral(annotationType.getUsage()));
                    }

                    // read list domain for internal list annotation
                    List<String> domain =
                            kAMStore.getAnnotationTypeDomainValues(kamInfo,
                                    annotationType);

                    if (hasItems(domain)) {
                        RDFList enumres = model.createList();
                        enumres.setStrict(true);

                        // iterate domain to pre-build RDF resources and associate domain value
                        Resource[] itemResources = new Resource[domain.size()];
                        String[] domainValues =
                                domain.toArray(new String[domain.size()]);
                        for (int i = 0; i < domainValues.length; i++) {
                            itemResources[i] = model
                                    .createResource(new AnonId(UUID
                                            .randomUUID().toString()));
                            itemResources[i].addProperty(RDF.type, RDF.List);
                            itemResources[i].addProperty(RDF.first,
                                    model.createTypedLiteral(domainValues[i]));
                        }

                        // iterate item resources to link them
                        for (int i = 0; i < itemResources.length; i++) {
                            if ((i + 1) < itemResources.length) {
                                // link to next domain value
                                itemResources[i].addProperty(RDF.rest,
                                        itemResources[i + 1]);
                            } else {
                                // link to RDF.nil indicating end of list
                                itemResources[i].addProperty(RDF.rest, RDF.nil);
                            }

                            enumres = enumres.with(itemResources[i]);
                        }

                        // associate annotation to the domain list
                        annotationDefResource.addProperty(hasList, enumres);
                    }

                    break;
                case REGULAR_EXPRESSION:
                    // read list domain for internal pattern annotation
                    domain =
                            kAMStore.getAnnotationTypeDomainValues(kamInfo,
                                    annotationType);

                    if (domain.size() != 1) {
                        throw new IllegalStateException(
                                "Expecting a single, Regular Expression pattern, but received: "
                                        + domain);
                    }

                    annotationDefResource =
                            model
                                    .createResource(new AnonId(UUID
                                            .randomUUID().toString()));

                    // associate metadata of annotation type
                    annotationDefResource.addProperty(hasName,
                            model.createTypedLiteral(annotationType.getName()));
                    annotationDefResource.addProperty(hasDescription,
                            model.createTypedLiteral(annotationType
                                    .getDescription()));
                    annotationDefResource.addProperty(hasType, model
                            .createTypedLiteral(annotationType
                                    .getAnnotationDefinitionType()
                                    .getDisplayValue()));
                    annotationDefResource
                            .addProperty(hasUsage, model
                                    .createTypedLiteral(annotationType
                                            .getUsage()));

                    String patternDomain = domain.get(0);

                    // associate annotation to the domain pattern
                    annotationDefResource.addProperty(hasPattern,
                            model.createTypedLiteral(patternDomain));
                    break;
                case URL:
                    if (annotationType.getUrl() == null) {
                        throw new IllegalStateException(
                                "Expecting non-null URL for external annotation");
                    }

                    // associate annotation to the URL where the domain is defined
                    annotationDefResource =
                            model.createResource(annotationType.getUrl());
                    annotationDefResource.addProperty(hasName,
                            model.createTypedLiteral(annotationType.getName()));
                    annotationDefResource.addProperty(hasURL,
                            model.createTypedLiteral(annotationType.getUrl()));
                    break;
                default:
                    throw new UnsupportedOperationException(
                            "Annotation definition type not supported: "
                                    + annotationType
                                            .getAnnotationDefinitionType());
                }

                annotationDefResource.addProperty(RDF.type,
                        AnnotationDefinition);

                // associate document with annotation definition as a defines relationship
                docResource.addProperty(defines, annotationDefResource);

                annotationDefinitions.put(annotationType.getId(),
                        annotationDefResource);
            }

            kamResource.addProperty(composedOf, docResource);
            documents.put(doc.getId(), docResource);
        }

        Map<KamNode, Resource> kamNodeResources =
                new HashMap<Kam.KamNode, Resource>();
        Map<Integer, Resource> termResources = new HashMap<Integer, Resource>();

        // handle kam nodes first
        Iterator<KamNode> kamNodes = kam.getNodes().iterator();
        while (kamNodes.hasNext()) {
            KamNode kamNode = kamNodes.next();

            // TODO: This is a sanity check that should be removed as LIST is not a KAM function type
            if (FunctionEnum.LIST == kamNode.getFunctionType()) {
                System.err.println("Invalid KAM node type found: "
                        + kamNode.getFunctionType().getDisplayValue());
                continue;
            }

            Resource functionResource = model.getResource(KAMVocabulary
                    .resourceForFunction(kamNode.getFunctionType()).getURI());

            // Retrieve seen KAMNode Resource or create a new Blank Node for it.
            Resource kamNodeResource;
            if (kamNodeResources.containsKey(kamNode)) {
                kamNodeResource = kamNodeResources.get(kamNode);
            } else {
                kamNodeResource = model.createResource(new AnonId(UUID
                        .randomUUID().toString()));

                // associate kam node with kam resource
                kamResource.addProperty(composedOf, kamNodeResource);
            }

            // node type KAMNode
            kamNodeResource.addProperty(RDF.type, KAMNode);

            // node hasFunction Function
            kamNodeResource.addProperty(hasFunction, functionResource);

            // node hasId "1"^^xsd:int
            kamNodeResource.addLiteral(hasId,
                    model.createTypedLiteral(kamNode.getId()));

            // node hasLabel "p(EG:207)"^^xsd:string
            kamNodeResource.addLiteral(hasLabel,
                    model.createTypedLiteral(kamNode.getLabel()));

            // hold on to kam node resources
            kamNodeResources.put(kamNode, kamNodeResource);

            // handle terms for this KAMNode
            // TODO Support nested terms instead of just Parameters!
            List<BelTerm> terms = kAMStore.getSupportingTerms(kamNode);
            for (BelTerm term : terms) {
                Resource termResource = model.createResource(new AnonId(UUID
                        .randomUUID().toString()));

                termResource.addProperty(RDF.type, Term);
                termResource.addProperty(hasId,
                        model.createTypedLiteral(term.getId()));
                termResource.addProperty(hasLabel,
                        model.createTypedLiteral(term.getLabel()));
                termResource.addProperty(hasFunction,
                        resourceForFunction(kamNode.getFunctionType()));

                RDFList argumentres = model.createList();

                List<TermParameter> termParameters =
                        kAMStore.getTermParameters(kamInfo, term);
                TermParameter[] tparray = termParameters
                        .toArray(new TermParameter[termParameters.size()]);
                Resource[] tpresarray = new Resource[tparray.length];

                // iterate term parameters to pre-build RDF resources and associate Parameter
                for (int i = 0; i < tparray.length; i++) {
                    tpresarray[i] = model.createResource(new AnonId(UUID
                            .randomUUID().toString()));
                    tpresarray[i].addProperty(RDF.type, RDF.List);

                    Resource parameterResource =
                            model
                                    .createResource(new AnonId(UUID
                                            .randomUUID().toString()));
                    parameterResource.addProperty(RDF.type, Parameter);
                    parameterResource
                            .addProperty(hasValue, model
                                    .createTypedLiteral(tparray[i]
                                            .getParameterValue()));

                    if (tparray[i].getNamespace() != null) {
                        parameterResource.addProperty(hasNamespace, model
                                .getResource(tparray[i].getNamespace()
                                        .getResourceLocation()));
                    }

                    tpresarray[i].addProperty(RDF.first, parameterResource);
                }

                // iterate argument resources to link them
                for (int i = 0; i < tpresarray.length; i++) {
                    if ((i + 1) < tpresarray.length) {
                        // link to next term argument
                        tpresarray[i].addProperty(RDF.rest, tpresarray[i + 1]);
                    } else {
                        // link to RDF.nil indicating end of list
                        tpresarray[i].addProperty(RDF.rest, RDF.nil);
                    }

                    argumentres = argumentres.with(tpresarray[i]);
                }

                // associate term resource to the arguments list
                termResource.addProperty(hasArguments, argumentres);

                // node is represented by the term
                kamNodeResource.addProperty(isRepresentedBy, termResource);

                // hold on to term resources
                termResources.put(term.getId(), termResource);
            }
        }

        // handle kam edges second
        Iterator<KamEdge> kamEdges = kam.getEdges().iterator();
        while (kamEdges.hasNext()) {
            KamEdge kamEdge = kamEdges.next();

            Resource relationshipResource =
                    KAMVocabulary.resourceForRelationship(kamEdge
                            .getRelationshipType());

            Resource kamEdgeResource =
                    model.createResource(new AnonId(UUID.randomUUID()
                            .toString()));

            // associate kam edge with kam resource
            kamResource.addProperty(composedOf, kamEdgeResource);

            // edge type KAMEdge
            kamEdgeResource.addProperty(RDF.type, KAMEdge);

            // edge hasRelationship Relationship
            kamEdgeResource.addProperty(hasRelationship, relationshipResource);

            // edge hasId "1"^^xsd:int
            kamEdgeResource.addLiteral(hasId,
                    model.createTypedLiteral(kamEdge.getId()));

            Resource sourceResource =
                    kamNodeResources.get(kamEdge.getSourceNode());
            Resource targetResource =
                    kamNodeResources.get(kamEdge.getTargetNode());

            // TODO: This is a sanity check that should be removed
            if (null == sourceResource || null == targetResource) {
                System.err
                        .println("Can't locate source or target node resource for edge: "
                                + kamEdge.toString());
                continue;
            }

            // edge hasSubjectNode KAMNode
            kamEdgeResource.addProperty(hasSubjectNode, sourceResource);

            // edge hasObjectNode KAMNode
            kamEdgeResource.addProperty(hasObjectNode, targetResource);

            // TODO Handle object statements
            // TODO Handle statement annotation associations
            List<BelStatement> statements =
                    kAMStore.getSupportingEvidence(kamEdge);
            for (BelStatement statement : statements) {
                if (null == statement.getObject()) {
                    continue;
                }

                if (!BelTerm.class.isAssignableFrom(statement.getObject()
                        .getClass())) {
                    continue;
                }

                Resource statementResource =
                        model.createResource(new AnonId(UUID.randomUUID()
                                .toString()));

                statementResource.addProperty(RDF.type, Statement);
                statementResource.addProperty(hasId,
                        model.createTypedLiteral(statement.getId()));

                // associate statement with document
                Resource docres =
                        documents.get(statement.getBelDocumentInfo().getId());
                docres.addProperty(defines, statementResource);

                Resource subjectTermResource =
                        termResources.get(statement.getSubject().getId());

                if (subjectTermResource == null) {
                    throw new IllegalStateException(
                            "subject term for statement is not known.");
                }

                statementResource.addProperty(hasSubjectTerm,
                        subjectTermResource);

                if (statement.getObject() != null) {
                    Resource objectTermResource =
                            termResources.get(statement.getObject().getId());

                    if (objectTermResource == null) {
                        throw new IllegalStateException(
                                "object term for statement is not known.");
                    }

                    // associate to relationship and object term
                    statementResource.addProperty(hasRelationship,
                            resourceForRelationship(statement
                                    .getRelationshipType()));
                    statementResource.addProperty(hasObjectTerm,
                            objectTermResource);

                    // associate edge to this subject,rel,object statement
                    kamEdgeResource.addProperty(isRepresentedBy,
                            statementResource);
                }

                // associate annotations to statement
                List<Annotation> statementAnnotations =
                        statement.getAnnotationList();
                for (Annotation statementAnnotation : statementAnnotations) {
                    Resource ares =
                            annotations.get(statementAnnotation.getId());
                    if (ares == null) {
                        ares =
                                model.createResource(new AnonId(UUID
                                        .randomUUID().toString()));
                        annotations.put(statementAnnotation.getId(), ares);
                    }

                    // associate annotation value to annotation
                    ares.addProperty(hasValue, model
                            .createTypedLiteral(statementAnnotation.getValue()));

                    Integer adefId =
                            statementAnnotation.getAnnotationType().getId();
                    Resource adefResource = annotationDefinitions.get(adefId);

                    // associate annotation with the annotation definition it is defined by
                    ares.addProperty(definedBy, adefResource);

                    // associate statement with its annotation
                    statementResource.addProperty(hasAnnotation, ares);
                }
            }
        }

        model.write(new FileWriter(outputPath), N3_FORMAT);
    }
}
TOP

Related Classes of org.openbel.framework.tools.rdf.RDFExporter

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.