Hello Reto,

how does this relate to github Commons RDF? Is this part of the code base
proposed for incubation?

Regards,
Benedikt

2015-02-15 19:41 GMT+01:00 <r...@apache.org>:

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


-- 
http://people.apache.org/~britter/
http://www.systemoutprintln.de/
http://twitter.com/BenediktRitter
http://github.com/britter

Reply via email to