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();
+    }
+    
+}