You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@stanbol.apache.org by rw...@apache.org on 2013/10/14 16:13:59 UTC
svn commit: r1531905 - in /stanbol/trunk/entityhub/yard/sesame: ./ src/
src/main/ src/main/java/ src/main/java/org/ src/main/java/org/apache/
src/main/java/org/apache/stanbol/ src/main/java/org/apache/stanbol/entityhub/
src/main/java/org/apache/stanbol...
Author: rwesten
Date: Mon Oct 14 14:13:59 2013
New Revision: 1531905
URL: http://svn.apache.org/r1531905
Log:
STANBOL-1169: Implementation of a Sesame based Entityhub Yard
Added:
stanbol/trunk/entityhub/yard/sesame/ (with props)
stanbol/trunk/entityhub/yard/sesame/pom.xml
stanbol/trunk/entityhub/yard/sesame/src/
stanbol/trunk/entityhub/yard/sesame/src/main/
stanbol/trunk/entityhub/yard/sesame/src/main/java/
stanbol/trunk/entityhub/yard/sesame/src/main/java/org/
stanbol/trunk/entityhub/yard/sesame/src/main/java/org/apache/
stanbol/trunk/entityhub/yard/sesame/src/main/java/org/apache/stanbol/
stanbol/trunk/entityhub/yard/sesame/src/main/java/org/apache/stanbol/entityhub/
stanbol/trunk/entityhub/yard/sesame/src/main/java/org/apache/stanbol/entityhub/yard/
stanbol/trunk/entityhub/yard/sesame/src/main/java/org/apache/stanbol/entityhub/yard/sesame/
stanbol/trunk/entityhub/yard/sesame/src/main/java/org/apache/stanbol/entityhub/yard/sesame/SesameQueryResultList.java
stanbol/trunk/entityhub/yard/sesame/src/main/java/org/apache/stanbol/entityhub/yard/sesame/SesameYard.java
stanbol/trunk/entityhub/yard/sesame/src/main/java/org/apache/stanbol/entityhub/yard/sesame/SesameYardConfig.java
stanbol/trunk/entityhub/yard/sesame/src/main/resources/
stanbol/trunk/entityhub/yard/sesame/src/test/
stanbol/trunk/entityhub/yard/sesame/src/test/java/
stanbol/trunk/entityhub/yard/sesame/src/test/java/org/
stanbol/trunk/entityhub/yard/sesame/src/test/java/org/apache/
stanbol/trunk/entityhub/yard/sesame/src/test/java/org/apache/stanbol/
stanbol/trunk/entityhub/yard/sesame/src/test/java/org/apache/stanbol/entityhub/
stanbol/trunk/entityhub/yard/sesame/src/test/java/org/apache/stanbol/entityhub/yard/
stanbol/trunk/entityhub/yard/sesame/src/test/java/org/apache/stanbol/entityhub/yard/sesame/
stanbol/trunk/entityhub/yard/sesame/src/test/java/org/apache/stanbol/entityhub/yard/sesame/SesameContextTest.java
stanbol/trunk/entityhub/yard/sesame/src/test/java/org/apache/stanbol/entityhub/yard/sesame/SesameYardTest.java
Propchange: stanbol/trunk/entityhub/yard/sesame/
------------------------------------------------------------------------------
--- svn:ignore (added)
+++ svn:ignore Mon Oct 14 14:13:59 2013
@@ -0,0 +1,7 @@
+target
+
+.settings
+
+.classpath
+
+.project
Added: stanbol/trunk/entityhub/yard/sesame/pom.xml
URL: http://svn.apache.org/viewvc/stanbol/trunk/entityhub/yard/sesame/pom.xml?rev=1531905&view=auto
==============================================================================
--- stanbol/trunk/entityhub/yard/sesame/pom.xml (added)
+++ stanbol/trunk/entityhub/yard/sesame/pom.xml Mon Oct 14 14:13:59 2013
@@ -0,0 +1,133 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+
+ <modelVersion>4.0.0</modelVersion>
+
+ <parent>
+ <groupId>org.apache.stanbol</groupId>
+ <artifactId>apache-stanbol-entityhub</artifactId>
+ <version>0.12.0-SNAPSHOT</version>
+ <relativePath>../..</relativePath>
+ </parent>
+
+ <artifactId>org.apache.stanbol.entityhub.yard.sesame</artifactId>
+ <packaging>bundle</packaging>
+
+ <name>Apache Stanbol Entityhub Yard based on Sesame Sail</name>
+ <description>This bundle provides implementation of the Entityhub Yard interface(s)
+ based on a Sesame Repository.
+ </description>
+
+ <inceptionYear>2013</inceptionYear>
+ <licenses>
+ <license>
+ <name>Apache Software License, Version 2.0</name>
+ <url>http://www.apache.org/licenses/LICENSE-2.0.txt</url>
+ <distribution>repo</distribution>
+ <comments>A business-friendly OSS license</comments>
+ </license>
+ </licenses>
+
+ <scm>
+ <connection>
+ scm:svn:http://svn.apache.org/repos/asf/stanbol/trunk/entityhub/yard/sesame
+ </connection>
+ <developerConnection>
+ scm:svn:https://svn.apache.org/repos/asf/stanbol/trunk/entityhub/yard/sesame
+ </developerConnection>
+ <url>http://stanbol.apache.org</url>
+ </scm>
+
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.felix</groupId>
+ <artifactId>maven-bundle-plugin</artifactId>
+ <extensions>true</extensions>
+ <configuration>
+ <instructions>
+ <Import-Package>
+ org.apache.stanbol.entityhub.servicesapi.yard; provide:=true; version="[0.11,0.13)",
+ *
+ </Import-Package>
+ <Private-Package>
+ org.apache.stanbol.entityhub.yard.sesame.impl;version=${project.version}
+ </Private-Package>
+ </instructions>
+ </configuration>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.felix</groupId>
+ <artifactId>maven-scr-plugin</artifactId>
+ </plugin>
+
+ </plugins>
+ </build>
+
+ <dependencies>
+ <dependency>
+ <groupId>org.apache.stanbol</groupId>
+ <artifactId>org.apache.stanbol.entityhub.core</artifactId>
+ <version>0.11.0</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.stanbol</groupId>
+ <artifactId>org.apache.stanbol.entityhub.model.sesame</artifactId>
+ <version>0.12.0-SNAPSHOT</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.stanbol</groupId>
+ <artifactId>org.apache.stanbol.entityhub.query.sparql</artifactId>
+ <version>0.12.0-SNAPSHOT</version>
+ </dependency>
+ <dependency> <!-- the sesame repository API -->
+ <groupId>org.openrdf.sesame</groupId>
+ <artifactId>sesame-repository-api</artifactId>
+ </dependency>
+
+ <!-- for tests -->
+ <dependency>
+ <groupId>org.apache.stanbol</groupId>
+ <artifactId>org.apache.stanbol.entityhub.test</artifactId>
+ <version>0.12.0-SNAPSHOT</version>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.openrdf.sesame</groupId>
+ <artifactId>sesame-sail-memory</artifactId>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.openrdf.sesame</groupId>
+ <artifactId>sesame-repository-sail</artifactId>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>junit</groupId>
+ <artifactId>junit</artifactId>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.slf4j</groupId>
+ <artifactId>slf4j-simple</artifactId>
+ <scope>test</scope>
+ </dependency>
+ </dependencies>
+
+</project>
Added: stanbol/trunk/entityhub/yard/sesame/src/main/java/org/apache/stanbol/entityhub/yard/sesame/SesameQueryResultList.java
URL: http://svn.apache.org/viewvc/stanbol/trunk/entityhub/yard/sesame/src/main/java/org/apache/stanbol/entityhub/yard/sesame/SesameQueryResultList.java?rev=1531905&view=auto
==============================================================================
--- stanbol/trunk/entityhub/yard/sesame/src/main/java/org/apache/stanbol/entityhub/yard/sesame/SesameQueryResultList.java (added)
+++ stanbol/trunk/entityhub/yard/sesame/src/main/java/org/apache/stanbol/entityhub/yard/sesame/SesameQueryResultList.java Mon Oct 14 14:13:59 2013
@@ -0,0 +1,80 @@
+package org.apache.stanbol.entityhub.yard.sesame;
+
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Set;
+
+import org.apache.stanbol.entityhub.query.sparql.SparqlFieldQuery;
+import org.apache.stanbol.entityhub.servicesapi.model.Representation;
+import org.apache.stanbol.entityhub.servicesapi.query.QueryResultList;
+import org.openrdf.model.Model;
+
+/**
+ * {@link QueryResultList} implementation for Sesame. This provides
+ * access to the Sesame {@link Model} holding the dat. Mainly for the use of
+ * Sesame specific RDF serializer.
+ *
+ * @author Rupert Westenthaler
+ *
+ * @param <T>
+ */
+public class SesameQueryResultList implements QueryResultList<Representation> {
+
+ protected final Model model;
+ protected final Collection<Representation> representations;
+ protected final SparqlFieldQuery query;
+
+
+ public SesameQueryResultList(Model model, SparqlFieldQuery query, List<Representation> representations){
+ this.model = model;
+ this.representations = Collections.unmodifiableCollection(representations);
+ this.query = query;
+ }
+
+ @Override
+ public SparqlFieldQuery getQuery() {
+ return query;
+ }
+
+ @Override
+ public Set<String> getSelectedFields() {
+ return query.getSelectedFields();
+ }
+
+ @Override
+ public Class<Representation> getType() {
+ return Representation.class;
+ }
+
+ @Override
+ public boolean isEmpty() {
+ return representations.isEmpty();
+
+ }
+
+ @Override
+ public Iterator<Representation> iterator() {
+ return representations.iterator();
+ }
+
+ @Override
+ public Collection<Representation> results() {
+ return representations;
+ }
+
+ @Override
+ public int size() {
+ return representations.size();
+ }
+
+ /**
+ * The model holding all query results
+ * @return
+ */
+ public Model getModel() {
+ return model;
+ }
+
+}
Added: stanbol/trunk/entityhub/yard/sesame/src/main/java/org/apache/stanbol/entityhub/yard/sesame/SesameYard.java
URL: http://svn.apache.org/viewvc/stanbol/trunk/entityhub/yard/sesame/src/main/java/org/apache/stanbol/entityhub/yard/sesame/SesameYard.java?rev=1531905&view=auto
==============================================================================
--- stanbol/trunk/entityhub/yard/sesame/src/main/java/org/apache/stanbol/entityhub/yard/sesame/SesameYard.java (added)
+++ stanbol/trunk/entityhub/yard/sesame/src/main/java/org/apache/stanbol/entityhub/yard/sesame/SesameYard.java Mon Oct 14 14:13:59 2013
@@ -0,0 +1,752 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.stanbol.entityhub.yard.sesame;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.Set;
+
+import org.apache.stanbol.entityhub.core.query.QueryResultListImpl;
+import org.apache.stanbol.entityhub.core.query.QueryUtils;
+import org.apache.stanbol.entityhub.core.yard.AbstractYard;
+import org.apache.stanbol.entityhub.model.sesame.RdfRepresentation;
+import org.apache.stanbol.entityhub.model.sesame.RdfValueFactory;
+import org.apache.stanbol.entityhub.query.sparql.SparqlEndpointTypeEnum;
+import org.apache.stanbol.entityhub.query.sparql.SparqlFieldQuery;
+import org.apache.stanbol.entityhub.query.sparql.SparqlFieldQueryFactory;
+import org.apache.stanbol.entityhub.query.sparql.SparqlQueryUtils;
+import org.apache.stanbol.entityhub.servicesapi.model.Representation;
+import org.apache.stanbol.entityhub.servicesapi.model.rdf.RdfResourceEnum;
+import org.apache.stanbol.entityhub.servicesapi.query.FieldQuery;
+import org.apache.stanbol.entityhub.servicesapi.query.QueryResultList;
+import org.apache.stanbol.entityhub.servicesapi.query.UnsupportedQueryTypeException;
+import org.apache.stanbol.entityhub.servicesapi.yard.Yard;
+import org.apache.stanbol.entityhub.servicesapi.yard.YardException;
+import org.openrdf.model.BNode;
+import org.openrdf.model.Model;
+import org.openrdf.model.Resource;
+import org.openrdf.model.Statement;
+import org.openrdf.model.URI;
+import org.openrdf.model.Value;
+import org.openrdf.model.ValueFactory;
+import org.openrdf.model.impl.TreeModel;
+import org.openrdf.query.BindingSet;
+import org.openrdf.query.Dataset;
+import org.openrdf.query.MalformedQueryException;
+import org.openrdf.query.QueryEvaluationException;
+import org.openrdf.query.QueryLanguage;
+import org.openrdf.query.TupleQuery;
+import org.openrdf.query.TupleQueryResult;
+import org.openrdf.query.impl.DatasetImpl;
+import org.openrdf.repository.Repository;
+import org.openrdf.repository.RepositoryConnection;
+import org.openrdf.repository.RepositoryException;
+import org.openrdf.repository.RepositoryResult;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+
+/**
+ * Implementation of the Yard Interface based on a Sesame {@link Repository}.
+ * <p>
+ * This is NOT an OSGI component nor service. It is intended to be used by
+ * Components that do allow users to configure a Repository implementation.
+ * Such components will than create a SesameYard instance and register it as
+ * a OSGI service.
+ *
+ * @author Rupert Westenthaler
+ *
+ */
+public class SesameYard extends AbstractYard implements Yard {
+ private static Logger log = LoggerFactory.getLogger(SesameYard.class);
+ /**
+ * Property used to mark empty Representations managed by this Graph. This is
+ * needed to workaround the fact, that the Entityhub supports the storage of
+ * empty Representations but this Yard uses the search for any outgoing
+ * relation (triple with the id of the representation as Subject) for the
+ * implementation of {@link #isRepresentation(String)}. Therefore for an
+ * empty Representation {@link #isRepresentation(String)} would return false
+ * even if the representation was {@link #store(Representation)} previously.
+ * <p>
+ * Adding the Triple<br>
+ * <code> ?representationId <{@value #MANAGED_REPRESENTATION}> true^^xsd:boolean </code>
+ * <br> for any empty Representation avoids this unwanted behaviour.
+ */
+ private static final String MANAGED_REPRESENTATION_URI = "urn:org.apache.stanbol:entityhub.yard:rdf.sesame:managesRepresentation";
+ /**
+ * used as property for a triple to ensure existence for representations that
+ * do not define yet any triples
+ */
+ private final URI managedRepresentation;
+ /**
+ * used as value for a triple to ensure existence for representations that
+ * do not define yet any triples
+ */
+ private final Value managedRepresentationState;
+ /**
+ * If inferred Triples are included in operations on this Yard.
+ */
+ public static final String INCLUDE_INFERRED = "org.apache.stanbol.entityhub.yard.sesame.includeInferred";
+ /**
+ * By default {@link #INCLUDE_INFERRED} is enabled.
+ */
+ public static final boolean DEFAULT_INCLUDE_INFERRED = true;
+ /**
+ * Property used to enable/disable Sesame Context. If <code>false</code> the
+ * {@link #CONTEXT_URI} property gets ignored. If <code>true</code> and
+ * {@link #CONTEXT_URI} is missing the default context (<code>null</code>) is
+ * used. Otherwise the contexts as configured for {@link #CONTEXT_URI} are
+ * used.
+ */
+ public static final String CONTEXT_ENABLED = "org.apache.stanbol.entityhub.yard.sesame.enableContext";
+ /**
+ * By default the {@link #CONTEXT_ENABLED} feature is disabled.
+ */
+ public static final boolean DEFAULT_CONTEXT_ENABLED = false;
+
+ /**
+ * Property used to optionally configure one or more context URIs. empty
+ * values are interpreted as <code>null</code>
+ */
+ public static final String CONTEXT_URI = "org.apache.stanbol.entityhub.yard.sesame.contextUri";
+
+ /**
+ * The context used by this yard
+ */
+ private final URI[] contexts;
+ private final Dataset dataset;
+ private boolean includeInferred;
+ private final Repository repository;
+ private final RdfValueFactory valueFactory;
+ private final ValueFactory sesameFactory;
+ private final SesameYardConfig config;
+
+ private final URI queryRoot;
+ private final URI queryResult;
+
+ public SesameYard(Repository repo, SesameYardConfig config) {
+ super();
+ this.repository = repo;
+ this.config = config;
+ this.sesameFactory = repo.getValueFactory();
+ this.valueFactory = new RdfValueFactory(null, sesameFactory);
+ this.managedRepresentation = sesameFactory.createURI(MANAGED_REPRESENTATION_URI);
+ this.managedRepresentationState = sesameFactory.createLiteral(true);
+ this.includeInferred = config.isIncludeInferred();
+ //init the super class
+ activate(this.valueFactory, SparqlFieldQueryFactory.getInstance(), config);
+ if(config.isContextEnabled()){
+ //Set the contexts
+ String[] contexts = config.getContexts();
+ this.contexts = new URI[contexts.length];
+ for(int i = 0; i < contexts.length; i++){
+ this.contexts[i] = contexts[i] == null ? null :
+ sesameFactory.createURI(contexts[i]);
+ }
+ } else {
+ this.contexts = new URI[]{};
+ }
+ //also init the dataset required for SPARQL queries
+ if(contexts.length > 0){
+ DatasetImpl dataset = new DatasetImpl();
+ for(URI context : this.contexts){
+ dataset.addNamedGraph(context);
+ dataset.addDefaultGraph(context);
+ }
+ this.dataset = dataset;
+ } else {
+ this.dataset = null;
+ }
+ queryRoot = sesameFactory.createURI(RdfResourceEnum.QueryResultSet.getUri());
+ queryResult = sesameFactory.createURI(RdfResourceEnum.queryResult.getUri());
+ }
+
+ /**
+ * Closes this Yard, but <b>does not</b> close the Sesame Repository!
+ */
+ public void close(){
+ //init the super class
+ deactivate();
+ }
+
+ /**
+ * Getter for the context URI used by this yard.
+ * @return the URI used for the RDF graph that stores all the data of this
+ * yard.
+ */
+ public final URI[] getContexts(){
+ return contexts;
+ }
+
+ @Override
+ public Representation getRepresentation(String id) throws YardException{
+ if(id == null){
+ throw new IllegalArgumentException("The parsed representation id MUST NOT be NULL!");
+ }
+ if(id.isEmpty()){
+ throw new IllegalArgumentException("The parsed representation id MUST NOT be EMTPY!");
+ }
+ RepositoryConnection con = null;
+ try {
+ con = repository.getConnection();
+ con.begin();
+ Representation rep = getRepresentation(con, sesameFactory.createURI(id), true);
+ con.commit();
+ return rep;
+ } catch (RepositoryException e) {
+ throw new YardException("Unable to get Representation "+id, e);
+ } finally {
+ if(con != null){
+ try {
+ con.close();
+ } catch (RepositoryException ignore) {}
+ }
+ }
+ }
+ /**
+ * Internally used to create Representations for URIs
+ * @param uri the uri
+ * @param check if <code>false</code> than there is no check if the URI
+ * refers to a Resource in the graph that is of type {@link #REPRESENTATION}
+ * @return the Representation
+ */
+ protected final Representation getRepresentation(RepositoryConnection con, URI uri, boolean check) throws RepositoryException {
+ if(!check || isRepresentation(con,uri)){
+ return createRepresentationGraph(con,uri);
+ } else {
+ return null; //not found
+ }
+ }
+
+ /**
+ * Extracts the triples that belong to the {@link Representation} with the
+ * parsed id from the Sesame repository.
+ * @param con the repository connection
+ * @param uri the subject of the Representation to extract
+ * @return the representation with the extracted data.
+ * @throws RepositoryException
+ */
+ protected RdfRepresentation createRepresentationGraph(RepositoryConnection con, URI uri) throws RepositoryException{
+ RdfRepresentation rep = valueFactory.createRdfRepresentation(uri);
+ Model model = rep.getModel();
+ extractRepresentation(con, model, uri, new HashSet<BNode>());
+ return rep;
+ }
+ /**
+ * Recursive Method internally doing all the work for
+ * {@link #createRepresentationGraph(UriRef, TripleCollection)}
+ * @param con the repository connection to read the data from
+ * @param model The model to add the statements retrieved
+ * @param node the current node. Changes in recursive calls as it follows
+ * @param visited holding all the visited BNodes to avoid cycles. Other nodes
+ * need not be added because this implementation would not follow it anyway
+ * outgoing relations if the object is a {@link BNode} instance.
+ * @throws RepositoryException
+ */
+ private void extractRepresentation(RepositoryConnection con,Model model, Resource node, Set<BNode> visited) throws RepositoryException{
+ //we need all the outgoing relations and also want to follow bNodes until
+ //the next UriRef. However we are not interested in incoming relations!
+ RepositoryResult<Statement> outgoing = con.getStatements(node, null, null, includeInferred, contexts);
+ Statement statement;
+ Set<BNode> bnodes = new HashSet<BNode>();
+ while(outgoing.hasNext()){
+ statement = outgoing.next();
+ model.add(statement);
+ Value object = statement.getObject();
+ if(object instanceof BNode && visited.contains(object)){
+ bnodes.add((BNode)object);
+ }
+ }
+ outgoing.close();
+ for(BNode bnode : bnodes){
+ visited.add(bnode);
+ //TODO: recursive calls could cause stackoverflows with wired graphs
+ extractRepresentation(con, model, bnode, visited);
+ }
+ }
+
+ @Override
+ public boolean isRepresentation(String id) throws YardException {
+ if(id == null) {
+ throw new IllegalArgumentException("The parsed id MUST NOT be NULL!");
+ }
+ if(id.isEmpty()){
+ throw new IllegalArgumentException("The parsed id MUST NOT be EMPTY!");
+ }
+ RepositoryConnection con = null;
+ try {
+ con = repository.getConnection();
+ con.begin();
+ boolean state = isRepresentation(con, sesameFactory.createURI(id));
+ con.commit();
+ return state;
+ } catch (RepositoryException e) {
+ throw new YardException("Unable to check for Representation "+id, e);
+ } finally {
+ if(con != null){
+ try {
+ con.close();
+ } catch (RepositoryException ignore) {}
+ }
+ }
+ }
+ /**
+ * Internally used to check if a URI resource represents an representation
+ * @param con the repository connection
+ * @param subject the subject URI of the representation to check
+ * @return the state
+ * @throws RepositoryException
+ */
+ protected final boolean isRepresentation(RepositoryConnection con , URI subject) throws RepositoryException{
+ return con.hasStatement(subject, null, null, includeInferred, contexts);
+ }
+
+ @Override
+ public void remove(String id) throws YardException, IllegalArgumentException {
+ if(id == null) {
+ throw new IllegalArgumentException("The parsed Representation id MUST NOT be NULL!");
+ }
+ RepositoryConnection con = null;
+ try {
+ con = repository.getConnection();
+ con.begin();
+ remove(con, sesameFactory.createURI(id));
+ con.commit();
+ } catch (RepositoryException e) {
+ throw new YardException("Unable to remove for Representation "+id, e);
+ } finally {
+ if(con != null){
+ try {
+ con.close();
+ } catch (RepositoryException ignore) {}
+ }
+ }
+ }
+ /**
+ * Internally used to remove a Representation from the Repository. <p>
+ * NOTE: this does not remove any {@link Statement}s for {@link BNode}s
+ * beeing {@link Statement#getObject() object}s of the parsed subjects.
+ * @param con the connection
+ * @param subject the subject of the Representation to remove
+ * @throws RepositoryException
+ */
+ protected void remove(RepositoryConnection con, URI subject) throws RepositoryException{
+ con.remove(subject, null, null, contexts);
+ }
+
+ @Override
+ public final void remove(Iterable<String> ids) throws IllegalArgumentException, YardException {
+ if(ids == null){
+ throw new IllegalArgumentException("The parsed Iterable over the IDs to remove MUST NOT be NULL!");
+ }
+ RepositoryConnection con = null;
+ try {
+ con = repository.getConnection();
+ con.begin();
+ for(String id : ids){
+ if(id != null){
+ remove(con, sesameFactory.createURI(id));
+ }
+ }
+ con.commit();
+ } catch (RepositoryException e) {
+ throw new YardException("Unable to remove parsed Representations", e);
+ } finally {
+ if(con != null){
+ try {
+ con.close();
+ } catch (RepositoryException ignore) {}
+ }
+ }
+ }
+ @Override
+ public final void removeAll() throws YardException {
+ RepositoryConnection con = null;
+ try {
+ con = repository.getConnection();
+ con.begin();
+ con.clear(contexts); //removes everything
+ con.commit();
+ } catch (RepositoryException e) {
+ throw new YardException("Unable to remove parsed Representations", e);
+ } finally {
+ if(con != null){
+ try {
+ con.close();
+ } catch (RepositoryException ignore) {}
+ }
+ }
+ }
+ @Override
+ public final Representation store(Representation representation) throws IllegalArgumentException, YardException {
+ if(representation == null){
+ throw new IllegalArgumentException("The parsed Representation MUST NOT be NULL!");
+ }
+ return store(representation,true,true);
+ }
+ @Override
+ public final Iterable<Representation> store(Iterable<Representation> representations) throws IllegalArgumentException, YardException {
+ if(representations == null){
+ throw new IllegalArgumentException("The parsed Iterable over the Representations to store MUST NOT be NULL!");
+ }
+ return store(representations, true);
+ }
+ @Override
+ public final Representation update(Representation representation) throws IllegalArgumentException, YardException {
+ if(representation == null){
+ throw new IllegalArgumentException("The parsed Representation MUST NOT be NULL!");
+ }
+ return store(representation,false,true);
+ }
+ @Override
+ public final Iterable<Representation> update(Iterable<Representation> representations) throws YardException, IllegalArgumentException {
+ if(representations == null){
+ throw new IllegalArgumentException("The parsed Iterable over the Representations to update MUST NOT be NULL!");
+ }
+ return store(representations,false);
+ }
+ protected final Iterable<Representation> store(Iterable<Representation> representations,boolean allowCreate) throws IllegalArgumentException, YardException{
+ RepositoryConnection con = null;
+ try {
+ con = repository.getConnection();
+ con.begin();
+ ArrayList<Representation> added = new ArrayList<Representation>();
+ for(Representation representation : representations){
+ if(representation != null){
+ Representation stored = store(con, representation,allowCreate,false); //reassign
+ //to check if the store was successful
+ if(stored != null){
+ added.add(stored);
+ } else { //can only be the case if allowCreate==false (update was called)
+ log.warn(String.format("Unable to update Representation %s in Yard %s because it is not present!",
+ representation.getId(),getId()));
+ }
+ } //ignore null values in the parsed Iterable!
+ }
+ con.commit();
+ return added;
+ } catch (RepositoryException e) {
+ throw new YardException("Unable to remove parsed Representations", e);
+ } catch (IllegalArgumentException e) {
+ try {
+ //to avoid Exception logs in case store(..) throws an Exception
+ //in the case allowCreate and canNotCreateIsError do not allow
+ //the store operation
+ con.rollback();
+ } catch (RepositoryException ignore) {}
+ throw e;
+ } finally {
+ if(con != null){
+ try {
+ con.close();
+ } catch (RepositoryException ignore) {}
+ }
+ }
+ }
+ /**
+ * Generic store method used by store and update methods
+ * @param representation the representation to store/update
+ * @param allowCreate if new representation are allowed to be created
+ * @param canNotCreateIsError if updates to existing one are allowed
+ * @return the representation as added to the yard
+ * @throws IllegalArgumentException
+ * @throws YardException
+ */
+ protected final Representation store(Representation representation,boolean allowCreate,boolean canNotCreateIsError) throws IllegalArgumentException, YardException{
+ RepositoryConnection con = null;
+ try {
+ con = repository.getConnection();
+ con.begin();
+ Representation added = store(con,representation,allowCreate,canNotCreateIsError);
+ con.commit();
+ return added;
+ } catch (RepositoryException e) {
+ throw new YardException("Unable to remove parsed Representations", e);
+ } catch (IllegalArgumentException e) {
+ try {
+ //to avoid Exception logs in case store(..) throws an Exception
+ //in the case allowCreate and canNotCreateIsError do not allow
+ //the store operation
+ con.rollback();
+ } catch (RepositoryException ignore) {}
+ throw e;
+ } finally {
+ if(con != null){
+ try {
+ con.close();
+ } catch (RepositoryException ignore) {}
+ }
+ }
+ }
+ protected final Representation store(RepositoryConnection con, Representation representation,boolean allowCreate,boolean canNotCreateIsError) throws IllegalArgumentException, RepositoryException {
+ if(representation == null) {
+ return null;
+ }
+ log.debug("store Representation " + representation.getId());
+ URI subject = sesameFactory.createURI(representation.getId());
+ boolean contains = con.hasStatement(subject, null, null, includeInferred, contexts);
+ con.remove(subject, null, null, contexts);
+ if(!contains && !allowCreate){
+ if(canNotCreateIsError) {
+ throw new IllegalArgumentException("Parsed Representation "+representation.getId()+" in not managed by this Yard "+getName()+"(id="+getId()+")");
+ } else {
+ return null;
+ }
+ }
+ //get the graph for the Representation and add it to the store
+ RdfRepresentation toAdd = valueFactory.toRdfRepresentation(representation);
+ if(toAdd.getModel().isEmpty()){
+ con.add(toAdd.getURI(),managedRepresentation,managedRepresentationState, contexts);
+ } else {
+ con.add(toAdd.getModel(), contexts);
+ }
+ return toAdd;
+ }
+
+ @Override
+ public QueryResultList<String> findReferences(FieldQuery parsedQuery) throws YardException, IllegalArgumentException {
+ if(parsedQuery == null){
+ throw new IllegalArgumentException("The parsed query MUST NOT be NULL!");
+ }
+ final SparqlFieldQuery query = SparqlFieldQueryFactory.getSparqlFieldQuery(parsedQuery);
+ RepositoryConnection con = null;
+ TupleQueryResult results = null;
+ try {
+ con = repository.getConnection();
+ con.begin();
+ //execute the query
+ int limit = QueryUtils.getLimit(query, config.getDefaultQueryResultNumber(),
+ config.getMaxQueryResultNumber());
+ results = executeSparqlFieldQuery(con, query, limit, false);
+ //parse the results
+ List<String> ids = new ArrayList<String>(limit);
+ while(results.hasNext()){
+ BindingSet result = results.next();
+ Value value = result.getValue(query.getRootVariableName());
+ if(value instanceof Resource){
+ ids.add(value.stringValue());
+ }
+ }
+ con.commit();
+ return new QueryResultListImpl<String>(query,ids,String.class);
+ } catch (RepositoryException e) {
+ throw new YardException("Unable to execute findReferences query", e);
+ } catch (QueryEvaluationException e) {
+ throw new YardException("Unable to execute findReferences query", e);
+ } finally {
+ if(results != null) { //close the result if present
+ try {
+ results.close();
+ } catch (QueryEvaluationException ignore) {/* ignore */}
+ }
+ if(con != null){
+ try {
+ con.close();
+ } catch (RepositoryException ignore) {/* ignore */}
+ }
+ }
+ }
+
+ /**
+ * Returns the SPARQL result set for a given {@link SparqlFieldQuery} that
+ * was executed on this yard
+ * @param con the repository connection to use
+ * @param fieldQuery the SparqlFieldQuery instance
+ * @param limit the maximum number of results
+ * @return the results of the SPARQL query in the {@link #contexts} of the
+ * Sesame Repository
+ * @throws RepositoryException on any error while using the parsed connection
+ * @throws QueryEvaluationException on any error while executing the query
+ * @throws YardException if the SPARQL query created for the parsed FieldQuery
+ * was illegal formatted or if the {@link #repository} does not support
+ * SPARQL.
+ */
+ private TupleQueryResult executeSparqlFieldQuery(RepositoryConnection con, final SparqlFieldQuery fieldQuery, int limit, boolean select) throws RepositoryException, YardException, QueryEvaluationException {
+ String sparqlQueryString = SparqlQueryUtils.createSparqlSelectQuery(
+ fieldQuery, select,limit,SparqlEndpointTypeEnum.Sesame);
+ TupleQuery sparqlOuery;
+ try {
+ sparqlOuery = con.prepareTupleQuery(QueryLanguage.SPARQL, sparqlQueryString);
+ } catch (MalformedQueryException e) {
+ log.error("Unable to pparse SPARQL Query generated for a FieldQuery");
+ log.error("FieldQuery: {}",fieldQuery);
+ log.error("SPARQL Query: {}",sparqlQueryString);
+ log.error("Exception ", e);
+ throw new YardException("Unable to parse SPARQL query generated for the parse FieldQuery", e);
+ } catch (UnsupportedQueryTypeException e) {
+ String message = "The Sesame Repository '" + repository + "'(class: "
+ + repository.getClass().getName() + ") does not support SPARQL!";
+ log.error(message, e);
+ throw new YardException(message, e);
+ }
+ if(dataset != null){ //respect the configured contexts
+ sparqlOuery.setDataset(dataset);
+ }
+ return sparqlOuery.evaluate();
+ }
+
+ @Override
+ public QueryResultList<Representation> findRepresentation(FieldQuery parsedQuery) throws YardException, IllegalArgumentException {
+ if(parsedQuery == null){
+ throw new IllegalArgumentException("The parsed query MUST NOT be NULL!");
+ }
+ final SparqlFieldQuery query = SparqlFieldQueryFactory.getSparqlFieldQuery(parsedQuery);
+ RepositoryConnection con = null;
+ TupleQueryResult results = null;
+ try {
+ con = repository.getConnection();
+ con.begin();
+ //execute the query
+ int limit = QueryUtils.getLimit(query, config.getDefaultQueryResultNumber(),
+ config.getMaxQueryResultNumber());
+ results = executeSparqlFieldQuery(con,query, limit, false);
+ //parse the results and generate the Representations
+ //create an own valueFactors so that all the data of the query results
+ //are added to the same Sesame Model
+ Model model = new TreeModel();
+ RdfValueFactory valueFactory = new RdfValueFactory(model, sesameFactory);
+ List<Representation> representations = new ArrayList<Representation>(limit);
+ while(results.hasNext()){
+ BindingSet result = results.next();
+ Value value = result.getValue(query.getRootVariableName());
+ if(value instanceof URI){
+ createRepresentationGraph(con, (URI)value); //copy all data to the model
+ model.add(queryRoot, queryResult, value); //link the result with the query result
+ representations.add(valueFactory.createRdfRepresentation((URI)value));
+ } //ignore non URI results
+ }
+ con.commit();
+ return new SesameQueryResultList(model, query, representations);
+ } catch (RepositoryException e) {
+ throw new YardException("Unable to execute findReferences query", e);
+ } catch (QueryEvaluationException e) {
+ throw new YardException("Unable to execute findReferences query", e);
+ } finally {
+ if(results != null) { //close the result if present
+ try {
+ results.close();
+ } catch (QueryEvaluationException ignore) {/* ignore */}
+ }
+ if(con != null){
+ try {
+ con.close();
+ } catch (RepositoryException ignore) {/* ignore */}
+ }
+ }
+ }
+ @Override
+ public final QueryResultList<Representation> find(FieldQuery parsedQuery) throws YardException, IllegalArgumentException {
+ if(parsedQuery == null){
+ throw new IllegalArgumentException("The parsed query MUST NOT be NULL!");
+ }
+ final SparqlFieldQuery query = SparqlFieldQueryFactory.getSparqlFieldQuery(parsedQuery);
+ RepositoryConnection con = null;
+ TupleQueryResult results = null;
+ try {
+ con = repository.getConnection();
+ con.begin();
+ //execute the query
+ int limit = QueryUtils.getLimit(query, config.getDefaultQueryResultNumber(),
+ config.getMaxQueryResultNumber());
+ results = executeSparqlFieldQuery(con,query, limit, true);
+ //parse the results and generate the Representations
+ //create an own valueFactors so that all the data of the query results
+ //are added to the same Sesame Model
+ Model model = new TreeModel();
+ List<Representation> representations = new ArrayList<Representation>(limit);
+ Map<String,URI> bindings = new HashMap<String,URI>(query.getFieldVariableMappings().size());
+ for(Entry<String,String> mapping : query.getFieldVariableMappings().entrySet()){
+ bindings.put(mapping.getValue(), sesameFactory.createURI(mapping.getKey()));
+ }
+ while(results.hasNext()){
+ BindingSet result = results.next();
+ Value value = result.getValue(query.getRootVariableName());
+ if(value instanceof URI){
+ URI subject = (URI) value;
+ //link the result with the query result
+ model.add(queryRoot, queryResult, subject);
+ //now copy over the other selected data
+ for(String binding : result.getBindingNames()){
+ URI property = bindings.get(binding);
+ if(property != null){
+ model.add(subject, property, value);
+ } //else no mapping for the query.getRootVariableName()
+ }
+ } //ignore non URI results
+ }
+ con.commit();
+ return new SesameQueryResultList(model, query, representations);
+ } catch (RepositoryException e) {
+ throw new YardException("Unable to execute findReferences query", e);
+ } catch (QueryEvaluationException e) {
+ throw new YardException("Unable to execute findReferences query", e);
+ } finally {
+ if(results != null) { //close the result if present
+ try {
+ results.close();
+ } catch (QueryEvaluationException ignore) {/* ignore */}
+ }
+ if(con != null){
+ try {
+ con.close();
+ } catch (RepositoryException ignore) {/* ignore */}
+ }
+ }
+ }
+ /**
+ * Wrapper that converts a Sesame {@link TupleQueryResult} to a {@link Iterator}.
+ * <b>NOTE</b> this will not close the {@link TupleQueryResult}!
+ * @author Rupert westenthaler
+ *
+ */
+ static class TupleResultIterator implements Iterator<BindingSet> {
+
+ private final TupleQueryResult resultList;
+
+ public TupleResultIterator(TupleQueryResult resultList) {
+ this.resultList = resultList;
+ }
+ @Override
+ public boolean hasNext() {
+ try {
+ return resultList.hasNext();
+ } catch (QueryEvaluationException e) {
+ throw new IllegalStateException(e);
+ }
+ }
+
+ @Override
+ public BindingSet next() {
+ try {
+ return resultList.next();
+ } catch (QueryEvaluationException e) {
+ throw new IllegalStateException(e);
+ }
+ }
+
+ @Override
+ public void remove() {
+ throw new UnsupportedOperationException("Remove is not supported by Sesame TupleQueryResult");
+ }
+
+ }
+}
Added: stanbol/trunk/entityhub/yard/sesame/src/main/java/org/apache/stanbol/entityhub/yard/sesame/SesameYardConfig.java
URL: http://svn.apache.org/viewvc/stanbol/trunk/entityhub/yard/sesame/src/main/java/org/apache/stanbol/entityhub/yard/sesame/SesameYardConfig.java?rev=1531905&view=auto
==============================================================================
--- stanbol/trunk/entityhub/yard/sesame/src/main/java/org/apache/stanbol/entityhub/yard/sesame/SesameYardConfig.java (added)
+++ stanbol/trunk/entityhub/yard/sesame/src/main/java/org/apache/stanbol/entityhub/yard/sesame/SesameYardConfig.java Mon Oct 14 14:13:59 2013
@@ -0,0 +1,154 @@
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements. See the NOTICE file distributed with
+* this work for additional information regarding copyright ownership.
+* The ASF licenses this file to You under the Apache License, Version 2.0
+* (the "License"); you may not use this file except in compliance with
+* the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+package org.apache.stanbol.entityhub.yard.sesame;
+
+import java.util.Dictionary;
+import java.util.HashSet;
+import java.util.Set;
+
+import org.apache.stanbol.entityhub.core.yard.AbstractYard.YardConfig;
+import org.osgi.service.cm.ConfigurationException;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class SesameYardConfig extends YardConfig {
+
+ private final Logger log = LoggerFactory.getLogger(SesameYardConfig.class);
+
+
+ public SesameYardConfig(String id) throws IllegalArgumentException {
+ super(id);
+ }
+ public SesameYardConfig(Dictionary<String,Object> config) throws ConfigurationException, IllegalArgumentException {
+ super(config);
+ }
+ /**
+ * Getter for the {@link SesameYard#CONTEXT_ENABLED} state
+ * @return the state or the {@link SesameYard#DEFAULT_CONTEXT_ENABLED default}
+ * if not present in the config.
+ */
+ public boolean isContextEnabled(){
+ Object value = config.get(SesameYard.CONTEXT_ENABLED);
+ if(value instanceof Boolean){
+ return ((Boolean)value).booleanValue();
+ } else if(value != null){
+ return Boolean.parseBoolean(value.toString());
+ } else {
+ return SesameYard.DEFAULT_CONTEXT_ENABLED;
+ }
+ }
+ /**
+ * Setter for the {@link SesameYard#CONTEXT_ENABLED} state
+ * @param state the state or <code>null</code> to remove the config (reset to
+ * the {@link SesameYard#DEFAULT_CONTEXT_ENABLED default})
+ */
+ public void setContextEnabled(Boolean state){
+ if(state != null){
+ config.put(SesameYard.CONTEXT_ENABLED, state);
+ } else {
+ config.remove(SesameYard.CONTEXT_ENABLED);
+ }
+ }
+
+ /**
+ * Setter for the Contexts
+ * @param contexts
+ */
+ public void setContexts(String[] contexts){
+ if(contexts == null){
+ config.remove(SesameYard.CONTEXT_URI);
+ } else {
+ config.put(SesameYard.CONTEXT_URI, contexts);
+ }
+ }
+
+ /**
+ * Getter for the {@link SesameYard#CONTEXT_URI} property.
+ * @return the contexts or an empty array if none
+ */
+ public String[] getContexts(){
+ Object value = config.get(SesameYard.CONTEXT_URI);
+ Set<String> values = null;
+ if(value instanceof String){
+ String str = ((String)value).trim();
+ return new String[]{str.isEmpty() ? null : str};
+ } else if (value == null){
+ return new String[]{};
+ } else if(value instanceof String[]){
+ values = new HashSet<String>(((String[])value).length);
+ for(String str : (String[])value){
+ str = str != null ? str.trim() : str;
+ values.add(str.isEmpty() ? null : str);
+ }
+ } else if(value instanceof Iterable<?>){
+ values = new HashSet<String>(((String[])value).length);
+ for(Object o : (String[])value){
+ if(o == null){
+ values.add(null);
+ } else {
+ String str = o.toString().trim();
+ values.add(str.isEmpty() ? null : str);
+ }
+ }
+ } else {
+ log.warn("Illegal '{}' value '{}' (type: '{}')! Supported: String, String[] and Iterables",
+ new Object[]{SesameYard.CONTEXT_URI, value, value.getClass()});
+ log.warn(" ... return empty context array as fallback!");
+ return new String[]{};
+ }
+ return values.toArray(new String[values.size()]);
+ }
+ /**
+ * Setter for the {@link SesameYard#INCLUDE_INFERRED} state
+ * @param state the state or <code>null</code> to remove the config (reset to
+ * the {@link SesameYard#DEFAULT_INCLUDE_INFERRED default})
+ */
+ public void setIncludeInferred(Boolean state){
+ if(state == null){
+ config.remove(SesameYard.INCLUDE_INFERRED);
+ } else {
+ config.put(SesameYard.INCLUDE_INFERRED, state);
+ }
+ }
+ /**
+ * Getter for the {@link SesameYard#INCLUDE_INFERRED} state.
+ * @return the state or {@link SesameYard#DEFAULT_INCLUDE_INFERRED} if not
+ * present in the configuration.
+ */
+ public boolean isIncludeInferred(){
+ Object value = config.get(SesameYard.INCLUDE_INFERRED);
+ if(value instanceof Boolean){
+ return ((Boolean)value).booleanValue();
+ } else if(value != null){
+ return Boolean.parseBoolean(value.toString());
+ } else {
+ return SesameYard.DEFAULT_INCLUDE_INFERRED;
+ }
+ }
+
+ @Override
+ protected void validateConfig() throws ConfigurationException {
+ Object value = config.get(SesameYard.CONTEXT_URI);
+ if(!(value == null || value instanceof String || value instanceof String[]
+ || value instanceof Iterable<?>)){
+ throw new ConfigurationException(SesameYard.CONTEXT_URI, String.format(
+ "Illegal '%s' value '%s' (type: '%s')! Supported: String, String[] and Iterables",
+ SesameYard.CONTEXT_URI, value, value.getClass()));
+ }
+ }
+
+}
Added: stanbol/trunk/entityhub/yard/sesame/src/test/java/org/apache/stanbol/entityhub/yard/sesame/SesameContextTest.java
URL: http://svn.apache.org/viewvc/stanbol/trunk/entityhub/yard/sesame/src/test/java/org/apache/stanbol/entityhub/yard/sesame/SesameContextTest.java?rev=1531905&view=auto
==============================================================================
--- stanbol/trunk/entityhub/yard/sesame/src/test/java/org/apache/stanbol/entityhub/yard/sesame/SesameContextTest.java (added)
+++ stanbol/trunk/entityhub/yard/sesame/src/test/java/org/apache/stanbol/entityhub/yard/sesame/SesameContextTest.java Mon Oct 14 14:13:59 2013
@@ -0,0 +1,183 @@
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements. See the NOTICE file distributed with
+* this work for additional information regarding copyright ownership.
+* The ASF licenses this file to You under the Apache License, Version 2.0
+* (the "License"); you may not use this file except in compliance with
+* the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+package org.apache.stanbol.entityhub.yard.sesame;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+
+import org.junit.Assert;
+
+import org.apache.stanbol.entityhub.model.sesame.RdfRepresentation;
+import org.apache.stanbol.entityhub.model.sesame.RdfValueFactory;
+import org.apache.stanbol.entityhub.servicesapi.defaults.NamespaceEnum;
+import org.apache.stanbol.entityhub.servicesapi.model.Representation;
+import org.apache.stanbol.entityhub.servicesapi.yard.Yard;
+import org.apache.stanbol.entityhub.servicesapi.yard.YardException;
+import org.apache.stanbol.entityhub.yard.sesame.SesameYard;
+import org.apache.stanbol.entityhub.yard.sesame.SesameYardConfig;
+import org.junit.AfterClass;
+import org.junit.BeforeClass;
+import org.junit.Test;
+import org.openrdf.model.URI;
+import org.openrdf.model.ValueFactory;
+import org.openrdf.repository.Repository;
+import org.openrdf.repository.RepositoryConnection;
+import org.openrdf.repository.RepositoryException;
+import org.openrdf.repository.sail.SailRepository;
+import org.openrdf.sail.memory.MemoryStore;
+
+/**
+ * Unit tests for testing {@link SesameYard} that do use contexts
+ *
+ * @author Rupert Westenthaler
+ *
+ */
+public class SesameContextTest {
+
+ private static Repository repo = new SailRepository(new MemoryStore());
+ private static ValueFactory sesameFactory = repo.getValueFactory();
+ private static String EN = "en";
+ private static String DE = "de";
+ private static final Map<URI,List<? extends Yard>> expectedEntities = new HashMap<URI,List<? extends Yard>>();
+
+ private static URI rdfType = sesameFactory.createURI(NamespaceEnum.rdf+"type");
+ private static URI skosConcept = sesameFactory.createURI(NamespaceEnum.skos+"Concept");
+ private static URI skosPrefLabel = sesameFactory.createURI(NamespaceEnum.skos+"preLabel");
+
+ private static URI CONTEXT1 = sesameFactory.createURI("http://www.test.org/contex1");
+ private static URI CONTEXT2 = sesameFactory.createURI("http://www.test.org/contex2");
+
+ private static SesameYard yard1;
+ private static SesameYard yard2;
+ private static SesameYard unionYard;
+ private static List<SesameYard> yards;
+
+ @BeforeClass
+ public static final void initYard() throws RepositoryException{
+ repo.initialize();
+ //create the graphs in Clerezza
+
+ //init the ClerezzaYards for the created Clerezza graphs
+ SesameYardConfig yard1config = new SesameYardConfig("context 1 yard");
+ yard1config.setName("Yard over context 1");
+ yard1config.setContextEnabled(true);
+ yard1config.setContexts(new String[]{CONTEXT1.stringValue()});
+ yard1 = new SesameYard(repo,yard1config);
+
+ SesameYardConfig yard2config = new SesameYardConfig("context 2 yard");
+ yard2config.setName("Yard over context 2");
+ yard2config.setContextEnabled(true);
+ yard2config.setContexts(new String[]{CONTEXT2.stringValue()});
+ yard2 = new SesameYard(repo,yard2config);
+
+ SesameYardConfig unionYardConfig = new SesameYardConfig("union yard");
+ unionYardConfig.setName("Union Yard");
+ unionYard = new SesameYard(repo, unionYardConfig);
+
+ yards = Arrays.asList(yard1,yard2,unionYard);
+
+ //add the test data (to the Repository to also test pre-existing data)
+ RepositoryConnection con = repo.getConnection();
+ con.begin();
+ URI entity1 = sesameFactory.createURI("http://www.test.org/entity1");
+ con.add(entity1,rdfType,skosConcept,CONTEXT1);
+ con.add(entity1,skosPrefLabel,sesameFactory.createLiteral("test context one", EN),CONTEXT1);
+ con.add(entity1,skosPrefLabel,sesameFactory.createLiteral("Test Context Eins", DE),CONTEXT1);
+ expectedEntities.put(entity1, Arrays.asList(yard1,unionYard));
+
+ URI entity2 = sesameFactory.createURI("http://www.test.org/entity2");
+ con.add(entity2,rdfType,skosConcept,CONTEXT2);
+ con.add(entity2,skosPrefLabel,sesameFactory.createLiteral("test context two", EN),CONTEXT2);
+ con.add(entity2,skosPrefLabel,sesameFactory.createLiteral("Test Context Zwei", DE),CONTEXT2);
+ expectedEntities.put(entity2, Arrays.asList(yard2,unionYard));
+ con.commit();
+ con.close();
+ }
+ /**
+ * Checks the expected visibility of Entities to the different yards
+ * @throws YardException
+ */
+ @Test
+ public void testRetrival() throws YardException{
+ for(Entry<URI,List<? extends Yard>> entry : expectedEntities.entrySet()){
+ for(Yard yard : yards){
+ if(entry.getValue().contains(yard)){
+ validateEntity(yard, entry.getKey());
+ } else {
+ Assert.assertFalse("Entity "+entry.getKey()
+ + " is not expected in Yard " + yard.getName() + "!",
+ yard.isRepresentation(entry.getKey().stringValue()));
+ }
+ }
+ }
+ }
+ /**
+ * Test visibility of Entities added to specific contexts
+ * @throws YardException
+ */
+ @Test
+ public void testStoreToContextEnabledYard() throws YardException{
+ //add a new entity to yard 2
+ String context2added = "http://www.test.org/addedEntity";
+ Representation rep = RdfValueFactory.getInstance().createRepresentation(
+ context2added);
+ rep.addReference(rdfType.stringValue(), skosConcept.stringValue());
+ rep.addNaturalText(skosPrefLabel.stringValue(), "added Entity", "en");
+ rep.addNaturalText(skosPrefLabel.stringValue(), "hinzugefüte Entity", "de");
+ yard2.store(rep);
+ //test visibility to other yards
+ Assert.assertFalse(yard1.isRepresentation(context2added));
+ Assert.assertTrue(yard2.isRepresentation(context2added));
+ Assert.assertTrue(unionYard.isRepresentation(context2added));
+ //remove it and test again
+ yard2.remove(context2added);
+ Assert.assertFalse(yard1.isRepresentation(context2added));
+ Assert.assertFalse(yard2.isRepresentation(context2added));
+ Assert.assertFalse(unionYard.isRepresentation(context2added));
+ }
+
+ /**
+ * Used by {@link #testRetrival()} to validate that an Entity is correctly
+ * retrieved by the tested {@link SesameYard}s.
+ * @param entity key - URI; value - expected RDF data
+ * @throws YardException
+ */
+ private void validateEntity(Yard yard, URI subject) throws YardException {
+ Representation rep = yard.getRepresentation(subject.stringValue());
+ assertNotNull("The Representation for "+subject
+ + "is missing in the "+yard.getId(), rep);
+ assertTrue("RdfRepresentation expected", rep instanceof RdfRepresentation);
+ //check the RDF type to validate that some data are present
+ assertEquals(skosConcept.stringValue(), rep.getFirstReference(rdfType.stringValue()).getReference());
+ }
+
+
+ @AfterClass
+ public static void cleanup() throws RepositoryException{
+ for(SesameYard yard : yards){
+ yard.close();
+ }
+ repo.shutDown();
+ }
+}
Added: stanbol/trunk/entityhub/yard/sesame/src/test/java/org/apache/stanbol/entityhub/yard/sesame/SesameYardTest.java
URL: http://svn.apache.org/viewvc/stanbol/trunk/entityhub/yard/sesame/src/test/java/org/apache/stanbol/entityhub/yard/sesame/SesameYardTest.java?rev=1531905&view=auto
==============================================================================
--- stanbol/trunk/entityhub/yard/sesame/src/test/java/org/apache/stanbol/entityhub/yard/sesame/SesameYardTest.java (added)
+++ stanbol/trunk/entityhub/yard/sesame/src/test/java/org/apache/stanbol/entityhub/yard/sesame/SesameYardTest.java Mon Oct 14 14:13:59 2013
@@ -0,0 +1,96 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.stanbol.entityhub.yard.sesame;
+
+import org.junit.Assert;
+
+import org.apache.stanbol.entityhub.servicesapi.defaults.NamespaceEnum;
+import org.apache.stanbol.entityhub.servicesapi.model.Reference;
+import org.apache.stanbol.entityhub.servicesapi.model.Representation;
+import org.apache.stanbol.entityhub.servicesapi.model.ValueFactory;
+import org.apache.stanbol.entityhub.servicesapi.model.rdf.RdfResourceEnum;
+import org.apache.stanbol.entityhub.servicesapi.yard.Yard;
+import org.apache.stanbol.entityhub.servicesapi.yard.YardException;
+import org.apache.stanbol.entityhub.test.yard.YardTest;
+import org.apache.stanbol.entityhub.yard.sesame.SesameYard;
+import org.apache.stanbol.entityhub.yard.sesame.SesameYardConfig;
+import org.junit.AfterClass;
+import org.junit.BeforeClass;
+import org.junit.Test;
+import org.openrdf.repository.RepositoryException;
+import org.openrdf.repository.sail.SailRepository;
+import org.openrdf.sail.memory.MemoryStore;
+
+public class SesameYardTest extends YardTest {
+
+ private static SailRepository repo;
+ private static SesameYard yard;
+
+ @BeforeClass
+ public static final void initYard() throws RepositoryException{
+ SesameYardConfig config = new SesameYardConfig("testYardId");
+ config.setName("Sesame Yard Test");
+ config.setDescription("The Sesame Yard instance used to execute the Unit Tests defined for the Yard Interface");
+ repo = new SailRepository(new MemoryStore());
+ repo.initialize();
+ yard = new SesameYard(repo,config);
+ }
+
+ @Override
+ protected Yard getYard() {
+ return yard;
+ }
+
+ /**
+ * The Clerezza Yard uses the Statement<br>
+ * <code>representationId -> rdf:type -> Representation</code><br>
+ * to identify that an UriRef in the RDF graph (MGraph) represents a
+ * Representation. This Triple is added when a Representation is stored and
+ * removed if retrieved from the Yard.<p>
+ * This tests if this functions as expected
+ * @throws YardException
+ */
+ @Test
+ public void testRemovalOfTypeRepresentationStatement() throws YardException {
+ Yard yard = getYard();
+ ValueFactory vf = yard.getValueFactory();
+ Reference representationType = vf.createReference(RdfResourceEnum.Representation.getUri());
+ Representation test = create();
+ //the rdf:type Representation MUST NOT be within the Representation
+ Assert.assertFalse(test.get(NamespaceEnum.rdf+"type").hasNext());
+ //now add the statement and see if an IllegalStateException is thrown
+ /*
+ * The triple within this Statement is internally used to "mark" the
+ * URI of the Representation as
+ */
+ test.add(NamespaceEnum.rdf+"type", representationType);
+ }
+ /**
+ * This Method removes all Representations create via {@link #create()} or
+ * {@link #create(String, boolean)} from the tested {@link Yard}.
+ * It also removes all Representations there ID was manually added to the
+ * {@link #representationIds} list.
+ * @throws RepositoryException
+ */
+ @AfterClass
+ public static final void clearUpRepresentations() throws YardException, RepositoryException {
+ yard.remove(representationIds);
+ yard.close();
+ repo.shutDown();
+ }
+
+}