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

org.ontoware.rdfreactor.runtime.BridgeBase Maven / Gradle / Ivy

Go to download

RDFReactor creates domain-specific, type-safe Java classes which act as a view over domain-free, loosely typed RDF instances. This library needs to be shipped together with generated classes.

The newest version!
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;

/**
 * BridgeBase provides methods for adding, querying and deleting
 * statements from the underlying RDF2Go model.
 * 
 * TODO: be type-safe
 * 
 * 
 * 
 * 
* RDF Reactor uses the following naming: * * resource - 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 * * property - a property belongs to a resource, represented by the * predicate of a statement about a resource * * value - 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 with each object of type 'returnType' * @throws Exception */ @Patrolled public static Set getAllValues_asSet(Model model, Resource resource, URI propertyURI, java.lang.Class returnType) { synchronized (model) { ClosableIterator it = model.findStatements( resource, propertyURI, Variable.ANY); Set result = new HashSet(); 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> 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 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 result = new HashSet(); synchronized (model) { ClosableIterator 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 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); // } // } }