Author: reto
Date: Sun Feb 15 18:41:15 2015
New Revision: 1659973

URL: http://svn.apache.org/r1659973
Log:
Started SPARQL Backed Implementation

Added:
    commons/sandbox/rdf/trunk/alerts.txt
    commons/sandbox/rdf/trunk/impl.sparql/   (with props)
    commons/sandbox/rdf/trunk/impl.sparql/pom.xml
    commons/sandbox/rdf/trunk/impl.sparql/src/
    commons/sandbox/rdf/trunk/impl.sparql/src/main/
    commons/sandbox/rdf/trunk/impl.sparql/src/main/java/
    commons/sandbox/rdf/trunk/impl.sparql/src/main/java/org/
    commons/sandbox/rdf/trunk/impl.sparql/src/main/java/org/apache/
    commons/sandbox/rdf/trunk/impl.sparql/src/main/java/org/apache/commons/
    commons/sandbox/rdf/trunk/impl.sparql/src/main/java/org/apache/commons/rdf/
    
commons/sandbox/rdf/trunk/impl.sparql/src/main/java/org/apache/commons/rdf/impl/
    
commons/sandbox/rdf/trunk/impl.sparql/src/main/java/org/apache/commons/rdf/impl/sparql/
    
commons/sandbox/rdf/trunk/impl.sparql/src/main/java/org/apache/commons/rdf/impl/sparql/SparqlClient.java
    
commons/sandbox/rdf/trunk/impl.sparql/src/main/java/org/apache/commons/rdf/impl/sparql/SparqlGraph.java
    commons/sandbox/rdf/trunk/impl.sparql/src/main/resources/
    commons/sandbox/rdf/trunk/impl.sparql/src/test/
    commons/sandbox/rdf/trunk/impl.sparql/src/test/java/
    commons/sandbox/rdf/trunk/impl.sparql/src/test/java/org/
    commons/sandbox/rdf/trunk/impl.sparql/src/test/java/org/apache/
    commons/sandbox/rdf/trunk/impl.sparql/src/test/java/org/apache/commons/
    commons/sandbox/rdf/trunk/impl.sparql/src/test/java/org/apache/commons/rdf/
    
commons/sandbox/rdf/trunk/impl.sparql/src/test/java/org/apache/commons/rdf/impl/
    
commons/sandbox/rdf/trunk/impl.sparql/src/test/java/org/apache/commons/rdf/impl/sparql/
    
commons/sandbox/rdf/trunk/impl.sparql/src/test/java/org/apache/commons/rdf/impl/sparql/SparqlGraphTest.java
    commons/sandbox/rdf/trunk/impl.sparql/src/test/resources/
    commons/sandbox/rdf/trunk/impl.sparql/src/test/resources/org/
    commons/sandbox/rdf/trunk/impl.sparql/src/test/resources/org/apache/
    commons/sandbox/rdf/trunk/impl.sparql/src/test/resources/org/apache/commons/
    
commons/sandbox/rdf/trunk/impl.sparql/src/test/resources/org/apache/commons/rdf/
    
commons/sandbox/rdf/trunk/impl.sparql/src/test/resources/org/apache/commons/rdf/impl/
    
commons/sandbox/rdf/trunk/impl.sparql/src/test/resources/org/apache/commons/rdf/impl/sparql/
    
commons/sandbox/rdf/trunk/impl.sparql/src/test/resources/org/apache/commons/rdf/impl/sparql/grounded.ttl
    commons/sandbox/rdf/trunk/impl.utils/   (with props)
    commons/sandbox/rdf/trunk/impl.utils/pom.xml
      - copied, changed from r1651181, commons/sandbox/rdf/trunk/pom.xml
    commons/sandbox/rdf/trunk/impl.utils/src/
    commons/sandbox/rdf/trunk/impl.utils/src/main/
    commons/sandbox/rdf/trunk/impl.utils/src/main/java/
    commons/sandbox/rdf/trunk/impl.utils/src/main/java/org/
    commons/sandbox/rdf/trunk/impl.utils/src/main/java/org/apache/
    commons/sandbox/rdf/trunk/impl.utils/src/main/java/org/apache/commons/
    commons/sandbox/rdf/trunk/impl.utils/src/main/java/org/apache/commons/rdf/
    
commons/sandbox/rdf/trunk/impl.utils/src/main/java/org/apache/commons/rdf/impl/
    
commons/sandbox/rdf/trunk/impl.utils/src/main/java/org/apache/commons/rdf/impl/utils/
    
commons/sandbox/rdf/trunk/impl.utils/src/main/java/org/apache/commons/rdf/impl/utils/AbstractGraph.java
    
commons/sandbox/rdf/trunk/impl.utils/src/main/java/org/apache/commons/rdf/impl/utils/AbstractImmutableGraph.java
    
commons/sandbox/rdf/trunk/impl.utils/src/main/java/org/apache/commons/rdf/impl/utils/AbstractLiteral.java
    
commons/sandbox/rdf/trunk/impl.utils/src/main/java/org/apache/commons/rdf/impl/utils/DelayedNotificator.java
    
commons/sandbox/rdf/trunk/impl.utils/src/main/java/org/apache/commons/rdf/impl/utils/LockingIterator.java
    
commons/sandbox/rdf/trunk/impl.utils/src/main/java/org/apache/commons/rdf/impl/utils/PlainLiteralImpl.java
    
commons/sandbox/rdf/trunk/impl.utils/src/main/java/org/apache/commons/rdf/impl/utils/TripleImpl.java
    
commons/sandbox/rdf/trunk/impl.utils/src/main/java/org/apache/commons/rdf/impl/utils/TypedLiteralImpl.java
    
commons/sandbox/rdf/trunk/impl.utils/src/main/java/org/apache/commons/rdf/impl/utils/WatchableGraphWrapper.java
    
commons/sandbox/rdf/trunk/impl.utils/src/main/java/org/apache/commons/rdf/impl/utils/debug/
    
commons/sandbox/rdf/trunk/impl.utils/src/main/java/org/apache/commons/rdf/impl/utils/debug/ReadLockDebug.java
    
commons/sandbox/rdf/trunk/impl.utils/src/main/java/org/apache/commons/rdf/impl/utils/debug/ReentrantReadWriteLockTracker.java
    
commons/sandbox/rdf/trunk/impl.utils/src/main/java/org/apache/commons/rdf/impl/utils/debug/WriteLockDebug.java
    
commons/sandbox/rdf/trunk/impl.utils/src/main/java/org/apache/commons/rdf/impl/utils/graphmatching/
    
commons/sandbox/rdf/trunk/impl.utils/src/main/java/org/apache/commons/rdf/impl/utils/graphmatching/GraphMatcher.java
    
commons/sandbox/rdf/trunk/impl.utils/src/main/java/org/apache/commons/rdf/impl/utils/graphmatching/GraphNotIsomorphicException.java
    
commons/sandbox/rdf/trunk/impl.utils/src/main/java/org/apache/commons/rdf/impl/utils/graphmatching/GroupMappingIterator.java
    
commons/sandbox/rdf/trunk/impl.utils/src/main/java/org/apache/commons/rdf/impl/utils/graphmatching/HashMatching.java
    
commons/sandbox/rdf/trunk/impl.utils/src/main/java/org/apache/commons/rdf/impl/utils/graphmatching/MappingIterator.java
    
commons/sandbox/rdf/trunk/impl.utils/src/main/java/org/apache/commons/rdf/impl/utils/graphmatching/PermutationIterator.java
    
commons/sandbox/rdf/trunk/impl.utils/src/main/java/org/apache/commons/rdf/impl/utils/graphmatching/Utils.java
    
commons/sandbox/rdf/trunk/impl.utils/src/main/java/org/apache/commons/rdf/impl/utils/graphmatching/collections/
    
commons/sandbox/rdf/trunk/impl.utils/src/main/java/org/apache/commons/rdf/impl/utils/graphmatching/collections/IntHashMap.java
    
commons/sandbox/rdf/trunk/impl.utils/src/main/java/org/apache/commons/rdf/impl/utils/graphmatching/collections/IntHashSet.java
    
commons/sandbox/rdf/trunk/impl.utils/src/main/java/org/apache/commons/rdf/impl/utils/graphmatching/collections/IntIterator.java
    
commons/sandbox/rdf/trunk/impl.utils/src/main/java/org/apache/commons/rdf/impl/utils/graphmatching/collections/IntSet.java
    
commons/sandbox/rdf/trunk/impl.utils/src/main/java/org/apache/commons/rdf/impl/utils/package-info.java
      - copied, changed from r1651181, 
commons/sandbox/rdf/trunk/src/main/java/org/apache/commons/rdf/package-info.java
    
commons/sandbox/rdf/trunk/impl.utils/src/main/java/org/apache/commons/rdf/impl/utils/simple/
    
commons/sandbox/rdf/trunk/impl.utils/src/main/java/org/apache/commons/rdf/impl/utils/simple/SimpleGraph.java
    
commons/sandbox/rdf/trunk/impl.utils/src/main/java/org/apache/commons/rdf/impl/utils/simple/SimpleImmutableGraph.java
    
commons/sandbox/rdf/trunk/impl.utils/src/main/java/org/apache/commons/rdf/impl/utils/simple/SimpleMGraph.java
    commons/sandbox/rdf/trunk/impl.utils/src/main/resources/
    commons/sandbox/rdf/trunk/impl.utils/src/test/
    commons/sandbox/rdf/trunk/impl.utils/src/test/java/
    commons/sandbox/rdf/trunk/impl.utils/src/test/java/org/
    commons/sandbox/rdf/trunk/impl.utils/src/test/java/org/apache/
    commons/sandbox/rdf/trunk/impl.utils/src/test/java/org/apache/commons/
    commons/sandbox/rdf/trunk/impl.utils/src/test/java/org/apache/commons/rdf/
    
commons/sandbox/rdf/trunk/impl.utils/src/test/java/org/apache/commons/rdf/impl/
    
commons/sandbox/rdf/trunk/impl.utils/src/test/java/org/apache/commons/rdf/impl/utils/
    
commons/sandbox/rdf/trunk/impl.utils/src/test/java/org/apache/commons/rdf/impl/utils/simple/
    
commons/sandbox/rdf/trunk/impl.utils/src/test/java/org/apache/commons/rdf/impl/utils/simple/PlainLiteralImplTest.java
    
commons/sandbox/rdf/trunk/impl.utils/src/test/java/org/apache/commons/rdf/impl/utils/simple/SimpleGraphTest.java
    
commons/sandbox/rdf/trunk/impl.utils/src/test/java/org/apache/commons/rdf/impl/utils/simple/TripleImplTest.java
    
commons/sandbox/rdf/trunk/impl.utils/src/test/java/org/apache/commons/rdf/impl/utils/simple/TypedLiteralImplTest.java
    commons/sandbox/rdf/trunk/report.xml
Modified:
    
commons/sandbox/rdf/trunk/api/src/main/java/org/apache/commons/rdf/Literal.java
    commons/sandbox/rdf/trunk/pom.xml

Added: commons/sandbox/rdf/trunk/alerts.txt
URL: 
http://svn.apache.org/viewvc/commons/sandbox/rdf/trunk/alerts.txt?rev=1659973&view=auto
==============================================================================
    (empty)

Modified: 
commons/sandbox/rdf/trunk/api/src/main/java/org/apache/commons/rdf/Literal.java
URL: 
http://svn.apache.org/viewvc/commons/sandbox/rdf/trunk/api/src/main/java/org/apache/commons/rdf/Literal.java?rev=1659973&r1=1659972&r2=1659973&view=diff
==============================================================================
--- 
commons/sandbox/rdf/trunk/api/src/main/java/org/apache/commons/rdf/Literal.java 
(original)
+++ 
commons/sandbox/rdf/trunk/api/src/main/java/org/apache/commons/rdf/Literal.java 
Sun Feb 15 18:41:15 2015
@@ -84,7 +84,8 @@ public interface Literal extends RdfTerm
     
     /**
      * Returns the hash code of the lexical form plus the hash code of the 
-     * language, plush the hash code of the datatype
+     * datatype plus if the literal has a language the hash code of the 
+     * language. 
      * 
      * @return hash code
      */

Propchange: commons/sandbox/rdf/trunk/impl.sparql/
------------------------------------------------------------------------------
--- svn:ignore (added)
+++ svn:ignore Sun Feb 15 18:41:15 2015
@@ -0,0 +1 @@
+target

Added: commons/sandbox/rdf/trunk/impl.sparql/pom.xml
URL: 
http://svn.apache.org/viewvc/commons/sandbox/rdf/trunk/impl.sparql/pom.xml?rev=1659973&view=auto
==============================================================================
--- commons/sandbox/rdf/trunk/impl.sparql/pom.xml (added)
+++ commons/sandbox/rdf/trunk/impl.sparql/pom.xml Sun Feb 15 18:41:15 2015
@@ -0,0 +1,52 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<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/xsd/maven-4.0.0.xsd";>
+    <parent>
+        <groupId>org.apache.commons</groupId>
+        <artifactId>commons-parent</artifactId>
+        <version>37</version>
+        <relativePath />
+    </parent>
+    <modelVersion>4.0.0</modelVersion>
+    <groupId>commons-rdf</groupId>
+    <artifactId>commons-rdf-impl-sparql</artifactId>
+    <version>1.0.0-SNAPSHOT</version>
+    <packaging>jar</packaging>
+    <name>Apache Commons RDF SPARQL backed implementation.</name>
+    <description>An implementation of the rdf commons API backed by a sparql 
+        endpoint. STATUS: Incomplete, currecnt code only supports reading 
+        graphs and does not yet support BlankNodes.</description>
+    <properties>
+        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+        <maven.compiler.source>1.7</maven.compiler.source>
+        <maven.compiler.target>1.7</maven.compiler.target>
+    </properties>
+    <dependencies>
+        <dependency>
+            <groupId>org.apache.httpcomponents</groupId>
+            <artifactId>httpclient</artifactId>
+            <version>4.4</version>
+        </dependency>
+        <dependency>
+            <groupId>commons-rdf</groupId>
+            <artifactId>commons-rdf-api</artifactId>
+            <version>0.1-SNAPSHOT</version>
+        </dependency>
+        <dependency>
+            <groupId>commons-rdf</groupId>
+            <artifactId>commons-rdf-impl-utils</artifactId>
+            <version>0.1-SNAPSHOT</version>
+        </dependency>
+        <dependency>
+            <groupId>junit</groupId>
+            <artifactId>junit</artifactId>
+            <version>4.12</version>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.jena</groupId>
+            <artifactId>jena-fuseki</artifactId>
+            <version>1.1.1</version>
+            <scope>test</scope>
+        </dependency>
+    </dependencies>
+</project>
\ No newline at end of file

Added: 
commons/sandbox/rdf/trunk/impl.sparql/src/main/java/org/apache/commons/rdf/impl/sparql/SparqlClient.java
URL: 
http://svn.apache.org/viewvc/commons/sandbox/rdf/trunk/impl.sparql/src/main/java/org/apache/commons/rdf/impl/sparql/SparqlClient.java?rev=1659973&view=auto
==============================================================================
--- 
commons/sandbox/rdf/trunk/impl.sparql/src/main/java/org/apache/commons/rdf/impl/sparql/SparqlClient.java
 (added)
+++ 
commons/sandbox/rdf/trunk/impl.sparql/src/main/java/org/apache/commons/rdf/impl/sparql/SparqlClient.java
 Sun Feb 15 18:41:15 2015
@@ -0,0 +1,220 @@
+/*
+ * To change this license header, choose License Headers in Project Properties.
+ * To change this template file, choose Tools | Templates
+ * and open the template in the editor.
+ */
+package org.apache.commons.rdf.impl.sparql;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.UnsupportedEncodingException;
+import java.util.ArrayList;
+import java.util.Enumeration;
+import java.util.HashMap;
+import java.util.Hashtable;
+import java.util.List;
+import java.util.Map;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+import org.apache.http.HttpEntity;
+import org.apache.http.NameValuePair;
+import org.apache.http.client.entity.UrlEncodedFormEntity;
+import org.apache.http.client.methods.CloseableHttpResponse;
+import org.apache.http.client.methods.HttpPost;
+import org.apache.http.impl.client.CloseableHttpClient;
+import org.apache.http.impl.client.HttpClients;
+import org.apache.http.message.BasicNameValuePair;
+import org.apache.http.util.EntityUtils;
+import javax.xml.parsers.*;
+import org.apache.commons.rdf.BlankNode;
+import org.apache.commons.rdf.BlankNodeOrIri;
+import org.apache.commons.rdf.Iri;
+import org.apache.commons.rdf.Language;
+import org.apache.commons.rdf.Literal;
+import org.apache.commons.rdf.RdfTerm;
+import org.apache.commons.rdf.Triple;
+import org.apache.commons.rdf.impl.utils.AbstractLiteral;
+import org.xml.sax.*;
+import org.xml.sax.helpers.*;
+
+/**
+ *
+ * @author developer
+ */
+public class SparqlClient {
+
+    final String endpoint;
+
+    public SparqlClient(final String endpoint) {
+        this.endpoint = endpoint;
+    }
+
+    List<Map<String, RdfTerm>> queryResultSet(final String query) throws 
IOException {
+        CloseableHttpClient httpclient = HttpClients.createDefault();
+        HttpPost httpPost = new HttpPost(endpoint);
+        List<NameValuePair> nvps = new ArrayList<NameValuePair>();
+        nvps.add(new BasicNameValuePair("query", query));
+        httpPost.setEntity(new UrlEncodedFormEntity(nvps));
+        CloseableHttpResponse response2 = httpclient.execute(httpPost);
+
+        try {
+            HttpEntity entity2 = response2.getEntity();
+            InputStream in = entity2.getContent();
+            SAXParserFactory spf = SAXParserFactory.newInstance();
+            spf.setNamespaceAware(true);
+            SAXParser saxParser = spf.newSAXParser();
+            XMLReader xmlReader = saxParser.getXMLReader();
+            final SparqlsResultsHandler sparqlsResultsHandler = new 
SparqlsResultsHandler();
+            xmlReader.setContentHandler(sparqlsResultsHandler);
+            xmlReader.parse(new InputSource(in));
+            /*
+             for (int ch = in.read(); ch != -1; ch = in.read()) {
+             System.out.print((char)ch);
+             }
+             */
+            // do something useful with the response body
+            // and ensure it is fully consumed
+            EntityUtils.consume(entity2);
+            return sparqlsResultsHandler.getResults();
+        } catch (ParserConfigurationException ex) {
+            throw new RuntimeException(ex);
+        } catch (SAXException ex) {
+            throw new RuntimeException(ex);
+        } finally {
+            response2.close();
+        }
+
+    }
+
+    final public static class SparqlsResultsHandler extends DefaultHandler {
+
+        private String currentBindingName;
+        private Map<String, RdfTerm> currentResult = null;
+        private final List<Map<String, RdfTerm>> results = new ArrayList<>();
+        private boolean readingValue;
+        private String value;
+        private Map<String, BlankNode> bNodeMap = new HashMap<>();
+        private static final Iri XSD_STRING = new 
Iri("http://www.w3.org/2001/XMLSchema#string";);
+
+        private RdfTerm getBNode(String value) {
+            if (!bNodeMap.containsKey(value)) {
+                bNodeMap.put(value, new BlankNode());
+            }
+            return bNodeMap.get(value);
+        }
+
+        private List<Map<String, RdfTerm>> getResults() {
+            return results;
+        }
+
+        enum BindingType {
+
+            uri, bnode, literal;
+        }
+
+        @Override
+        public void startDocument() throws SAXException {
+
+        }
+
+        @Override
+        public void startElement(String namespaceURI,
+                String localName,
+                String qName,
+                Attributes atts)
+                throws SAXException {
+            if ("http://www.w3.org/2005/sparql-results#".equals(namespaceURI)) 
{
+                if ("result".equals(localName)) {
+                    if (currentResult != null) {
+                        throw new SAXException("unexpected tag <result>");
+                    }
+                    currentResult = new HashMap<>();
+                } else if ("binding".equals(localName)) {
+                    if (currentResult == null) {
+                        throw new SAXException("unexpected tag <binding>");
+                    }
+                    currentBindingName = atts.getValue("name");
+                } else if ("uri".equals(localName) || 
"bnode".equals(localName) || "literal".equals(localName)) {
+                    if (readingValue) {
+                        throw new SAXException("unexpected tag <" + localName 
+ ">");
+                    }
+                    readingValue = true;
+                }
+            }
+
+            //System.out.println(namespaceURI);
+            //System.out.println(qName);
+        }
+
+        @Override
+        public void characters(char[] chars, int start, int length) throws 
SAXException {
+            if (readingValue) {
+                value = new String(chars, start, length);
+                //System.err.println(value + start + ", " + length);
+            }
+        }
+
+        @Override
+        public void endElement(String namespaceURI,
+                String localName,
+                String qName)
+                throws SAXException {
+            if ("http://www.w3.org/2005/sparql-results#".equals(namespaceURI)) 
{
+                if ("result".equals(localName)) {
+                    results.add(currentResult);
+                    currentResult = null;
+                } else if ("binding".equals(localName)) {
+                    if (currentBindingName == null) {
+                        throw new SAXException("unexpected tag </binding>");
+                    }
+                    currentBindingName = null;
+                } else {
+                    try {
+                        BindingType b = BindingType.valueOf(localName);
+                        RdfTerm rdfTerm = null;
+                        switch (b) {
+                            case uri:
+                                rdfTerm = new Iri(value);
+                                break;
+                            case bnode:
+                                rdfTerm = getBNode(value);
+                                break;
+                            case literal:
+                                final String lf = value;
+                                rdfTerm = new AbstractLiteral() {
+
+                                    @Override
+                                    public String getLexicalForm() {
+                                        return lf;
+                                    }
+
+                                    @Override
+                                    public Iri getDataType() {
+                                        //TODO implement
+                                        return XSD_STRING;
+                                    }
+
+                                    @Override
+                                    public Language getLanguage() {
+                                        //TODO impl
+                                        return null;
+                                    }
+                                };
+                                break;
+                        }
+                        currentResult.put(currentBindingName, rdfTerm);
+                        readingValue = false;
+                    } catch (IllegalArgumentException e) {
+                            //not uri|bnode|literal
+                    }
+                }
+            }
+        }
+
+        public void endDocument() throws SAXException {
+            //System.out.println("results: " + results.size());
+        }
+
+    }
+
+}

Added: 
commons/sandbox/rdf/trunk/impl.sparql/src/main/java/org/apache/commons/rdf/impl/sparql/SparqlGraph.java
URL: 
http://svn.apache.org/viewvc/commons/sandbox/rdf/trunk/impl.sparql/src/main/java/org/apache/commons/rdf/impl/sparql/SparqlGraph.java?rev=1659973&view=auto
==============================================================================
--- 
commons/sandbox/rdf/trunk/impl.sparql/src/main/java/org/apache/commons/rdf/impl/sparql/SparqlGraph.java
 (added)
+++ 
commons/sandbox/rdf/trunk/impl.sparql/src/main/java/org/apache/commons/rdf/impl/sparql/SparqlGraph.java
 Sun Feb 15 18:41:15 2015
@@ -0,0 +1,121 @@
+/*
+ * To change this license header, choose License Headers in Project Properties.
+ * To change this template file, choose Tools | Templates
+ * and open the template in the editor.
+ */
+package org.apache.commons.rdf.impl.sparql;
+
+import java.io.IOException;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import org.apache.commons.rdf.BlankNode;
+import org.apache.commons.rdf.BlankNodeOrIri;
+import org.apache.commons.rdf.Iri;
+import org.apache.commons.rdf.Literal;
+import org.apache.commons.rdf.RdfTerm;
+import org.apache.commons.rdf.Triple;
+import org.apache.commons.rdf.impl.utils.AbstractGraph;
+import org.apache.commons.rdf.impl.utils.TripleImpl;
+
+/**
+ *
+ * @author reto
+ */
+public class SparqlGraph extends AbstractGraph {
+
+    final SparqlClient sparqlClient;
+
+    /** Constructs a Graph representing the default graph at the specified 
+     * endpoint 
+     */
+    public SparqlGraph(final String endpoint) {
+        sparqlClient = new SparqlClient(endpoint);
+    }
+    
+    @Override
+    protected Iterator<Triple> performFilter(final BlankNodeOrIri subject, 
+            final Iri predicate, final RdfTerm object) {
+        try {
+            final StringBuilder queryBuilder = new StringBuilder();
+            queryBuilder.append("SELECT * WHERE { ");
+            if (subject == null) {
+                queryBuilder.append("?s");
+            } else {
+                queryBuilder.append(asSparqlTerm(subject));
+            }
+            queryBuilder.append(' ');
+            if (predicate == null) {
+                queryBuilder.append("?p");
+            } else {
+                queryBuilder.append(asSparqlTerm(predicate));
+            }
+            queryBuilder.append(' ');
+            if (object == null) {
+                queryBuilder.append("?o");
+            } else {
+                queryBuilder.append(asSparqlTerm(object));
+            }
+            queryBuilder.append(" }");
+            List<Map<String, RdfTerm>> sparqlResults = 
sparqlClient.queryResultSet(queryBuilder.toString());
+            final Iterator<Map<String, RdfTerm>> resultsIterator = 
sparqlResults.iterator();
+            return new Iterator<Triple>() {
+
+                @Override
+                public boolean hasNext() {
+                    return resultsIterator.hasNext();
+                }
+
+                @Override
+                public Triple next() {
+                    Map<String, RdfTerm> result = resultsIterator.next();
+                    return new TripleImpl(subject != null ? subject : 
(BlankNodeOrIri)result.get("s"),
+                            predicate != null ? predicate : 
(Iri)result.get("p"), 
+                            object != null ? object : result.get("o"));
+                }
+            };
+        } catch (IOException ex) {
+            throw new RuntimeException(ex);
+        }
+    }
+
+    @Override
+    protected int performSize() {
+        try {
+            return sparqlClient.queryResultSet("SELECT * WHERE { ?s ?p 
?o}").size();
+        } catch (IOException ex) {
+            throw new RuntimeException(ex);
+        }
+    }
+
+    private String asSparqlTerm(Iri iri) {
+        return "<"+iri.getUnicodeString()+">";
+    }
+    
+    private String asSparqlTerm(Literal literal) {
+        //TODO langauge and datatype
+        return "\""+literal.getLexicalForm()+"\"";
+    }
+    
+    private String asSparqlTerm(BlankNode bnode) {
+        //this requires adding additional clauses to the graph pattern
+        throw new UnsupportedOperationException("Not supported yet.");
+    }
+
+    private String asSparqlTerm(BlankNodeOrIri term) {
+        if (term instanceof Iri) {
+            return asSparqlTerm((Iri)term);
+        } else {
+            return asSparqlTerm((BlankNode)term);
+        }
+    }
+    
+    private String asSparqlTerm(RdfTerm term) {
+        if (term instanceof BlankNodeOrIri) {
+            return asSparqlTerm((BlankNodeOrIri)term);
+        } else {
+            return asSparqlTerm((Literal)term);
+        }
+    }
+    
+}

Added: 
commons/sandbox/rdf/trunk/impl.sparql/src/test/java/org/apache/commons/rdf/impl/sparql/SparqlGraphTest.java
URL: 
http://svn.apache.org/viewvc/commons/sandbox/rdf/trunk/impl.sparql/src/test/java/org/apache/commons/rdf/impl/sparql/SparqlGraphTest.java?rev=1659973&view=auto
==============================================================================
--- 
commons/sandbox/rdf/trunk/impl.sparql/src/test/java/org/apache/commons/rdf/impl/sparql/SparqlGraphTest.java
 (added)
+++ 
commons/sandbox/rdf/trunk/impl.sparql/src/test/java/org/apache/commons/rdf/impl/sparql/SparqlGraphTest.java
 Sun Feb 15 18:41:15 2015
@@ -0,0 +1,106 @@
+/*
+ * To change this license header, choose License Headers in Project Properties.
+ * To change this template file, choose Tools | Templates
+ * and open the template in the editor.
+ */
+package org.apache.commons.rdf.impl.sparql;
+
+import com.hp.hpl.jena.query.DatasetAccessor;
+import com.hp.hpl.jena.query.DatasetAccessorFactory;
+import java.io.File;
+import java.io.IOException;
+import java.net.ServerSocket;
+import org.apache.jena.fuseki.EmbeddedFusekiServer;
+import com.hp.hpl.jena.rdf.model.Model;
+import com.hp.hpl.jena.rdf.model.ModelFactory;
+import java.io.InputStream;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.Set;
+import org.apache.commons.rdf.Graph;
+import org.apache.commons.rdf.Iri;
+import org.apache.commons.rdf.Literal;
+import org.apache.commons.rdf.RdfTerm;
+import org.apache.commons.rdf.Triple;
+import org.apache.commons.rdf.impl.utils.PlainLiteralImpl;
+import org.junit.AfterClass;
+import org.junit.Assert;
+import org.junit.BeforeClass;
+import org.junit.Test;
+
+/**
+ *
+ * @author reto
+ */
+public class SparqlGraphTest {
+
+    final static int serverPort = findFreePort();
+    static EmbeddedFusekiServer server;
+
+    @BeforeClass
+    public static void prepare() throws IOException {
+        final String serviceURI = "http://localhost:"; + serverPort + 
"/ds/data";
+        final DatasetAccessorFactory factory = new DatasetAccessorFactory();
+        final DatasetAccessor accessor = factory.createHTTP(serviceURI);
+        final InputStream in = 
SparqlGraphTest.class.getResourceAsStream("grounded.ttl");
+        final Model m = ModelFactory.createDefaultModel();
+        String base = "http://example.org/";;
+        m.read(in, base, "TURTLE");
+
+        final File dataSet = File.createTempFile("dataset", "fuseki");
+        dataSet.delete();
+        server = EmbeddedFusekiServer.memTDB(serverPort, 
"/ds");//dataSet.getAbsolutePath());
+        server.start();
+        System.out.println("Started fuseki on port " + serverPort);
+        accessor.putModel(m);
+    }
+
+    @AfterClass
+    public static void cleanup() {
+        server.stop();
+    }
+
+    @Test
+    public void graphSize() {
+        final Graph graph = new SparqlGraph("http://localhost:"; + serverPort + 
"/ds/query");
+        Assert.assertEquals("Graph not of the exepected size", 8, 
graph.size());
+    }
+
+    @Test
+    public void filter1() {
+        final Graph graph = new SparqlGraph("http://localhost:"; + serverPort + 
"/ds/query");
+        final Iri spiderman = new Iri("http://example.org/#spiderman";);
+        final Iri greenGoblin = new Iri("http://example.org/#green-goblin";);
+        final Iri enemyOf = new 
Iri("http://www.perceive.net/schemas/relationship/enemyOf";);
+        final Iri foafName = new Iri("http://xmlns.com/foaf/0.1/name";);
+        {
+            final Iterator<Triple> iter = graph.filter(spiderman, null, 
greenGoblin);
+            Assert.assertTrue(iter.hasNext());
+            Assert.assertEquals(enemyOf, iter.next().getPredicate());
+            Assert.assertFalse(iter.hasNext());
+        }
+        {
+            final Iterator<Triple> iter = graph.filter(spiderman, foafName, 
null);
+            Set<Literal> names = new HashSet<>();
+            for (int i = 0; i < 2; i++) {
+                Assert.assertTrue(iter.hasNext());
+                RdfTerm name = iter.next().getObject();
+                Assert.assertTrue(name instanceof Literal);
+                names.add((Literal)name);
+            }
+            Assert.assertFalse(iter.hasNext());
+            Assert.assertTrue(names.contains(new 
PlainLiteralImpl("Spiderman")));
+        }
+    }
+
+    public static int findFreePort() {
+        int port = 0;
+        try (ServerSocket server = new ServerSocket(0);) {
+            port = server.getLocalPort();
+        } catch (Exception e) {
+            throw new RuntimeException("unable to find a free port");
+        }
+        return port;
+    }
+
+}

Added: 
commons/sandbox/rdf/trunk/impl.sparql/src/test/resources/org/apache/commons/rdf/impl/sparql/grounded.ttl
URL: 
http://svn.apache.org/viewvc/commons/sandbox/rdf/trunk/impl.sparql/src/test/resources/org/apache/commons/rdf/impl/sparql/grounded.ttl?rev=1659973&view=auto
==============================================================================
--- 
commons/sandbox/rdf/trunk/impl.sparql/src/test/resources/org/apache/commons/rdf/impl/sparql/grounded.ttl
 (added)
+++ 
commons/sandbox/rdf/trunk/impl.sparql/src/test/resources/org/apache/commons/rdf/impl/sparql/grounded.ttl
 Sun Feb 15 18:41:15 2015
@@ -0,0 +1,16 @@
+@base <http://example.org/> .
+@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
+@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
+@prefix foaf: <http://xmlns.com/foaf/0.1/> .
+@prefix rel: <http://www.perceive.net/schemas/relationship/> .
+
+<#green-goblin>
+    rel:enemyOf <#spiderman> ;
+    a foaf:Person ;    # in the context of the Marvel universe
+    foaf:name "Green Goblin" ;
+    foaf:age 128 .
+
+<#spiderman>
+    rel:enemyOf <#green-goblin> ;
+    a foaf:Person ;
+    foaf:name "Spiderman", "Человек-паук"@ru .
\ No newline at end of file

Propchange: commons/sandbox/rdf/trunk/impl.utils/
------------------------------------------------------------------------------
--- svn:ignore (added)
+++ svn:ignore Sun Feb 15 18:41:15 2015
@@ -0,0 +1 @@
+target

Copied: commons/sandbox/rdf/trunk/impl.utils/pom.xml (from r1651181, 
commons/sandbox/rdf/trunk/pom.xml)
URL: 
http://svn.apache.org/viewvc/commons/sandbox/rdf/trunk/impl.utils/pom.xml?p2=commons/sandbox/rdf/trunk/impl.utils/pom.xml&p1=commons/sandbox/rdf/trunk/pom.xml&r1=1651181&r2=1659973&rev=1659973&view=diff
==============================================================================
--- commons/sandbox/rdf/trunk/pom.xml (original)
+++ commons/sandbox/rdf/trunk/impl.utils/pom.xml Sun Feb 15 18:41:15 2015
@@ -22,13 +22,14 @@
     <parent>
         <groupId>org.apache.commons</groupId>
         <artifactId>commons-parent</artifactId>
-        <version>35</version>
+        <version>37</version>
+        <relativePath />
     </parent>
     <modelVersion>4.0.0</modelVersion>
     <groupId>commons-rdf</groupId>
-    <artifactId>commons-rdf</artifactId>
+    <artifactId>commons-rdf-impl-utils</artifactId>
     <version>0.1-SNAPSHOT</version>
-    <name>Apache Commons RDF</name>
+    <name>Apache Commons RDF Implementation Utils</name>
     <description>
         Apache Commons RDF provides an API modelling the RDF data model as 
defined by 
         http://www.w3.org/TR/rdf11-concepts/
@@ -50,11 +51,22 @@
 
     <dependencies>
         <dependency>
+            <groupId>commons-rdf</groupId>
+            <artifactId>commons-rdf-api</artifactId>
+            <version>0.1-SNAPSHOT</version>
+        </dependency>
+        <dependency>
             <groupId>junit</groupId>
             <artifactId>junit</artifactId>
             <version>4.12</version>
             <scope>test</scope>
         </dependency>
+        <dependency>
+            <groupId>org.slf4j</groupId>
+            <artifactId>slf4j-api</artifactId>
+            <version>1.7.7</version>
+            <type>jar</type>
+        </dependency>
     </dependencies>
 
     <distributionManagement>

Added: 
commons/sandbox/rdf/trunk/impl.utils/src/main/java/org/apache/commons/rdf/impl/utils/AbstractGraph.java
URL: 
http://svn.apache.org/viewvc/commons/sandbox/rdf/trunk/impl.utils/src/main/java/org/apache/commons/rdf/impl/utils/AbstractGraph.java?rev=1659973&view=auto
==============================================================================
--- 
commons/sandbox/rdf/trunk/impl.utils/src/main/java/org/apache/commons/rdf/impl/utils/AbstractGraph.java
 (added)
+++ 
commons/sandbox/rdf/trunk/impl.utils/src/main/java/org/apache/commons/rdf/impl/utils/AbstractGraph.java
 Sun Feb 15 18:41:15 2015
@@ -0,0 +1,316 @@
+/*
+ * 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.commons.rdf.impl.utils;
+
+import java.lang.ref.WeakReference;
+import java.util.AbstractCollection;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.Iterator;
+
+import java.util.Set;
+import java.util.concurrent.locks.Lock;
+import java.util.concurrent.locks.ReadWriteLock;
+import java.util.concurrent.locks.ReentrantReadWriteLock;
+import org.apache.commons.rdf.BlankNodeOrIri;
+import org.apache.commons.rdf.RdfTerm;
+import org.apache.commons.rdf.Triple;
+import org.apache.commons.rdf.Graph;
+import org.apache.commons.rdf.ImmutableGraph;
+import org.apache.commons.rdf.Iri;
+import org.apache.commons.rdf.WatchableGraph;
+import org.apache.commons.rdf.event.AddEvent;
+import org.apache.commons.rdf.event.FilterTriple;
+import org.apache.commons.rdf.event.GraphEvent;
+import org.apache.commons.rdf.event.GraphListener;
+import org.apache.commons.rdf.event.RemoveEvent;
+import org.apache.commons.rdf.impl.utils.debug.ReentrantReadWriteLockTracker;
+import org.apache.commons.rdf.impl.utils.simple.SimpleImmutableGraph;
+
+/**
+ * An abstract implementation of <code>Graph</code> implementing
+ * <code>iterator</code> and <code>contains</code> calling <code>filter</code>.
+ *
+ * @author reto
+ */
+public abstract class AbstractGraph extends AbstractCollection<Triple>
+        implements Graph {
+
+    
+    private static final String DEBUG_MODE = "rdfLocksDebugging";
+    private final ReadWriteLock lock;
+
+    private final Lock readLock;
+    private final Lock writeLock;
+
+    /**
+     * Constructs a LocalbleMGraph for an Graph.
+     *
+     * @param providedMGraph a non-lockable graph
+     */
+    public AbstractGraph() {
+        {
+            String debugMode = System.getProperty(DEBUG_MODE);
+            if (debugMode != null && debugMode.toLowerCase().equals("true")) {
+                lock = new ReentrantReadWriteLockTracker();
+            } else {
+                lock = new ReentrantReadWriteLock();
+            }
+        }
+        readLock = lock.readLock();
+        writeLock = lock.writeLock();
+    }
+    
+    public AbstractGraph(final ReadWriteLock lock) {
+        this.lock = lock;
+        readLock = lock.readLock();
+        writeLock = lock.writeLock();
+    }
+
+    @Override
+    public ReadWriteLock getLock() {
+        return lock;
+    }
+
+    @Override
+    public ImmutableGraph getImmutableGraph() {
+        readLock.lock();
+        try {
+            return performGetImmutableGraph();
+        } finally {
+            readLock.unlock();
+        }
+    }
+    
+    public ImmutableGraph performGetImmutableGraph() {
+        return new SimpleImmutableGraph(this);
+    }
+
+    @Override
+    public Iterator<Triple> filter(BlankNodeOrIri subject, Iri predicate, 
RdfTerm object) {
+        readLock.lock();
+        try {
+            return new LockingIterator(performFilter(subject, predicate, 
object), lock);
+        } finally {
+            readLock.unlock();
+        }
+    }
+
+    @Override
+    public int size() {
+        readLock.lock();
+        try {
+            return performSize();
+        } finally {
+            readLock.unlock();
+        }
+    }
+
+    @Override
+    public boolean isEmpty() {
+        readLock.lock();
+        try {
+            return performIsEmpty();
+        } finally {
+            readLock.unlock();
+        }
+    }
+
+    @Override
+    @SuppressWarnings("element-type-mismatch")
+    public boolean contains(Object o) {
+        readLock.lock();
+        try {
+            return performContains(o);
+        } finally {
+            readLock.unlock();
+        }
+    }
+
+    @Override
+    public Iterator<Triple> iterator() {
+        readLock.lock();
+        try {
+            return new LockingIterator(performIterator(), lock);
+        } finally {
+            readLock.unlock();
+        }
+    }
+
+    @Override
+    public Object[] toArray() {
+        readLock.lock();
+        try {
+            return performToArray();
+        } finally {
+            readLock.unlock();
+        }
+    }
+
+    @Override
+    public <T> T[] toArray(T[] a) {
+        readLock.lock();
+        try {
+            return performToArray(a);
+        } finally {
+            readLock.unlock();
+        }
+    }
+
+    @Override
+    public boolean containsAll(Collection<?> c) {
+        readLock.lock();
+        try {
+            return performContainsAll(c);
+        } finally {
+            readLock.unlock();
+        }
+    }
+
+    @Override
+    public boolean add(Triple e) {
+        writeLock.lock();
+        try {
+            return performAdd(e);
+        } finally {
+            writeLock.unlock();
+        }
+    }
+
+    @Override
+    public boolean remove(Object o) {
+        writeLock.lock();
+        try {
+            return performRemove(o);
+        } finally {
+            writeLock.unlock();
+        }
+    }
+
+    @Override
+    public boolean addAll(Collection<? extends Triple> c) {
+        writeLock.lock();
+        try {
+            return performAddAll(c);
+        } finally {
+            writeLock.unlock();
+        }
+    }
+
+    @Override
+    public boolean removeAll(Collection<?> c) {
+        writeLock.lock();
+        try {
+            return performRemoveAll(c);
+        } finally {
+            writeLock.unlock();
+        }
+    }
+
+    @Override
+    public boolean retainAll(Collection<?> c) {
+        writeLock.lock();
+        try {
+            return performRetainAll(c);
+        } finally {
+            writeLock.unlock();
+        }
+    }
+
+    @Override
+    public void clear() {
+        writeLock.lock();
+        try {
+            performClear();
+        } finally {
+            writeLock.unlock();
+        }
+    }
+
+    
+    @Override
+    public boolean equals(Object obj) {
+        /*if (obj == null) {
+            return false;
+        }
+        if (obj == this) {
+            return true;
+        }
+        if (obj.getClass() != getClass()) {
+            return false;
+        }*/
+        return this == obj;
+    }
+
+
+    protected abstract Iterator<Triple> performFilter(BlankNodeOrIri subject, 
Iri predicate, RdfTerm object);
+
+    protected abstract int performSize();
+
+    protected boolean performIsEmpty() {
+        return super.isEmpty();
+    }
+
+    protected Object[] performToArray() {
+        return super.toArray();
+    }
+
+    protected boolean performRemove(Object o) {
+        return super.remove(o);
+    }
+
+    protected boolean performAddAll(Collection<? extends Triple> c) {
+        return super.addAll(c);
+    }
+
+    protected boolean performRemoveAll(Collection<?> c) {
+        return super.removeAll(c);
+    }
+
+    protected boolean performRetainAll(Collection<?> c) {
+        return super.retainAll(c);
+    }
+
+    protected void performClear() {
+        super.clear();
+    }
+
+    protected boolean performContains(Object o) {
+        return super.contains(o);
+    }
+
+    protected Iterator<Triple> performIterator() {
+        return performFilter(null, null, null);
+    }
+
+    protected boolean performContainsAll(Collection<?> c) {
+        return super.containsAll(c);
+    }
+
+    protected <T> T[] performToArray(T[] a) {
+        return super.toArray(a);
+    }
+
+    protected boolean performAdd(Triple e) {
+        return super.add(e);
+    }
+
+ 
+}

Added: 
commons/sandbox/rdf/trunk/impl.utils/src/main/java/org/apache/commons/rdf/impl/utils/AbstractImmutableGraph.java
URL: 
http://svn.apache.org/viewvc/commons/sandbox/rdf/trunk/impl.utils/src/main/java/org/apache/commons/rdf/impl/utils/AbstractImmutableGraph.java?rev=1659973&view=auto
==============================================================================
--- 
commons/sandbox/rdf/trunk/impl.utils/src/main/java/org/apache/commons/rdf/impl/utils/AbstractImmutableGraph.java
 (added)
+++ 
commons/sandbox/rdf/trunk/impl.utils/src/main/java/org/apache/commons/rdf/impl/utils/AbstractImmutableGraph.java
 Sun Feb 15 18:41:15 2015
@@ -0,0 +1,112 @@
+/*
+ * 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.commons.rdf.impl.utils;
+
+import java.util.Collection;
+import java.util.Iterator;
+
+import org.apache.commons.rdf.BlankNode;
+import org.apache.commons.rdf.ImmutableGraph;
+import org.apache.commons.rdf.RdfTerm;
+import org.apache.commons.rdf.Triple;
+import org.apache.commons.rdf.impl.utils.graphmatching.GraphMatcher;
+
+/**
+ * <code>AbstractGraph</code> is an abstract implementation of 
<code>ImmutableGraph</code> 
+ * implementing the <code>equals</code> and the <code>hashCode</code> methods.
+ * 
+ * @author reto
+ * 
+ */
+public abstract class AbstractImmutableGraph extends AbstractGraph
+        implements ImmutableGraph {
+
+    public final synchronized int hashCode() {
+        int result = 0;
+        for (Iterator<Triple> iter = iterator(); iter.hasNext();) {
+            result += getBlankNodeBlindHash(iter.next());
+        }
+        return result;
+    }
+
+    /**
+     * @param triple
+     * @return hash without BNode hashes
+     */
+    private int getBlankNodeBlindHash(Triple triple) {
+        int hash = triple.getPredicate().hashCode();
+        RdfTerm subject = triple.getSubject();
+
+        if (!(subject instanceof BlankNode)) {
+            hash ^= subject.hashCode() >> 1;
+        }
+        RdfTerm object = triple.getObject();
+        if (!(object instanceof BlankNode)) {
+            hash ^= object.hashCode() << 1;
+        }
+
+        return hash;
+    }
+
+    @Override
+    public boolean add(Triple e) {
+        throw new UnsupportedOperationException("Graphs are not mutable, use 
Graph");
+
+    }
+
+    @Override
+    public boolean addAll(Collection<? extends Triple> c) {
+        throw new UnsupportedOperationException("Graphs are not mutable, use 
Graph");
+    }
+
+    @Override
+    public boolean remove(Object o) {
+        throw new UnsupportedOperationException("Graphs are not mutable, use 
Graph");
+    }
+
+    @Override
+    public boolean removeAll(Collection<?> c) {
+        throw new UnsupportedOperationException("Graphs are not mutable, use 
Graph");
+    }
+
+    @Override
+    public void clear() {
+        throw new UnsupportedOperationException("Graphs are not mutable, use 
Graph");
+    }
+    
+    
+    @Override
+    public ImmutableGraph getImmutableGraph() {
+        return this;
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj) {
+            return true;
+        }
+        if (!(obj instanceof ImmutableGraph)) {
+            return false;
+        }
+        if (hashCode() != obj.hashCode()) {
+            return false;
+        }
+        return GraphMatcher.getValidMapping(this, (ImmutableGraph) obj) != 
null;
+    }
+}

Added: 
commons/sandbox/rdf/trunk/impl.utils/src/main/java/org/apache/commons/rdf/impl/utils/AbstractLiteral.java
URL: 
http://svn.apache.org/viewvc/commons/sandbox/rdf/trunk/impl.utils/src/main/java/org/apache/commons/rdf/impl/utils/AbstractLiteral.java?rev=1659973&view=auto
==============================================================================
--- 
commons/sandbox/rdf/trunk/impl.utils/src/main/java/org/apache/commons/rdf/impl/utils/AbstractLiteral.java
 (added)
+++ 
commons/sandbox/rdf/trunk/impl.utils/src/main/java/org/apache/commons/rdf/impl/utils/AbstractLiteral.java
 Sun Feb 15 18:41:15 2015
@@ -0,0 +1,61 @@
+/*
+ * Copyright 2015 The Apache Software Foundation.
+ *
+ * Licensed 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.commons.rdf.impl.utils;
+
+import org.apache.commons.rdf.Literal;
+
+/**
+ *
+ * @author developer
+ */
+public abstract class AbstractLiteral implements Literal {
+
+    @Override
+    public int hashCode() {
+        int result = 0;
+        if (getLanguage() != null) {
+            result = getLanguage().hashCode();
+        }
+        result += getLexicalForm().hashCode();
+        result += getDataType().hashCode();
+        return result;
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj) {
+            return true;
+        }
+        if (obj instanceof Literal) {
+            Literal other = (Literal) obj;
+            
+            if (getLanguage() == null) {
+                if (other.getLanguage() != null) {
+                    return false;
+                }
+            } else {
+                if (!getLanguage().equals(other.getLanguage())) {
+                    return false;
+                }
+            }
+            boolean res = getDataType().equals(other.getDataType()) && 
getLexicalForm().equals(other.getLexicalForm());
+            return res;
+        } else {
+            return false;
+        }
+    }
+    
+}

Added: 
commons/sandbox/rdf/trunk/impl.utils/src/main/java/org/apache/commons/rdf/impl/utils/DelayedNotificator.java
URL: 
http://svn.apache.org/viewvc/commons/sandbox/rdf/trunk/impl.utils/src/main/java/org/apache/commons/rdf/impl/utils/DelayedNotificator.java?rev=1659973&view=auto
==============================================================================
--- 
commons/sandbox/rdf/trunk/impl.utils/src/main/java/org/apache/commons/rdf/impl/utils/DelayedNotificator.java
 (added)
+++ 
commons/sandbox/rdf/trunk/impl.utils/src/main/java/org/apache/commons/rdf/impl/utils/DelayedNotificator.java
 Sun Feb 15 18:41:15 2015
@@ -0,0 +1,112 @@
+/*
+ * 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.commons.rdf.impl.utils;
+
+import java.lang.ref.WeakReference;
+import java.util.*;
+
+import org.apache.commons.rdf.event.GraphEvent;
+import org.apache.commons.rdf.event.GraphListener;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ *
+ * @author reto
+ */
+class DelayedNotificator {
+
+    private static final Logger log = 
LoggerFactory.getLogger(DelayedNotificator.class);
+    private static Timer timer = new Timer("Event delivery timer",true);
+
+    static class ListenerHolder {
+
+        long delay;
+        List<GraphEvent> events = null;
+        WeakReference<GraphListener> listenerRef;
+
+        public ListenerHolder(GraphListener listener, long delay) {
+            this.listenerRef = new WeakReference<GraphListener>(listener);
+            this.delay = delay;
+        }
+
+        private void registerEvent(GraphEvent event) {
+            synchronized (this) {
+                if (events == null) {
+                    events = new ArrayList<GraphEvent>();
+                    events.add(event);
+                    timer.schedule(new TimerTask() {
+
+                        @Override
+                        public void run() {
+                            List<GraphEvent> eventsLocal;
+                            synchronized (ListenerHolder.this) {
+                                eventsLocal = events;
+                                events = null;
+                            }
+                            GraphListener listener = listenerRef.get();
+                            if (listener == null) {
+                                log.debug("Ignoring garbage collected 
listener");
+                            } else {
+                                try {
+                                    listener.graphChanged(eventsLocal);
+                                } catch (Exception e) {
+                                    log.warn("Exception delivering 
ImmutableGraph event", e);
+                                }
+                            }
+                        }
+                    }, delay);
+                } else {
+                    events.add(event);
+                }
+            }
+        }
+    }
+    
+    private final Map<GraphListener, ListenerHolder> map = 
Collections.synchronizedMap(
+            new WeakHashMap<GraphListener, ListenerHolder>());
+
+    void addDelayedListener(GraphListener listener, long delay) {
+        map.put(listener, new ListenerHolder(listener, delay));
+    }
+
+    /**
+     * removes a Listener, this doesn't prevent the listenerRef from receiving
+     * events alreay scheduled.
+     *
+     * @param listenerRef
+     */
+    void removeDelayedListener(GraphListener listener) {
+        map.remove(listener);
+    }
+
+    /**
+     * if the listenerRef has not been registered as delayed listenerRef te 
events is
+     * forwarded synchroneously
+     * @param event
+     */
+    void sendEventToListener(GraphListener listener, GraphEvent event) {
+        ListenerHolder holder = map.get(listener);
+        if (holder == null) {
+            listener.graphChanged(Collections.singletonList(event));
+        } else {
+            holder.registerEvent(event);
+        }
+    }
+}

Added: 
commons/sandbox/rdf/trunk/impl.utils/src/main/java/org/apache/commons/rdf/impl/utils/LockingIterator.java
URL: 
http://svn.apache.org/viewvc/commons/sandbox/rdf/trunk/impl.utils/src/main/java/org/apache/commons/rdf/impl/utils/LockingIterator.java?rev=1659973&view=auto
==============================================================================
--- 
commons/sandbox/rdf/trunk/impl.utils/src/main/java/org/apache/commons/rdf/impl/utils/LockingIterator.java
 (added)
+++ 
commons/sandbox/rdf/trunk/impl.utils/src/main/java/org/apache/commons/rdf/impl/utils/LockingIterator.java
 Sun Feb 15 18:41:15 2015
@@ -0,0 +1,73 @@
+/*
+ * 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.commons.rdf.impl.utils;
+
+import java.util.Iterator;
+import java.util.concurrent.locks.Lock;
+import java.util.concurrent.locks.ReadWriteLock;
+import org.apache.commons.rdf.Triple;
+
+/**
+ * Wrapps an iterator<Triple> reading entering a read-lock on every invocation
+ * of hasNext and next
+ * @author reto
+ */
+class LockingIterator implements Iterator<Triple> {
+
+    private Iterator<Triple> base;
+    private Lock readLock;
+    private Lock writeLock;
+
+    public LockingIterator(Iterator<Triple> iterator, ReadWriteLock lock) {
+        base = iterator;
+        readLock = lock.readLock();
+        writeLock = lock.writeLock();
+    }
+
+    @Override
+    public boolean hasNext() {
+        readLock.lock();
+        try {
+            return base.hasNext();
+        } finally {
+            readLock.unlock();
+        }
+    }
+
+    @Override
+    public Triple next() {
+        readLock.lock();
+        try {
+            return base.next();
+        } finally {
+            readLock.unlock();
+        }
+    }
+
+    @Override
+    public void remove() {
+        writeLock.lock();
+        try {
+            base.remove();
+        } finally {
+            writeLock.unlock();
+        }
+    }
+
+}

Added: 
commons/sandbox/rdf/trunk/impl.utils/src/main/java/org/apache/commons/rdf/impl/utils/PlainLiteralImpl.java
URL: 
http://svn.apache.org/viewvc/commons/sandbox/rdf/trunk/impl.utils/src/main/java/org/apache/commons/rdf/impl/utils/PlainLiteralImpl.java?rev=1659973&view=auto
==============================================================================
--- 
commons/sandbox/rdf/trunk/impl.utils/src/main/java/org/apache/commons/rdf/impl/utils/PlainLiteralImpl.java
 (added)
+++ 
commons/sandbox/rdf/trunk/impl.utils/src/main/java/org/apache/commons/rdf/impl/utils/PlainLiteralImpl.java
 Sun Feb 15 18:41:15 2015
@@ -0,0 +1,104 @@
+/*
+ * 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.commons.rdf.impl.utils;
+
+import java.io.Serializable;
+import org.apache.commons.rdf.Iri;
+
+import org.apache.commons.rdf.Language;
+import org.apache.commons.rdf.Literal;
+
+/**
+ *
+ * @author reto
+ */
+public class PlainLiteralImpl implements Literal, Serializable {
+
+    private String lexicalForm;
+    private Language language = null;
+
+    public PlainLiteralImpl(String value) {
+        if (value == null) {
+            throw new IllegalArgumentException("The literal string cannot be 
null");
+        }
+        this.lexicalForm = value;
+    }
+
+    public PlainLiteralImpl(String value, Language language) {
+        if (value == null) {
+            throw new IllegalArgumentException("The literal string cannot be 
null");
+        }
+        this.lexicalForm = value;
+        this.language = language;
+    }
+
+    @Override
+    public String getLexicalForm() {
+        return lexicalForm;
+    }
+
+    @Override
+    public boolean equals(Object otherObj) {
+        if (!(otherObj instanceof Literal)) {
+            return false;
+        }
+        Literal other = (Literal) otherObj;
+        if (!lexicalForm.equals(other.getLexicalForm())) {
+            return false;
+        }
+        if (language != null) {
+            return language.equals(other.getLanguage());
+        }
+        if (other.getLanguage() != null) {
+            return false;
+        }
+        return true;
+    }
+
+    @Override
+    public int hashCode() {
+        int hash = lexicalForm.hashCode() + XSD_STRING_HASH;
+        if (language != null) {
+            hash += language.hashCode();
+        }
+        return hash;
+    }
+
+    @Override
+    public Language getLanguage() {
+        return language;
+    }
+
+    @Override
+    public String toString() {
+        StringBuffer result = new StringBuffer();
+        result.append('\"').append(lexicalForm).append('\"');
+        if (language != null) {
+            result.append("@").append(language.toString());
+        }
+        return result.toString();
+    }
+
+    @Override
+    public Iri getDataType() {
+        return XSD_STRING;
+    }
+    private static final Iri XSD_STRING = new 
Iri("http://www.w3.org/2001/XMLSchema#string";);
+    private static final int XSD_STRING_HASH = XSD_STRING.hashCode();
+}

Added: 
commons/sandbox/rdf/trunk/impl.utils/src/main/java/org/apache/commons/rdf/impl/utils/TripleImpl.java
URL: 
http://svn.apache.org/viewvc/commons/sandbox/rdf/trunk/impl.utils/src/main/java/org/apache/commons/rdf/impl/utils/TripleImpl.java?rev=1659973&view=auto
==============================================================================
--- 
commons/sandbox/rdf/trunk/impl.utils/src/main/java/org/apache/commons/rdf/impl/utils/TripleImpl.java
 (added)
+++ 
commons/sandbox/rdf/trunk/impl.utils/src/main/java/org/apache/commons/rdf/impl/utils/TripleImpl.java
 Sun Feb 15 18:41:15 2015
@@ -0,0 +1,100 @@
+/*
+ * 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.commons.rdf.impl.utils;
+
+import org.apache.commons.rdf.BlankNodeOrIri;
+import org.apache.commons.rdf.RdfTerm;
+import org.apache.commons.rdf.Triple;
+import org.apache.commons.rdf.Iri;
+
+/**
+ *
+ * @author reto
+ */
+public class TripleImpl implements Triple {
+
+    private final BlankNodeOrIri subject;
+    private final Iri predicate;
+    private final RdfTerm object;
+
+    /**
+     * Creates a new <code>TripleImpl</code>.
+     *
+     * @param subject  the subject.
+     * @param predicate  the predicate.
+     * @param object  the object.
+     * @throws IllegalArgumentException  if an attribute is <code>null</code>.
+     */
+    public TripleImpl(BlankNodeOrIri subject, Iri predicate, RdfTerm object) {
+        if (subject == null) {
+            throw new IllegalArgumentException("Invalid subject: null");
+        } else if (predicate == null) {
+            throw new IllegalArgumentException("Invalid predicate: null");
+        } else if (object == null) {
+            throw new IllegalArgumentException("Invalid object: null");
+        }
+        this.subject = subject;
+        this.predicate = predicate;
+        this.object = object;
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (obj == null) {
+            return false;
+        }
+        if (!(obj instanceof Triple)) {
+            return false;
+        }
+        final Triple other = (Triple) obj;
+        if (!this.subject.equals(other.getSubject())) {
+            return false;
+        }
+        if (!this.predicate.equals(other.getPredicate())) {
+            return false;
+        }
+        if (!this.object.equals(other.getObject())) {
+            return false;
+        }
+        return true;
+    }
+
+    @Override
+    public int hashCode() {
+        return (subject.hashCode() >> 1) ^ predicate.hashCode() ^ 
(object.hashCode() << 1);
+    }
+
+    @Override
+    public BlankNodeOrIri getSubject() {
+        return subject;
+    }
+
+    public Iri getPredicate() {
+        return predicate;
+    }
+
+    public RdfTerm getObject() {
+        return object;
+    }
+
+    @Override
+    public String toString() {
+        return subject + " " + predicate + " " + object + ".";
+    }
+}

Added: 
commons/sandbox/rdf/trunk/impl.utils/src/main/java/org/apache/commons/rdf/impl/utils/TypedLiteralImpl.java
URL: 
http://svn.apache.org/viewvc/commons/sandbox/rdf/trunk/impl.utils/src/main/java/org/apache/commons/rdf/impl/utils/TypedLiteralImpl.java?rev=1659973&view=auto
==============================================================================
--- 
commons/sandbox/rdf/trunk/impl.utils/src/main/java/org/apache/commons/rdf/impl/utils/TypedLiteralImpl.java
 (added)
+++ 
commons/sandbox/rdf/trunk/impl.utils/src/main/java/org/apache/commons/rdf/impl/utils/TypedLiteralImpl.java
 Sun Feb 15 18:41:15 2015
@@ -0,0 +1,80 @@
+/*
+ * 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.commons.rdf.impl.utils;
+
+import java.io.Serializable;
+
+import org.apache.commons.rdf.Iri;
+import org.apache.commons.rdf.Language;
+import org.apache.commons.rdf.Literal;
+
+/**
+ *
+ * @author reto
+ */
+public class TypedLiteralImpl extends AbstractLiteral implements  Serializable 
{
+    private String lexicalForm;
+    private Iri dataType;
+    private int hashCode;
+
+    /**
+     * @param lexicalForm 
+     * @param dataType 
+     */
+    public TypedLiteralImpl(String lexicalForm, Iri dataType) {
+        this.lexicalForm = lexicalForm;
+        this.dataType = dataType;
+        this.hashCode = lexicalForm.hashCode()+dataType.hashCode();
+    }
+    
+    public Iri getDataType() {
+        return dataType;
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.clerezza.rdf.core.LiteralNode#getLexicalForm()
+     */
+    @Override
+    public String getLexicalForm() {
+        return lexicalForm;
+    }
+
+    @Override
+    public int hashCode() {
+        return hashCode;
+    }
+    
+
+    @Override
+    public String toString() {
+        StringBuffer result = new StringBuffer();
+        result.append('\"');
+        result.append(getLexicalForm());
+        result.append('\"');
+        result.append("^^");
+        result.append(getDataType());
+        return result.toString();
+    }
+
+    @Override
+    public Language getLanguage() {
+        return null;
+    }
+
+}

Added: 
commons/sandbox/rdf/trunk/impl.utils/src/main/java/org/apache/commons/rdf/impl/utils/WatchableGraphWrapper.java
URL: 
http://svn.apache.org/viewvc/commons/sandbox/rdf/trunk/impl.utils/src/main/java/org/apache/commons/rdf/impl/utils/WatchableGraphWrapper.java?rev=1659973&view=auto
==============================================================================
--- 
commons/sandbox/rdf/trunk/impl.utils/src/main/java/org/apache/commons/rdf/impl/utils/WatchableGraphWrapper.java
 (added)
+++ 
commons/sandbox/rdf/trunk/impl.utils/src/main/java/org/apache/commons/rdf/impl/utils/WatchableGraphWrapper.java
 Sun Feb 15 18:41:15 2015
@@ -0,0 +1,289 @@
+/*
+ * Copyright 2015 The Apache Software Foundation.
+ *
+ * Licensed 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.commons.rdf.impl.utils;
+
+import java.lang.ref.WeakReference;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.Set;
+import java.util.concurrent.locks.ReadWriteLock;
+import org.apache.commons.rdf.BlankNodeOrIri;
+import org.apache.commons.rdf.Graph;
+import org.apache.commons.rdf.ImmutableGraph;
+import org.apache.commons.rdf.Iri;
+import org.apache.commons.rdf.RdfTerm;
+import org.apache.commons.rdf.Triple;
+import org.apache.commons.rdf.WatchableGraph;
+import org.apache.commons.rdf.event.AddEvent;
+import org.apache.commons.rdf.event.FilterTriple;
+import org.apache.commons.rdf.event.GraphEvent;
+import org.apache.commons.rdf.event.GraphListener;
+import org.apache.commons.rdf.event.RemoveEvent;
+
+/**
+ *
+ * @author developer
+ */
+public class WatchableGraphWrapper implements WatchableGraph {
+    
+    final Graph wrapped;
+
+    public WatchableGraphWrapper(Graph wrapped) {
+        this.wrapped = wrapped;
+    }
+    
+       
+    //all listeners
+    private final Set<ListenerConfiguration> listenerConfigs = 
Collections.synchronizedSet(
+            new HashSet<ListenerConfiguration>());
+    private DelayedNotificator delayedNotificator = new DelayedNotificator();
+
+    @Override
+    public Iterator<Triple> iterator() {
+        return filter(null, null, null);
+    }
+
+    @Override
+    public boolean contains(Object o) {
+        if (!(o instanceof Triple)) {
+            return false;
+        }
+        Triple t = (Triple) o;
+        return filter(t.getSubject(), t.getPredicate(), 
t.getObject()).hasNext();
+    }
+
+    @Override
+    public Iterator<Triple> filter(BlankNodeOrIri subject, Iri predicate,
+            RdfTerm object) {
+        final Iterator<Triple> baseIter = wrapped.filter(subject, predicate, 
object);
+        return new Iterator<Triple>() {
+
+            Triple currentTriple = null;
+
+            @Override
+            public boolean hasNext() {
+                return baseIter.hasNext();
+            }
+
+            @Override
+            public Triple next() {
+                currentTriple = baseIter.next();
+                return currentTriple;
+            }
+
+            @Override
+            public void remove() {
+                baseIter.remove();
+                dispatchEvent(new RemoveEvent(WatchableGraphWrapper.this, 
currentTriple));
+            }
+        };
+    }
+
+    @Override
+    public boolean add(Triple triple) {
+        boolean success = performAdd(triple);
+        if (success) {
+            dispatchEvent(new AddEvent(this, triple));
+        }
+        return success;
+    }
+
+    /**
+     * A subclass of <code>AbstractGraph</code> should override 
+     * this method instead of <code>add</code> for Graph event support to be
+     * added.
+     * 
+     * @param e The triple to be added to the triple collection
+     * @return
+     */
+    protected boolean performAdd(Triple e) {
+        return wrapped.add(e);
+    }
+
+    @Override
+    public boolean remove(Object o) {
+        Triple triple = (Triple) o;
+        boolean success = performRemove(triple);
+        if (success) {
+            dispatchEvent(new RemoveEvent(this, triple));
+        }
+        return success;
+    }
+
+    @Override
+    public boolean removeAll(Collection<?> c) {
+        boolean modified = false;
+        for (Iterator<? extends Object> it = c.iterator(); it.hasNext();) {
+            Object object = it.next();
+            if (remove(object)) {
+                modified = true;
+            }
+        }
+        return modified;
+    }
+
+    /**
+     * A subclass of <code>AbstractGraph</code> should override 
+     * this method instead of <code>remove</code> for ImmutableGraph event 
support to be
+     * added.
+     * 
+     * @param o The triple to be removed from the triple collection
+     * @return
+     */
+    protected boolean performRemove(Triple triple) {
+        Iterator<Triple> e = filter(null, null, null);
+        while (e.hasNext()) {
+            if (triple.equals(e.next())) {
+                e.remove();
+                return true;
+            }
+        }
+        return false;
+    }
+
+    /**
+     * Dispatches a <code>GraphEvent</code> to all registered listeners for 
which
+     * the specified <code>Triple</code> matches the <code>FilterTriple</code>s
+     * of the listeners.
+     * 
+     * @param triple The Triple that was modified
+     * @param type The type of modification
+     */
+    protected void dispatchEvent(GraphEvent event) {
+        synchronized(listenerConfigs) {
+            Iterator<ListenerConfiguration> iter = listenerConfigs.iterator();
+            while (iter.hasNext()) {
+                ListenerConfiguration config = iter.next();
+                GraphListener registeredListener = config.getListener();
+                if (registeredListener == null) {
+                    iter.remove();
+                    continue;
+                }
+                if (config.getFilter().match(event.getTriple())) {
+                    delayedNotificator.sendEventToListener(registeredListener, 
event);
+                }
+            }
+        }
+    }
+
+    @Override
+    public void addGraphListener(GraphListener listener, FilterTriple filter) {
+        addGraphListener(listener, filter, 0);
+    }
+
+    @Override
+    public void addGraphListener(GraphListener listener, FilterTriple filter,
+            long delay) {
+        listenerConfigs.add(new ListenerConfiguration(listener, filter));
+        if (delay > 0) {
+            delayedNotificator.addDelayedListener(listener, delay);
+        }
+    }
+
+    @Override
+    public void removeGraphListener(GraphListener listener) {
+        synchronized(listenerConfigs) {
+            Iterator<ListenerConfiguration> iter = listenerConfigs.iterator();
+            while (iter.hasNext()) {
+                ListenerConfiguration listenerConfig = iter.next();
+                GraphListener registeredListener = 
listenerConfig.getListener();
+                if ((registeredListener == null) || 
(registeredListener.equals(listener))) {
+                    iter.remove();
+                }
+            }
+        }
+        delayedNotificator.removeDelayedListener(listener);
+    }
+
+    @Override
+    public ImmutableGraph getImmutableGraph() {
+        throw new UnsupportedOperationException("Not supported yet."); //To 
change body of generated methods, choose Tools | Templates.
+    }
+
+    @Override
+    public ReadWriteLock getLock() {
+        return wrapped.getLock();
+    }
+
+    @Override
+    public int size() {
+        return wrapped.size();
+    }
+
+    @Override
+    public boolean isEmpty() {
+        return wrapped.isEmpty();
+    }
+
+    @Override
+    public Object[] toArray() {
+        return wrapped.toArray();
+    }
+
+    @Override
+    public <T> T[] toArray(T[] a) {
+        return wrapped.toArray(a);
+    }
+
+    @Override
+    public boolean containsAll(Collection<?> c) {
+        return wrapped.containsAll(c);
+    }
+
+    @Override
+    public boolean addAll(Collection<? extends Triple> c) {
+        return wrapped.addAll(c);
+    }
+
+    @Override
+    public boolean retainAll(Collection<?> c) {
+        return wrapped.retainAll(c);
+    }
+
+    @Override
+    public void clear() {
+        wrapped.clear();
+    }
+
+    private static class ListenerConfiguration {
+
+        private WeakReference<GraphListener> listenerRef;
+        private FilterTriple filter;
+
+        private ListenerConfiguration(GraphListener listener, FilterTriple 
filter) {
+            this.listenerRef = new WeakReference<GraphListener>(listener);
+            this.filter = filter;
+        }
+
+        /**
+         * @return the listener
+         */
+        GraphListener getListener() {
+            GraphListener listener = listenerRef.get();
+            return listener;
+        }
+
+        /**
+         * @return the filter
+         */
+        FilterTriple getFilter() {
+            return filter;
+        }
+    }
+    
+}

Added: 
commons/sandbox/rdf/trunk/impl.utils/src/main/java/org/apache/commons/rdf/impl/utils/debug/ReadLockDebug.java
URL: 
http://svn.apache.org/viewvc/commons/sandbox/rdf/trunk/impl.utils/src/main/java/org/apache/commons/rdf/impl/utils/debug/ReadLockDebug.java?rev=1659973&view=auto
==============================================================================
--- 
commons/sandbox/rdf/trunk/impl.utils/src/main/java/org/apache/commons/rdf/impl/utils/debug/ReadLockDebug.java
 (added)
+++ 
commons/sandbox/rdf/trunk/impl.utils/src/main/java/org/apache/commons/rdf/impl/utils/debug/ReadLockDebug.java
 Sun Feb 15 18:41:15 2015
@@ -0,0 +1,85 @@
+/*
+ * 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.commons.rdf.impl.utils.debug;
+
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.locks.Condition;
+import java.util.concurrent.locks.ReentrantReadWriteLock.ReadLock;
+
+/**
+ *
+ * @author mir
+ */
+public class ReadLockDebug extends ReadLock {
+
+    ReentrantReadWriteLockTracker lock;
+    StackTraceElement[] stackTrace;
+
+    ReadLock readLock;
+    public ReadLockDebug(ReentrantReadWriteLockTracker lock) {
+        super(lock);
+        this.lock = lock;
+        this.readLock = lock.realReadLock();
+    }
+
+    @Override
+    public void lock() {
+        readLock.lock();
+        lock.addLockedReadLock(this);
+        stackTrace = Thread.currentThread().getStackTrace();
+    }
+
+    @Override
+    public void lockInterruptibly() throws InterruptedException {
+        readLock.lockInterruptibly();
+    }
+
+    @Override
+    public Condition newCondition() {
+        return readLock.newCondition();
+    }
+
+    @Override
+    public String toString() {
+        return readLock.toString();
+    }
+
+    @Override
+    public boolean tryLock() {
+        return readLock.tryLock();
+    }
+
+    @Override
+    public boolean tryLock(long timeout, TimeUnit unit) throws 
InterruptedException {
+        return readLock.tryLock(timeout, unit);
+    }
+
+    @Override
+    public void unlock() {
+        readLock.unlock();
+        lock.removeReadLock(this);
+        stackTrace = null;
+    }
+
+    public StackTraceElement[] getStackTrace() {
+        return stackTrace;
+    }
+
+}

Added: 
commons/sandbox/rdf/trunk/impl.utils/src/main/java/org/apache/commons/rdf/impl/utils/debug/ReentrantReadWriteLockTracker.java
URL: 
http://svn.apache.org/viewvc/commons/sandbox/rdf/trunk/impl.utils/src/main/java/org/apache/commons/rdf/impl/utils/debug/ReentrantReadWriteLockTracker.java?rev=1659973&view=auto
==============================================================================
--- 
commons/sandbox/rdf/trunk/impl.utils/src/main/java/org/apache/commons/rdf/impl/utils/debug/ReentrantReadWriteLockTracker.java
 (added)
+++ 
commons/sandbox/rdf/trunk/impl.utils/src/main/java/org/apache/commons/rdf/impl/utils/debug/ReentrantReadWriteLockTracker.java
 Sun Feb 15 18:41:15 2015
@@ -0,0 +1,133 @@
+/*
+ * 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.commons.rdf.impl.utils.debug;
+
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.Set;
+import java.util.concurrent.locks.Condition;
+import java.util.concurrent.locks.ReentrantReadWriteLock;
+
+/**
+ *
+ * @author mir
+ */
+public class ReentrantReadWriteLockTracker extends ReentrantReadWriteLock {
+
+
+    private Set<ReadLockDebug> lockedReadLocks = 
Collections.synchronizedSet(new HashSet<ReadLockDebug>());
+    private final WriteLockDebug writeLock = new WriteLockDebug(this);
+    @Override
+    protected Thread getOwner() {
+        return super.getOwner();
+    }
+
+    @Override
+    protected Collection<Thread> getQueuedReaderThreads() {
+        return super.getQueuedReaderThreads();
+    }
+
+    @Override
+    protected Collection<Thread> getQueuedThreads() {
+        return super.getQueuedThreads();
+    }
+
+    @Override
+    protected Collection<Thread> getQueuedWriterThreads() {
+        return super.getQueuedWriterThreads();
+    }
+
+    @Override
+    public int getReadHoldCount() {
+        return super.getReadHoldCount();
+    }
+
+    @Override
+    public int getReadLockCount() {
+        return super.getReadLockCount();
+    }
+
+    @Override
+    public int getWaitQueueLength(Condition condition) {
+        return super.getWaitQueueLength(condition);
+    }
+
+    @Override
+    protected Collection<Thread> getWaitingThreads(Condition condition) {
+        return super.getWaitingThreads(condition);
+    }
+
+    @Override
+    public int getWriteHoldCount() {
+        return super.getWriteHoldCount();
+    }
+
+    @Override
+    public boolean hasWaiters(Condition condition) {
+        return super.hasWaiters(condition);
+    }
+
+    @Override
+    public boolean isWriteLocked() {
+        return super.isWriteLocked();
+    }
+
+    @Override
+    public boolean isWriteLockedByCurrentThread() {
+        return super.isWriteLockedByCurrentThread();
+    }
+
+    @Override
+    public ReadLock readLock() {
+        return new ReadLockDebug(this);
+    }
+
+    ReadLock realReadLock() {
+        return super.readLock();
+    }
+
+    WriteLock realWriteLock() {
+        return super.writeLock();
+    }
+
+    @Override
+    public String toString() {
+        return super.toString();
+    }
+
+    @Override
+    public WriteLockDebug writeLock() {
+        return writeLock;
+    }
+
+    void addLockedReadLock(ReadLockDebug lock) {
+        lockedReadLocks.add(lock);
+    }
+
+    void removeReadLock(ReadLockDebug lock) {
+        lockedReadLocks.remove(lock);
+    }
+
+    public Set<ReadLockDebug> getLockedReadLocks() {
+        return lockedReadLocks;
+    }
+
+
+}

Added: 
commons/sandbox/rdf/trunk/impl.utils/src/main/java/org/apache/commons/rdf/impl/utils/debug/WriteLockDebug.java
URL: 
http://svn.apache.org/viewvc/commons/sandbox/rdf/trunk/impl.utils/src/main/java/org/apache/commons/rdf/impl/utils/debug/WriteLockDebug.java?rev=1659973&view=auto
==============================================================================
--- 
commons/sandbox/rdf/trunk/impl.utils/src/main/java/org/apache/commons/rdf/impl/utils/debug/WriteLockDebug.java
 (added)
+++ 
commons/sandbox/rdf/trunk/impl.utils/src/main/java/org/apache/commons/rdf/impl/utils/debug/WriteLockDebug.java
 Sun Feb 15 18:41:15 2015
@@ -0,0 +1,89 @@
+/*
+ * 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.commons.rdf.impl.utils.debug;
+
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.locks.Condition;
+import java.util.concurrent.locks.ReentrantReadWriteLock.WriteLock;
+
+/**
+ *
+ * @author mir
+ */
+public class WriteLockDebug extends WriteLock {
+
+    private ReentrantReadWriteLockTracker lock;
+    private WriteLock writeLock;
+    private StackTraceElement[] stackTrace;
+
+    public WriteLockDebug(ReentrantReadWriteLockTracker lock) {
+        super(lock);
+        this.lock = lock;
+        this.writeLock = lock.realWriteLock();
+    }
+
+    @Override
+    public int getHoldCount() {
+        return writeLock.getHoldCount();
+    }
+
+    @Override
+    public boolean isHeldByCurrentThread() {
+        return writeLock.isHeldByCurrentThread();
+    }
+
+    @Override
+    public void lock() {
+        writeLock.lock();
+        stackTrace = Thread.currentThread().getStackTrace();
+    }
+
+    @Override
+    public void lockInterruptibly() throws InterruptedException {
+        writeLock.lockInterruptibly();
+    }
+
+    @Override
+    public Condition newCondition() {
+        return writeLock.newCondition();
+    }
+
+    @Override
+    public boolean tryLock() {
+        return writeLock.tryLock();
+    }
+
+    @Override
+    public boolean tryLock(long timeout, TimeUnit unit) throws 
InterruptedException {
+        return writeLock.tryLock(timeout, unit);
+    }
+
+    @Override
+    public void unlock() {
+        writeLock.unlock();
+        stackTrace = null;
+    }
+
+    public StackTraceElement[] getStackTrace() {
+        return stackTrace;
+    }
+
+
+}


Reply via email to