Package org.ontoware.rdfreactor.runtime

Source Code of org.ontoware.rdfreactor.runtime.BridgeBase

package org.ontoware.rdfreactor.runtime;

import java.lang.reflect.Array;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;

import org.ontoware.aifbcommons.collection.ClosableIterator;
import org.ontoware.rdf2go.exception.ModelRuntimeException;
import org.ontoware.rdf2go.model.Model;
import org.ontoware.rdf2go.model.Statement;
import org.ontoware.rdf2go.model.impl.ModelAddRemoveMemoryImpl;
import org.ontoware.rdf2go.model.impl.TriplePatternImpl;
import org.ontoware.rdf2go.model.node.Node;
import org.ontoware.rdf2go.model.node.Resource;
import org.ontoware.rdf2go.model.node.URI;
import org.ontoware.rdf2go.model.node.Variable;
import org.ontoware.rdf2go.vocabulary.RDF;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
* <b>BridgeBase</b> provides methods for adding, querying and deleting
* statements from the underlying RDF2Go model.
*
* TODO: be type-safe
*
*
*
* <br>
* RDF Reactor uses the following naming:
*
* <b>resource</b> - instance of an RDF schema class, identified by the
* resource ID (an URI or BlankNode), allmost all statements about the resource
* use the resource ID as the object
*
* <b>property</b> - a property belongs to a resource, represented by the
* predicate of a statement about a resource
*
* <b>value</b> - value of a property of a resource, represented by the object
* of the statement with the property as predicate and the resource ID as the
* subject
*
* @author mvo
*/

public class BridgeBase {

  private static Logger log = LoggerFactory.getLogger(BridgeBase.class);

  // /////////////////////////
  // true implementations

  /**
   * Check if the resource identified by resourceID, has a property
   * identidified by propertyURI which has the given value among its values.
   *
   * @param model -
   *            the underlying RDF2Go model
   * @param resource -
   *            must be an URI or a BlankNode
   * @param propertyURI -
   *            URI of the property
   * @param value -
   *            look for this value of the property
   * @return true if value is among values for the property
   * @throws Exception
   */
  @Patrolled
  public static boolean containsGivenValue(Model model, Resource resource,
      URI propertyURI, Object value) throws ModelRuntimeException {

    Node objectNode = RDFReactorRuntime.java2node(model, value);
    return model.contains(resource, propertyURI, objectNode);
  }

  /**
   * Return the first x with matching statement (resourceObject, propertyURI,
   * x) from the given model. If severeal matching statements exist, only the
   * first is returned.
   *
   * @param model -
   *            the underlying RDF2Go model
   * @param resourceSubject -
   *            the URI or BlankNode of the resource
   * @param propertyURI -
   *            the URI of the property
   * @param returnType -
   *            return the value from the statement as the given Java Type
   * @return the first x matching (resourceObject, propertyURI, x)
   * @throws RDFDataException
   *             if more then one value was found
   * @throws ModelRuntimeException
   */
  @Patrolled
  public static Object getValue(Model model, Resource resourceSubject,
      URI propertyURI, java.lang.Class<?> returnType)
      throws RDFDataException, ModelRuntimeException {
    Node node = ResourceUtils.getSingleValue(model, resourceSubject,
        propertyURI);
    return RDFReactorRuntime.node2javatype(model, node, returnType);
  }

  /**
   * Return a Set with all x matching (resourceObject, propertyURI, x) in the
   * given model.
   *
   * @param model -
   *            the underlying model
   * @param resource -
   *            URI or BlankNode of the resource
   * @param propertyURI -
   *            URI of the property
   * @param returnType -
   *            return the found values as the given Java Type
   * @return Set<Object> with each object of type 'returnType'
   * @throws Exception
   */
  @Patrolled
  public static Set<Object> getAllValues_asSet(Model model,
      Resource resource, URI propertyURI, java.lang.Class<?> returnType) {
    synchronized (model) {
      ClosableIterator<? extends Statement> it = model.findStatements(
          resource, propertyURI, Variable.ANY);
      Set<Object> result = new HashSet<Object>();
      while (it.hasNext()) {
        Node rdfnode = it.next().getObject();
        result.add(RDFReactorRuntime.node2javatype(model, rdfnode,
            returnType));
      }
      it.close();
      return result;
    }
  }

  /**
   * Get all values for the given resource and property.
   *
   * @param model -
   *            the underlying RDF2Go model
   * @param resource -
   *            URI or BlankNode of the resource
   * @param propertyURI -
   *            URI of the property
   * @param returnType -
   *            return the values typed as returnType
   * @return array of type 'returnType' with 0..n values. Never null.
   * @throws Exception
   */
  @Patrolled
  public static Object[] getAllValues(Model model, Resource resource,
      URI propertyURI, java.lang.Class<?> returnType) {
    return triplepattern2reactor(model, TriplePatternImpl
        .createObjectPattern(resource, propertyURI), returnType);
  }

  /**
   * Get all resources having the given property and value.
   *
   * @param model -
   *            the underlying RDF2Go model
   * @param propertyURI -
   *            URI of the property
   * @param objectNode -
   *            predicate/value of the property
   * @param returnType -
   *            return the values typed as returnType
   * @return array of type 'returnType' with 0..n values. Never null.
   * @throws Exception
   */
  @Patrolled
  public static Object[] getAllValues_Inverse(Model model, URI propertyURI,
      Node objectNode, java.lang.Class<?> returnType)
      throws ModelRuntimeException {
    return triplepattern2reactor(model, TriplePatternImpl
        .createSubjectPattern(propertyURI, objectNode), returnType);
  }

  /**
   * Query the model with a SPARQL query.
   *
   * @param model -
   *            the underlying RDF2GO model
   * @param returnTypes -
   *            cast the values to the types in returnTypes[]
   * @param sparqlSelectQuery -
   *            the SPARQL query
   * @return java objects, typed as desired by 'returnTypes'
   * @throws Exception
   */
  @Patrolled
  public static OOQueryResultTable getSparqlSelect(Model model,
      Map<String, Class<?>> returnTypes, String sparqlSelectQuery)
      throws ModelRuntimeException {
    return new OOQueryResultTableImpl(model, returnTypes, sparqlSelectQuery);
  }

  /**
   * Add a value to a property of a resource.
   *
   * @param model -
   *            the underlying RDF2Go model
   * @param subject -
   *            URI or BlankNode representing the resource
   * @param property -
   *            URI of the property
   * @param object -
   *            value of the property which is to be added to the resource
   * @throws Exception
   */
  @Patrolled
  public static void add(Model model, Resource subject, URI property,
      Object object) throws ModelRuntimeException {
    addStatementGeneric(model, subject, property, RDFReactorRuntime
        .java2node(model, object));
  }

  /**
   * Get all instances of the class in the model.
   *
   * @param model -
   *            the underlying RDF2Go class
   * @param javaClass -
   *            the requested Java class
   * @return Array of the given javaClass type instances in the model
   */
  @Patrolled
  public static Object[] getAllInstances(Model model,
      java.lang.Class<?> javaClass) {
    URI rdfsClass;
    try {
      rdfsClass = (URI) javaClass.getDeclaredField("RDFS_CLASS")
          .get(null);
      return triplepattern2reactor(model, TriplePatternImpl
          .createObjectPattern(RDF.type, rdfsClass), javaClass);
    } catch (IllegalArgumentException e) {
      throw new RuntimeException(e);
    } catch (SecurityException e) {
      throw new RuntimeException(e);
    } catch (IllegalAccessException e) {
      throw new RuntimeException(e);
    } catch (NoSuchFieldException e) {
      throw new RuntimeException(e);
    } catch (Exception e) {
      throw new RuntimeException(e);
    }
  }

  /**
   * Remove all values of a property from a resource. (types don't matter
   * here)
   *
   * @param model -
   *            the underlying RDF2Go model
   * @param resourceObject -
   *            URI or BlankNode of the resource
   * @param propertyURI -
   *            URI of the property
   * @return true if any value was present
   * @throws Exception
   */
  public static boolean removeAllValues(Model model, Resource r, URI p)
      throws ModelRuntimeException {
    assert model != null;
    assert r != null;
    assert p != null;

    synchronized (model) {
      ModelAddRemoveMemoryImpl toBeDeleted = new ModelAddRemoveMemoryImpl();
      toBeDeleted.addAll(model.findStatements(r, p, Variable.ANY));
      ClosableIterator<Statement> it = toBeDeleted.iterator();
      model.removeAll(it);
      it.close();
      return toBeDeleted.size() > 0;
    }
  }

  /**
   * Remove a value of a property from a resource.
   *
   * @param model -
   *            the underlying RDF2Go model
   * @param resource -
   *            URI or BlankNode of the resource
   * @param propertyURI -
   *            URI of the property
   * @param value -
   *            value of the property which is removed
   * @return true if value could be removed
   * @throws Exception
   */
  static boolean removeValue(Model model, Resource resource, URI propertyURI,
      Object value) throws ModelRuntimeException {
    Node objectNode = RDFReactorRuntime.java2node(model, value);
    boolean found = model.contains(resource, propertyURI, objectNode);

    if (found) {
      model.removeStatement(resource, propertyURI, objectNode);
    }
    return found;
  }

  // /////////////////////////////
  // type conversion utilities

  /**
   * Take a TripplePattern, apply it to the model, and return an array with
   * the found instances typed as returnType.
   *
   * @param model -
   *            the underlying RDF2Go model
   * @param triplePattern -
   *            TriplePattern for which matches are searched
   * @param returnType -
   *            convert all found instances to this type
   * @return array with 0..n instances (never null) typed as 'returnType'
   * @throws Exception
   */
  @Patrolled
  private static Object[] triplepattern2reactor(Model model,
      org.ontoware.rdf2go.model.impl.TriplePatternImpl triplePattern,
      Class<?> returnType) {
    log.debug("looking for " + triplePattern);
    Set<Object> result = new HashSet<Object>();
    synchronized (model) {
      ClosableIterator<? extends Statement> it = model
          .findStatements(triplePattern);
      // eliminates duplicates
      while (it.hasNext()) {
        log.debug("got a result");
        Statement statement = it.next();
        Node rdfnode = triplePattern.getExtract(statement);
        result.add(RDFReactorRuntime.node2javatype(model, rdfnode,
            returnType));
      }
      it.close();
    }
    log.debug("Found " + result.size() + " results");
    // IMPROVE: quite complicated array creation
    Object[] resultValues = result.toArray();
    Object[] resultAsArray = (Object[]) Array.newInstance(returnType,
        result.size());

    for (int i = 0; i < resultAsArray.length; i++) {
      log.debug("casting " + resultValues[i] + " to " + returnType);
      resultAsArray[i] = returnType.cast(resultValues[i]);
    }
    return resultAsArray;
  }

  // @Patrolled
  // private static Object triplepattern2reactor_singleValue(Model model,
  // org.ontoware.rdf2go.model.impl.TriplePatternImpl triplePattern,
  // Class<?> returnType) {
  // log.debug("looking for *the* single value of " + triplePattern);
  // Object result = null;
  // synchronized (model) {
  // ClosableIterator<? extends Statement> it = model
  // .findStatements(triplePattern);
  // while (it.hasNext()) {
  // Statement statement = it.next();
  // Node rdfnode = triplePattern.getExtract(statement);
  // result = uriBlankLiteral2reactor(model, rdfnode, returnType);
  // }
  // it.close();
  // }
  //
  // return result;
  // }

  /**
   * Add a statement (subject, property, o) to the given model. ("generic"
   * because a lot of type casting is necessary if generic objects are allowed
   * as arguments).
   *
   * @param model -
   *            the underlying RDF2Go model
   * @param subject -
   *            subject of the statement has to be an URI or BlankNode
   * @param property -
   *            predicate of the statement has to be an URI
   * @param object -
   *            object of the statement can be an URI, URI[], String,
   *            DatatypeLiteral, LanguageTagLiteral or generic Object[]
   * @throws Exception
   */
  @Patrolled
  private static void addStatementGeneric(Model model, Resource subject,
      URI property, Object object) throws ModelRuntimeException {
    assert subject != null;
    assert property != null;
    assert object != null;
    log.debug("add (" + subject + "," + property + "," + object + ")");

    if (object.getClass().isArray()) {
      // handle each component
      log.debug("object is an instanceof some Array");
      Object[] values = (Object[]) object;
      for (int i = 0; i < values.length; i++) {
        addStatementGeneric_singleValue(model, subject, property,
            values[i]);
      }
    } else {
      // handle once
      addStatementGeneric_singleValue(model, subject, property, object);
    }
  }

  /**
   * Add a single statement.
   *
   * @param model
   * @param subject
   * @param property
   * @param object -
   *            handles rdf2go nodes and strings
   */
  @Patrolled
  private static void addStatementGeneric_singleValue(Model model,
      Resource subject, URI property, Object object) {
    if (object instanceof Node) {
      log
          .debug("object is an instance of an Rdf2go Node (URI, Literal, ...) , so will add as single resource");
      model.addStatement(subject, property, (Node) object);
    } else if (object instanceof String) {
      model.addStatement(subject, property, (String) object);
    } else
      throw new RuntimeException("unknown object type "
          + object.getClass());
  }

  // /**
  // * convert a ReactorBase or primitive Java object to a type used in the
  // * RDF2GO model
  // *
  // * @param reactorValue
  // * @return URI, String and Blank nodes are passed through, ReactorBase
  // * instances have their identifier returned.
  // * @throws ModelRuntimeException
  // */
  // private static Object toRDF2GoType(Object reactorValue) {
  // if (reactorValue == null) {
  // throw new IllegalArgumentException("Argument may not be null");
  // }
  //
  // // array in, array out
  //
  // if (reactorValue.getClass().isArray()) {
  // log.debug("object is an array");
  // Object[] reactorValues = (Object[]) reactorValue;
  // Node[] nodes = new Node[reactorValues.length];
  // for (int i = 0; i < reactorValues.length; i++) {
  // nodes[i] = toRDF2GoNode(reactorValues[i]);
  // }
  // return nodes;
  // }
  //
  // // if (reactorValue instanceof ResourceEntity[]) {
  // // log
  // // .debug("object is an instanceof ReactorBase[], so will add as
  // // multiple resources");
  // // ResourceEntity[] values = (ResourceEntity[]) reactorValue;
  // // Resource[] javatype = new Resource[values.length];
  // // for (int i = 0; i < values.length; i++) {
  // // javatype[i] = ((ResourceEntity) values[i]).getResource();
  // // }
  // // return javatype;
  // // }
  // else {
  // log.debug("object is simple, converting to rdf2go node...");
  // // value in, value out
  // return toRDF2GoNode(reactorValue);
  // }
  // }

}
TOP

Related Classes of org.ontoware.rdfreactor.runtime.BridgeBase

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.