<|start_filename|>api/src/main/java/org/apache/clerezza/Literal.java<|end_filename|>
/*
 * 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.clerezza;

/**
 * Represents a literal value that can be a node in an RDF Graph.
 * Literals are used to identify values such as numbers and dates by
 * means of a lexical representation. There are two types of literals
 * represented by the subinterfaces {@link PlainLiteral}
 * and {@link TypedLiteral}
 *
 * @author reto
 */
public interface Literal extends RDFTerm {

    /**
     * The lexical form of this literal, represented by a <a
     * href="http://www.unicode.org/versions/latest/">Unicode string</a>.
     *
     * @return The lexical form of this literal.
     * @see <a
     * href="http://www.w3.org/TR/rdf11-concepts/#dfn-lexical-form">RDF-1.1
     * Literal lexical form</a>
     */
    String getLexicalForm();

    /**
     * The IRI identifying the datatype that determines how the lexical form
     * maps to a literal value.
     *
     * @return The datatype IRI for this literal.
     * @see <a
     * href="http://www.w3.org/TR/rdf11-concepts/#dfn-datatype-iri">RDF-1.1
     * Literal datatype IRI</a>
     */
    IRI getDataType();

    /**
     * If and only if the datatype IRI is <a
     * href="http://www.w3.org/1999/02/22-rdf-syntax-ns#langString"
     * >http://www.w3.org/1999/02/22-rdf-syntax-ns#langString</a>, the language
     * tag for this Literal is a language tag as defined by <a
     * href="http://tools.ietf.org/html/bcp47">BCP47</a>.<br>
     * If the datatype IRI is not <a
     * href="http://www.w3.org/1999/02/22-rdf-syntax-ns#langString"
     * >http://www.w3.org/1999/02/22-rdf-syntax-ns#langString</a>, this method
     * must null.
     *
     * @return The language tag of the literal or null if no language tag is defined
     * @see <a
     * href="http://www.w3.org/TR/rdf11-concepts/#dfn-language-tag">RDF-1.1
     * Literal language tag</a>
     */
    public Language getLanguage();

    /**
     * Returns true if <code>obj</code> is an instance of
     * <code>literal</code> that is term-equal with this, false otherwise
     * <p>
     * Two literals are term-equal (the same RDF literal) if and only if the
     * two lexical forms, the two datatype IRIs, and the two language tags (if
     * any) compare equal, character by character.
     *
     * @return true if obj equals this, false otherwise.
     */
    public boolean equals(Object obj);

    /**
     * Returns the hash code of the lexical form plus the hash code of the
     * datatype plus if the literal has a language the hash code of the
     * language.
     *
     * @return hash code
     */
    public int hashCode();
}


<|start_filename|>api-implementation/src/main/java/org/apache/clerezza/implementation/graph/PrivilegedGraphWrapper.java<|end_filename|>
/*
 * 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.clerezza.implementation.graph;

import org.apache.clerezza.*;
import org.apache.clerezza.implementation.in_memory.SimpleImmutableGraph;

import java.security.AccessController;
import java.security.PrivilegedAction;
import java.util.Collection;
import java.util.Iterator;
import java.util.concurrent.locks.ReadWriteLock;

/**
 * Calls the methods of the wrapped <code>Graph</code> as privileged
 * code, because they may need permissions like writing to disk or accessing
 * network.
 *
 * @author mir
 */
public class PrivilegedGraphWrapper implements Graph {

    private Graph graph;

    public PrivilegedGraphWrapper(Graph Graph) {
        this.graph = Graph;
    }

    @Override
    public Iterator<Triple> filter(final BlankNodeOrIRI subject, final IRI predicate,
                                   final RDFTerm object) {
        return AccessController.doPrivileged(new PrivilegedAction<Iterator<Triple>>() {

            @Override
            public Iterator<Triple> run() {
                return graph.filter(subject, predicate, object);
            }
        });
    }

    @Override
    public int size() {
        return AccessController.doPrivileged(new PrivilegedAction<Integer>() {

            @Override
            public Integer run() {
                return graph.size();
            }
        });
    }

    @Override
    public boolean isEmpty() {
        return AccessController.doPrivileged(new PrivilegedAction<Boolean>() {

            @Override
            public Boolean run() {
                return graph.isEmpty();
            }
        });
    }

    @Override
    public boolean contains(final Object o) {
        return AccessController.doPrivileged(new PrivilegedAction<Boolean>() {

            @Override
            public Boolean run() {
                return graph.contains(o);
            }
        });
    }

    @Override
    public Iterator<Triple> iterator() {
        return AccessController.doPrivileged(new PrivilegedAction<Iterator<Triple>>() {

            @Override
            public Iterator<Triple> run() {
                return graph.iterator();
            }
        });
    }

    @Override
    public Object[] toArray() {
        return AccessController.doPrivileged(new PrivilegedAction<Object[]>() {

            @Override
            public Object[] run() {
                return graph.toArray();
            }
        });
    }

    @Override
    public <T> T[] toArray(final T[] a) {
        return AccessController.doPrivileged(new PrivilegedAction<T[]>() {

            @Override
            public T[] run() {
                return graph.toArray(a);
            }
        });
    }

    @Override
    public boolean add(final Triple triple) {
        return AccessController.doPrivileged(new PrivilegedAction<Boolean>() {

            @Override
            public Boolean run() {
                return graph.add(triple);
            }
        });
    }

    @Override
    public boolean remove(final Object o) {
        return AccessController.doPrivileged(new PrivilegedAction<Boolean>() {

            @Override
            public Boolean run() {
                return graph.remove(o);
            }
        });
    }

    @Override
    public boolean containsAll(final Collection<?> c) {
        return AccessController.doPrivileged(new PrivilegedAction<Boolean>() {

            @Override
            public Boolean run() {
                return graph.containsAll(c);
            }
        });
    }

    @Override
    public boolean addAll(final Collection<? extends Triple> c) {
        return AccessController.doPrivileged(new PrivilegedAction<Boolean>() {

            @Override
            public Boolean run() {
                return graph.addAll(c);
            }
        });
    }

    @Override
    public boolean removeAll(final Collection<?> c) {
        return AccessController.doPrivileged(new PrivilegedAction<Boolean>() {

            @Override
            public Boolean run() {
                return graph.removeAll(c);
            }
        });
    }

    @Override
    public boolean retainAll(final Collection<?> c) {
        return AccessController.doPrivileged(new PrivilegedAction<Boolean>() {

            @Override
            public Boolean run() {
                return graph.retainAll(c);
            }
        });
    }

    @Override
    public void clear() {
        AccessController.doPrivileged(new PrivilegedAction<Object>() {

            @Override
            public Object run() {
                graph.clear();
                return null;
            }
        });
    }

    @Override
    public ReadWriteLock getLock() {
        return graph.getLock();
    }

    private static class PriviledgedTripleIterator implements Iterator<Triple> {

        private final Iterator<Triple> wrappedIterator;

        public PriviledgedTripleIterator(Iterator<Triple> wrappedIterator) {
            this.wrappedIterator = wrappedIterator;
        }

        @Override
        public boolean hasNext() {
            return AccessController.doPrivileged(new PrivilegedAction<Boolean>() {

                @Override
                public Boolean run() {
                    return wrappedIterator.hasNext();
                }
            });
        }

        @Override
        public Triple next() {
            return AccessController.doPrivileged(new PrivilegedAction<Triple>() {

                @Override
                public Triple run() {
                    return wrappedIterator.next();
                }
            });
        }

        @Override
        public void remove() {
            AccessController.doPrivileged(new PrivilegedAction<Object>() {

                @Override
                public Object run() {
                    wrappedIterator.remove();
                    return null;
                }
            });
        }
    }


    @Override
    public ImmutableGraph getImmutableGraph() {
        return new SimpleImmutableGraph(this);
    }
}


<|start_filename|>sparql/src/main/java/org/apache/clerezza/sparql/GraphStore.java<|end_filename|>
package org.apache.clerezza.sparql;

import org.apache.clerezza.IRI;

import java.util.Set;

public interface GraphStore {

    /**
     * Lists the name of the <Code>Graph</code>s available through this <code>GraphStore</code>.
     *
     * @return the list of <Code>Graph</code>s
     */
    Set<IRI> listGraphs();

    /**
     * Lists the name of the named <Code>Graph</code>s available through this <code>GraphStore</code>.
     *
     * @return the list of named <Code>Graph</code>s
     */
    Set<IRI> listNamedGraphs();
}


<|start_filename|>test.utils/src/main/java/org/apache/clerezza/test/utils/RandomGraph.java<|end_filename|>
/*
 * 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.clerezza.test.utils;

import org.apache.clerezza.*;
import org.apache.clerezza.implementation.TripleImpl;
import org.apache.clerezza.implementation.literal.PlainLiteralImpl;
import org.apache.commons.lang.RandomStringUtils;

import java.util.Iterator;
import java.util.UUID;

/**
 * A <code>Graph</code> wrapper that allows growing and shrinking of
 * the wrapped mgraph.
 *
 * @author mir
 */
public class RandomGraph extends GraphWrapper {
    
    private int interconnectivity = 2;

    public RandomGraph(Graph mGraph, int interconnectivity) {
        super(mGraph);
        this.interconnectivity = interconnectivity;
    }

    /**
     * Creates a new random mutual graph.
     *
     * @param initialSize Determines the initial size of the content graph
     * @param interconnectivity Determines the probability of using already existing
     *        resource when creating a new triple. The probability of using an existing
     *        resource over creating a new resouce is 1-(1/interconnectivity).
     * @param mGraph
     */
    public RandomGraph(int initialSize, int interconnectivity, Graph mGraph) {
        super(mGraph);
        if (interconnectivity <= 0) {
            throw new IllegalArgumentException("growth speed and the interconnectivity "
                    + "value have to be equals or highter one");
        }
        this.interconnectivity = interconnectivity;

        setupInitialSize(initialSize);
    }

    /**
     * Add or removes randomly a triple.
     *
     * @return the triple that was added or removed.
     */
    public Triple evolve() {
        Triple triple;
        int random = rollDice(2);
        if (random == 0 && size() != 0) {
            triple = getRandomTriple();
            remove(triple);
        } else {
            triple = createRandomTriple();
            add(triple);
        }
        return triple;
    }

    /**
     * Removes a random triple.
     *
     * @return the triple that was removed.
     */
    public Triple removeRandomTriple() {
        Triple randomTriple = getRandomTriple();
        remove(randomTriple);
        return randomTriple;
    }

    /**
     * Adds a random triple.
     *
     * @return the triple that was added.
     */
    public Triple addRandomTriple() {
        Triple randomTriple;
        do {
         randomTriple = createRandomTriple();
        } while(contains(randomTriple));
        
        add(randomTriple);
        return randomTriple;
    }
    
    private Triple createRandomTriple() {
        return new TripleImpl(getSubject(), getPredicate(), getObject());
    }

    private BlankNodeOrIRI getSubject() {
        int random = rollDice(interconnectivity);
        if (size() == 0) {
            random = 0;
        }
        switch (random) {
            case 0: // create new BlankNodeOrIRI
                RDFTerm newRDFTerm;
                do {
                    newRDFTerm = createRandomRDFTerm();
                } while (!(newRDFTerm instanceof BlankNodeOrIRI));
                return (BlankNodeOrIRI) newRDFTerm;
            default: // get existing BlankNodeOrIRI
                RDFTerm existingRDFTerm;
                do {
                    existingRDFTerm = getExistingRDFTerm();
                    if (existingRDFTerm == null) {
                        random = 0;
                    }
                } while (!(existingRDFTerm instanceof BlankNodeOrIRI));

                return (BlankNodeOrIRI) existingRDFTerm;
        }
    }

    private IRI getPredicate() {
        int random = rollDice(interconnectivity);
        if (size() == 0) {
            random = 0;
        }
        switch (random) {
            case 0: // create new IRI
                return createRandomIRI();
            default: // get existing IRI
                RDFTerm existingRDFTerm;
                do {
                    existingRDFTerm = getExistingRDFTerm();
                    if (existingRDFTerm == null) {
                        random = 0;
                    }
                } while (!(existingRDFTerm instanceof IRI));
                return (IRI) existingRDFTerm;
        }
    }

    private RDFTerm getObject() {
        int random = rollDice(interconnectivity);
        if (size() == 0) {
            random = 0;
        }        
        switch (random) {
            case 0: // create new resource
                return createRandomRDFTerm();
            default: // get existing resource
                RDFTerm existingRDFTerm = getExistingRDFTerm();
                if (existingRDFTerm == null) {
                    random = 0;
                }
                return existingRDFTerm;
        }
    }

    private static int rollDice(int faces) {
        return (int) (Math.random() * faces);
    }

    private RDFTerm createRandomRDFTerm() {
        switch (rollDice(3)) {
            case 0:
                return new BlankNode();
            case 1:
                return createRandomIRI();
            case 2:
                return new PlainLiteralImpl(RandomStringUtils.random(rollDice(100) + 1));
        }
        throw new RuntimeException("in createRandomRDFTerm()");
    }

    private RDFTerm getExistingRDFTerm() {
        Triple triple = getRandomTriple();
        if (triple == null) {
            return null;
        }
        switch (rollDice(3)) {
            case 0:
                return triple.getSubject();
            case 1:
                return triple.getPredicate();
            case 2:
                return triple.getObject();
        }
        return null;
    }

    private IRI createRandomIRI() {
        return new IRI("http://" + UUID.randomUUID().toString());
    }

    /**
     * Returns a random triple contained in the Graph.
     */
    public Triple getRandomTriple() {
        int size = this.size();
        if (size == 0) {
            return null;
        }
        Iterator<Triple> triples = iterator();
        while (triples.hasNext()) {
            Triple triple = triples.next();
            if (rollDice(this.size()) == 0) {
                return triple;
            }
        }
        return getRandomTriple();
    }

    private void setupInitialSize(int initialSize) {
        for (int i = 0; i < initialSize; i++) {
            addRandomTriple();
        }
    }
}


<|start_filename|>sparql/src/main/java/org/apache/clerezza/sparql/query/GroupGraphPattern.java<|end_filename|>
/*
 * 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.clerezza.sparql.query;

import org.apache.clerezza.IRI;

import java.util.List;
import java.util.Set;

/**
 * Defines a group ImmutableGraph pattern.
 * @see <a href="http://www.w3.org/TR/rdf-sparql-query/#GroupPatterns">
 * SPARQL Query Language: 5.2 Group ImmutableGraph Patterns</a>
 *
 * @author hasan
 */
public interface GroupGraphPattern extends GraphPattern {

	/**
	 *
	 * @return 
     *      true if it wraps a {@link SelectQuery}, false otherwise.
	 */
	public boolean isSubSelect();

	/**
	 *
	 * @return 
     *      the wrapped subselect if it wraps a {@link SelectQuery}, null otherwise.
	 */
	public SelectQuery getSubSelect();

	/**
	 *
	 * @return
     *      null if it wraps a {@link SelectQuery}, otherwise
     *      a set of all patterns, ANDed together.
	 */
	public Set<GraphPattern> getGraphPatterns();

    /**
     * 
     * @return
     *      all graphs referred in this ImmutableGraph pattern.
     */
    public Set<IRI> getReferredGraphs();

    /**
	 * @return 
     *      null if it wraps a {@link SelectQuery}, otherwise
	 *		a list of filter expressions for all patterns in the group if any.
	 */
	public List<Expression> getFilter();
}


<|start_filename|>api-implementation/src/main/java/org/apache/clerezza/implementation/graphmatching/collections/IntSet.java<|end_filename|>
/*
 * Copyright 2002-2004 The Apache Software Foundation.
 *
 * 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.clerezza.implementation.graphmatching.collections;

import java.util.Set;

/**
 * A IntSet allows directly adding primitive ints to a set, Set<Integer> is
 * extended, but accessingt he respective methods is less efficient.
 *
 * @author reto
 */
public interface IntSet extends Set<Integer> {
    /**
     * @return an iterator over the primitive int
     */
    public IntIterator intIterator();

    public void add(int i);
}


<|start_filename|>api-implementation/src/main/java/org/apache/clerezza/implementation/graphmatching/PermutationIterator.java<|end_filename|>
/*
 * 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.clerezza.implementation.graphmatching;

import java.util.*;

/**
 * An Iterator over all permuations of a list.
 *
 * @author reto
 */
class PermutationIterator<T> implements Iterator<List<T>> {

    private Iterator<List<T>> restIterator;
    private List<T> list;
    private List<T> next;
    int posInList = 0; //the position of the last element of next returned list
    //with list, this is the one excluded from restIterator

    PermutationIterator(List<T> list) {
        this.list = Collections.unmodifiableList(list);
        if (list.size() > 1) {
            createRestList();
        }
        prepareNext();
    }

    @Override
    public boolean hasNext() {
        return next != null;
    }

    @Override
    public List<T> next() {
        List<T> result = next;
        if (result == null) {
            throw new NoSuchElementException();
        }
        prepareNext();
        return result;
    }

    @Override
    public void remove() {
        throw new UnsupportedOperationException("Not supported");
    }

    private void createRestList() {
        List<T> restList = new ArrayList<T>(list);
        restList.remove(posInList);
        restIterator = new PermutationIterator<T>(restList);
    }

    private void prepareNext() {
        next = getNext();

    }

    private List<T> getNext() {
        if (list.size() == 0) {
            return null;
        }
        if (list.size() == 1) {
            if (posInList++ == 0) {
                return new ArrayList<T>(list);
            } else {
                return null;
            }
        } else {
            if (!restIterator.hasNext()) {
                if (posInList < (list.size() - 1)) {
                    posInList++;
                    createRestList();
                } else {
                    return null;
                }
            }
            List<T> result = restIterator.next();
            result.add(list.get(posInList));
            return result;
        }
    }

}


<|start_filename|>api-implementation/src/main/java/org/apache/clerezza/implementation/debug/ReadLockDebug.java<|end_filename|>
/*
 * 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.clerezza.implementation.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;
    }

}


<|start_filename|>api/src/main/java/org/apache/clerezza/WatchableGraph.java<|end_filename|>
/*
 * 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.clerezza;

import org.apache.clerezza.event.FilterTriple;
import org.apache.clerezza.event.GraphListener;

/**
 * An extension to the Graph interface that allows to add throws events
 * on modifications.
 *
 * @author reto
 */
public interface WatchableGraph extends Graph {


    /**
     * Adds the specified <code>GraphListener</code> to the graph. This listener
     * will be notified, when the graph is modified and the <code>Triple</code>
     * that was part of the modifiaction matched the specified
     * <code>FilterTriple</code>. The notification will be passed to the
     * listener after the specified delay time (in milli-seconds) has passed.
     * If more matching events occur during the delay period, then they are
     * passed all together at the end of the delay period. If the the listener
     * unregisters or the platform is stopped within the period then the already
     * occurred events may not be delivered.
     * <p>
     * All implementations support this method, immutable implementations will
     * typically provide an empty implementation, they shall not throw an
     * exception.
     * <p>
     * Implementation of which the triples change over time without add- and
     * remove-methods being called (e.g. implementation dynamically generating
     * their triples on invocation of the filer-method) may choose not to, or
     * only partially propagate their changes to the listener. They should
     * describe the behavior in the documentation of the class.
     * <p>
     * Implementations should keep weak references the listeners, so that the
     * listener can be garbage collected if its no longer referenced by another
     * object.
     * <p>
     * If delay is 0 notification will happen synchroneously.
     *
     * @param listener The listener that will be notified
     * @param filter   The triple filter with which triples are tested,
     *                 that were part of the modification.
     * @param delay    The time period afer which the listener will be notified in milliseconds.
     */
    public void addGraphListener(GraphListener listener, FilterTriple filter,
                                 long delay);

    /**
     * Adds the specified <code>GraphListener</code> to the graph. This listener
     * will be notified, when the graph is modified and the <code>Triple</code>
     * that was part of the modifiaction matched the specified
     * <code>FilterTriple</code>. The notification will be passed without delay.
     * <p>
     * Same as <code>addGraphListener(listener, filter, 0).
     *
     * @param listener The listener that will be notified
     * @param filter   The triple filter with which triples are tested,
     *                 that were part of the modification.
     */
    public void addGraphListener(GraphListener listener, FilterTriple filter);

    /**
     * Removes the specified <code>GraphListener</code> from the graph. This
     * listener will no longer be notified, when the graph is modified.
     *
     * @param listener The listener to be removed.
     */
    public void removeGraphListener(GraphListener listener);
}


<|start_filename|>sparql/src/main/java/org/apache/clerezza/sparql/query/PatternExistenceCondition.java<|end_filename|>
/*
 * 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.clerezza.sparql.query;

import java.util.ArrayList;
import java.util.List;

/**
 * This expression is intended to be used as a filter expression to test whether a ImmutableGraph pattern matches 
 * the dataset or not, given the values of variables in the group ImmutableGraph pattern in which the filter occurs.
 * It does not generate any additional bindings.
 * 
 * @see <a href="http://www.w3.org/TR/sparql11-query/#neg-pattern">SPARQL 1.1 Query Language: 8.1 Filtering Using ImmutableGraph Patterns</a>
 * 
 * @author hasan
 */
public class PatternExistenceCondition extends BuiltInCall {
    private boolean negated = false;
    private GroupGraphPattern pattern;

    public PatternExistenceCondition() {
        super("EXISTS", new ArrayList<Expression>());
    }

    public PatternExistenceCondition(String name, List<Expression> arguments) {
        super(name, new ArrayList<Expression>());
        if (!(name.equalsIgnoreCase("EXISTS") || name.equalsIgnoreCase("NOT EXISTS"))) {
            throw new RuntimeException("Unsupported name: " + name);
        } else {
            this.negated = name.equalsIgnoreCase("NOT EXISTS");
        }
    }

    public boolean isExistenceTest() {
        return !negated;
    }

    public GroupGraphPattern getPattern() {
        return pattern;
    }

    public void setExistenceTest(boolean existenceTest) {
        this.negated = !existenceTest;
        this.name = existenceTest ? "EXISTS" : "NOT EXISTS";
    }

    public void setPattern(GroupGraphPattern pattern) {
        this.pattern = pattern;
    }
}


<|start_filename|>api.utils/src/main/java/org/apache/clerezza/utils/IRIUtil.java<|end_filename|>
/*
 * 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.clerezza.utils;

/**
 * A utility class for IRI and String manipulations.
 *
 * @author tio
 */
public class IRIUtil {

    /**
     * Strips #x00 - #x1F and #x7F-#x9F from a Unicode string
     *
     * @param inputChars
     * @return the stripped string
     * @see <a href="http://www.w3.org/TR/rdf-concepts/#dfn-URI-reference">
     * http://www.w3.org/TR/rdf-concepts/#dfn-URI-reference</a> and
     * replaces all US-ASCII space character with a "+".
     */
    public static String stripNonIRIChars(CharSequence inputChars) {

        if (inputChars == null) {
            return "";
        }

        StringBuffer buffer = new StringBuffer();

        for (int i = 0; i < inputChars.length(); i++) {
            char c = inputChars.charAt(i);

            if (!isIllegal(c)) {
                buffer.append(c);
            }
        }
        return buffer.toString().replaceAll("\\s+", "+");
    }

    private static boolean isIllegal(char ch) {
        if ((ch >= 0x7F) && (ch <= 0x9F)) {
            return true;
        }
        return false;
    }
}


<|start_filename|>api/src/main/java/org/apache/clerezza/event/RemoveEvent.java<|end_filename|>
/*
 * 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.clerezza.event;

import org.apache.clerezza.Graph;
import org.apache.clerezza.Triple;

/**
 * This class represent a removal event that occured on a
 * <code>TripleCollection</code>.
 *
 * @author rbn
 */
public class RemoveEvent extends GraphEvent {

    public RemoveEvent(Graph graph, Triple triple) {
        super(graph, triple);
    }
}


<|start_filename|>test.utils/src/main/java/org/apache/clerezza/test/utils/LockingIteratorForTesting.java<|end_filename|>
/*
 * 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.clerezza.test.utils;

import org.apache.clerezza.Triple;

import java.util.Iterator;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantReadWriteLock;

/**
 * Wrapps an iterator<Triple> reading all elements to a cache on construction
 * and returning them from that cache.
 * @author reto
 */
class LockingIteratorForTesting implements Iterator<Triple> {

    private Iterator<Triple> base;
    private Lock readLock;
    private Lock writeLock;
    private ReentrantReadWriteLock lock;

    public LockingIteratorForTesting(Iterator<Triple> iterator, ReentrantReadWriteLock lock) {
        base = iterator;
        readLock = lock.readLock();
        writeLock = lock.writeLock();
        this.lock = lock;
    }

    @Override
    public boolean hasNext() {
        LockChecker.checkIfReadLocked(lock);
        readLock.lock();
        try {
            return base.hasNext();
        } finally {
            readLock.unlock();
        }
    }

    @Override
    public Triple next() {
        LockChecker.checkIfReadLocked(lock);
        readLock.lock();
        try {
            return base.next();
        } finally {
            readLock.unlock();
        }
    }

    @Override
    public void remove() {
        LockChecker.checkIfWriteLocked(lock);
        writeLock.lock();
        try {
            base.remove();
        } finally {
            writeLock.unlock();
        }
    }


}


<|start_filename|>jaxrs.rdf.providers/src/main/java/org/apache/clerezza/jaxrs/sparql/providers/ResultSetJsonMessageBodyWriter.java<|end_filename|>
/*
 * 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.clerezza.jaxrs.sparql.providers;

import org.apache.clerezza.*;
import org.apache.clerezza.sparql.ResultSet;
import org.apache.clerezza.sparql.SolutionMapping;
import org.apache.clerezza.sparql.query.Variable;
import org.json.simple.JSONArray;
import org.json.simple.JSONObject;
import org.osgi.service.component.annotations.Component;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.ws.rs.Produces;
import javax.ws.rs.WebApplicationException;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.MultivaluedMap;
import javax.ws.rs.ext.MessageBodyWriter;
import javax.ws.rs.ext.Provider;
import java.io.IOException;
import java.io.OutputStream;
import java.lang.annotation.Annotation;
import java.lang.reflect.Type;
import java.util.List;
import java.util.Set;

/**
 * MessageBodyWirter for <code>ResultSet</code>.
 * Resulting output conforms to:
 * http://www.w3.org/TR/2007/NOTE-rdf-sparql-json-res-20070618/
 *
 * @author misl
 */
@Component(service = Object.class, property = {"javax.ws.rs=true"})
@Produces({"application/json", "application/sparql-results+json"})
@Provider
@SuppressWarnings("unchecked")
public class ResultSetJsonMessageBodyWriter implements MessageBodyWriter<ResultSet> {

    final Logger logger = LoggerFactory.getLogger(ResultSetJsonMessageBodyWriter.class);

    @Override
    public boolean isWriteable(Class<?> type, Type genericType, Annotation[] annotations,
                               MediaType mediaType) {
        return ResultSet.class.isAssignableFrom(type);
    }

    @Override
    public long getSize(ResultSet t, Class<?> type, Type genericType,
                        Annotation[] annotations, MediaType mediaType) {
        return -1;
    }

    @Override
    public void writeTo(ResultSet resultSet, Class<?> type, Type genericType,
                        Annotation[] annotations, MediaType mediaType, MultivaluedMap<String,
            Object> httpHeaders, OutputStream entityStream) throws IOException, WebApplicationException {

        JSONObject json = toJsonSource(resultSet);
        entityStream.write(json.toJSONString().getBytes("UTF-8"));
    }

    /**
     * Helper: transforms a {@link ResultSet} or a {@link Boolean} to a
     * json object.
     *
     * @param queryResult
     */
    private JSONObject toJsonSource(ResultSet queryResult) {
        JSONObject root = new JSONObject();
        JSONObject head = new JSONObject();
        root.put("head", head);
        createVariables(queryResult.getResultVars(), head);

        JSONObject results = new JSONObject();
        root.put("results", results);

        JSONArray bindings = null;
        while (queryResult.hasNext()) {
            if (bindings == null) {
                bindings = new JSONArray();
                results.put("bindings", bindings);
            }
            bindings.add(createResult(queryResult.next()));
        }

        return root;
    }

    /**
     * Helper: creates value element from {@link RDFTerm} depending on its
     * class
     */
    private JSONObject createResultElement(RDFTerm resource) {
        JSONObject element = new JSONObject();
        if (resource instanceof IRI) {
            element.put("type", "uri");
            element.put("value", IRI.class.cast(resource).getUnicodeString());
        } else if (resource instanceof Literal) {
            element.put("type", "literal");
            element.put("value", Literal.class.cast(resource).getLexicalForm());
            Language lang = Literal.class.cast(resource).getLanguage();
            if (lang != null) {
                element.put("xml:lang", lang.toString());
            }
        } else if (resource instanceof Literal) {
            element.put("type", "typed-literal");
            element.put("datatype", Literal.class.cast(resource).getDataType().getUnicodeString());
            element.put("value", Literal.class.cast(resource).getLexicalForm());
        } else if (resource instanceof BlankNode) {
            element.put("type", "bnode");
            element.put("value", "/");
        } else {
            element = null;
        }
        return element;
    }

    /**
     * Helper: creates results element from ResultSet
     */
    private JSONObject createResult(SolutionMapping solutionMap) {
        JSONObject result = new JSONObject();
        Set<Variable> keys = solutionMap.keySet();
        for (Variable key : keys) {
            result.put(key.getName(), createResultElement((RDFTerm) solutionMap.get(key)));
        }
        return result;
    }

    private void createVariables(List<String> variables, JSONObject head) {
        JSONArray vars = null;
        for (String variable : variables) {
            if (vars == null) {
                vars = new JSONArray();
                head.put("vars", vars);
            }
            vars.add(variable);
        }
    }
}


<|start_filename|>jaxrs.rdf.providers/src/main/java/org/apache/clerezza/jaxrs/rdf/providers/GraphWriter.java<|end_filename|>
/*
 * 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.clerezza.jaxrs.rdf.providers;

import org.apache.clerezza.Graph;
import org.apache.clerezza.representation.Serializer;
import org.apache.clerezza.representation.SupportedFormat;
import org.osgi.service.component.annotations.Component;
import org.osgi.service.component.annotations.Reference;

import javax.ws.rs.Produces;
import javax.ws.rs.WebApplicationException;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.MultivaluedMap;
import javax.ws.rs.ext.MessageBodyWriter;
import javax.ws.rs.ext.Provider;
import java.io.IOException;
import java.io.OutputStream;
import java.lang.annotation.Annotation;
import java.lang.reflect.Type;
import java.util.Objects;

@Component(service = Object.class, property = {"javax.ws.rs=true"})
@Provider
@Produces({SupportedFormat.N3, SupportedFormat.N_TRIPLE,
        SupportedFormat.RDF_XML, SupportedFormat.TURTLE,
        SupportedFormat.X_TURTLE, SupportedFormat.RDF_JSON})
public class GraphWriter implements MessageBodyWriter<Graph> {

    private Serializer serializer = Serializer.getInstance();

    @Reference
    public synchronized void setSerializer(Serializer serializer) {
        this.serializer = serializer;
    }

    public synchronized void unsetSerializer(Serializer serializer) {
        if (Objects.equals(this.serializer, serializer)) {
            this.serializer = Serializer.getInstance();
        }
    }

    @Override
    public boolean isWriteable(Class<?> type, Type genericType,
                               Annotation[] annotations, MediaType mediaType) {
        return Graph.class.isAssignableFrom(type);
    }

    @Override
    public long getSize(Graph t, Class<?> type, Type genericType,
                        Annotation[] annotations, MediaType mediaType) {
        return -1;
    }

    @Override
    public void writeTo(Graph t, Class<?> type, Type genericType,
                        Annotation[] annotations, MediaType mediaType,
                        MultivaluedMap<String, Object> httpHeaders,
                        OutputStream entityStream) throws IOException, WebApplicationException {
        serializer.serialize(entityStream, t, mediaType.toString());
    }
}


<|start_filename|>api.utils/src/test/java/org/apache/clerezza/utils/IfpSmushTest.java<|end_filename|>
/*
 * 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.clerezza.utils;

import org.apache.clerezza.BlankNode;
import org.apache.clerezza.Graph;
import org.apache.clerezza.IRI;
import org.apache.clerezza.implementation.TripleImpl;
import org.apache.clerezza.implementation.in_memory.SimpleGraph;
import org.apache.clerezza.implementation.literal.PlainLiteralImpl;
import org.apache.clerezza.ontologies.FOAF;
import org.apache.clerezza.ontologies.OWL;
import org.apache.clerezza.ontologies.RDF;
import org.apache.clerezza.ontologies.RDFS;
import org.junit.Assert;
import org.junit.Test;

/**
 * @author reto
 */
public class IfpSmushTest {

    private Graph ontology = new SimpleGraph();

    {
        ontology.add(new TripleImpl(FOAF.mbox, RDF.type, OWL.InverseFunctionalProperty));
    }

    @Test
    public void simpleBlankNode() {
        Graph mGraph = new SimpleGraph();
        IRI mbox1 = new IRI("mailto:<EMAIL>");
        final BlankNode bNode1 = new BlankNode();
        mGraph.add(new TripleImpl(bNode1, FOAF.mbox, mbox1));
        mGraph.add(new TripleImpl(bNode1, RDFS.comment,
                new PlainLiteralImpl("a comment")));
        final BlankNode bNode2 = new BlankNode();
        mGraph.add(new TripleImpl(bNode2, FOAF.mbox, mbox1));
        mGraph.add(new TripleImpl(bNode2, RDFS.comment,
                new PlainLiteralImpl("another comment")));
        Smusher.smush(mGraph, ontology);
        Assert.assertEquals(3, mGraph.size());
    }

    @Test
    public void overlappingEquivalenceClasses() {
        Graph mGraph = new SimpleGraph();
        IRI mbox1 = new IRI("mailto:<EMAIL>");
        final BlankNode bNode1 = new BlankNode();
        mGraph.add(new TripleImpl(bNode1, FOAF.mbox, mbox1));
        mGraph.add(new TripleImpl(bNode1, RDFS.comment,
                new PlainLiteralImpl("a comment")));
        final BlankNode bNode2 = new BlankNode();
        IRI mbox2 = new IRI("mailto:<EMAIL>");
        mGraph.add(new TripleImpl(bNode2, FOAF.mbox, mbox1));
        mGraph.add(new TripleImpl(bNode2, FOAF.mbox, mbox2));
        mGraph.add(new TripleImpl(bNode2, RDFS.comment,
                new PlainLiteralImpl("another comment")));
        final BlankNode bNode3 = new BlankNode();
        mGraph.add(new TripleImpl(bNode3, FOAF.mbox, mbox2));
        mGraph.add(new TripleImpl(bNode3, RDFS.comment,
                new PlainLiteralImpl("yet another comment")));
        Smusher.smush(mGraph, ontology);
        Assert.assertEquals(5, mGraph.size());
    }

    @Test
    public void oneIRI() {
        Graph mGraph = new SimpleGraph();
        IRI mbox1 = new IRI("mailto:<EMAIL>");
        final IRI resource = new IRI("http://example.org/");
        mGraph.add(new TripleImpl(resource, FOAF.mbox, mbox1));
        mGraph.add(new TripleImpl(resource, RDFS.comment,
                new PlainLiteralImpl("a comment")));
        final BlankNode bNode2 = new BlankNode();
        mGraph.add(new TripleImpl(bNode2, FOAF.mbox, mbox1));
        mGraph.add(new TripleImpl(bNode2, RDFS.comment,
                new PlainLiteralImpl("another comment")));
        Smusher.smush(mGraph, ontology);
        Assert.assertEquals(3, mGraph.size());
    }

    @Test
    public void twoIRIs() {
        Graph mGraph = new SimpleGraph();
        IRI mbox1 = new IRI("mailto:<EMAIL>");
        final IRI resource1 = new IRI("http://example.org/");
        mGraph.add(new TripleImpl(resource1, FOAF.mbox, mbox1));
        mGraph.add(new TripleImpl(resource1, RDFS.comment,
                new PlainLiteralImpl("a comment")));
        final IRI resource2 = new IRI("http://2.example.org/");
        mGraph.add(new TripleImpl(resource2, FOAF.mbox, mbox1));
        mGraph.add(new TripleImpl(resource2, RDFS.comment,
                new PlainLiteralImpl("another comment")));
        Smusher.smush(mGraph, ontology);
        Assert.assertEquals(4, mGraph.size());
    }

}


<|start_filename|>api-implementation/src/main/java/org/apache/clerezza/implementation/graphmatching/HashMatching.java<|end_filename|>
/*
 * 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.clerezza.implementation.graphmatching;

import org.apache.clerezza.*;
import org.apache.clerezza.implementation.TripleImpl;
import org.apache.clerezza.implementation.graphmatching.collections.IntHashMap;
import org.apache.clerezza.implementation.graphmatching.collections.IntIterator;

import java.util.*;

/**
 * @author reto
 */
public class HashMatching {

    private Map<BlankNode, BlankNode> matchings = new HashMap<BlankNode, BlankNode>();
    private Map<Set<BlankNode>, Set<BlankNode>> matchingGroups;

    /**
     * tc1 and tc2 will be modified: the triples containing no unmatched bnode
     * will be removed
     *
     * @param tc1
     * @param tc2
     * @throws GraphNotIsomorphicException
     */
    HashMatching(Graph tc1, Graph tc2) throws GraphNotIsomorphicException {
        int foundMatchings = 0;
        int foundMatchingGroups = 0;
        Map<BlankNode, Integer> bNodeHashMap = new HashMap<BlankNode, Integer>();
        while (true) {
            bNodeHashMap = matchByHashes(tc1, tc2, bNodeHashMap);
            if (bNodeHashMap == null) {
                throw new GraphNotIsomorphicException();
            }
            if (matchings.size() == foundMatchings) {
                if (!(matchingGroups.size() > foundMatchingGroups)) {
                    break;
                }
            }
            foundMatchings = matchings.size();
            foundMatchingGroups = matchingGroups.size();
        }
    }

    /**
     * @return a map containing set of which each bnodes mappes one of the other set
     */
    public Map<Set<BlankNode>, Set<BlankNode>> getMatchingGroups() {
        return matchingGroups;
    }

    public Map<BlankNode, BlankNode> getMatchings() {
        return matchings;
    }


    private static IntHashMap<Set<BlankNode>> getHashNodes(Map<BlankNode,
            Set<Property>> bNodePropMap, Map<BlankNode, Integer> bNodeHashMap) {
        IntHashMap<Set<BlankNode>> result = new IntHashMap<Set<BlankNode>>();
        for (Map.Entry<BlankNode, Set<Property>> entry : bNodePropMap.entrySet()) {
            int hash = computeHash(entry.getValue(), bNodeHashMap);
            Set<BlankNode> bNodeSet = result.get(hash);
            if (bNodeSet == null) {
                bNodeSet = new HashSet<BlankNode>();
                result.put(hash, bNodeSet);
            }
            bNodeSet.add(entry.getKey());
        }
        return result;
    }

    /*
     * returns a Map from bnodes to hash that can be used for future
     * refinements, this could be separate for each ImmutableGraph.
     *
     * triples no longer containing an unmatched bnodes ae removed.
     *
     * Note that the matched node are not guaranteed to be equals, but only to
     * be the correct if the graphs are isomorphic.
     */
    private Map<BlankNode, Integer> matchByHashes(Graph g1, Graph g2,
                                                  Map<BlankNode, Integer> bNodeHashMap) {
        Map<BlankNode, Set<Property>> bNodePropMap1 = getBNodePropMap(g1);
        Map<BlankNode, Set<Property>> bNodePropMap2 = getBNodePropMap(g2);
        IntHashMap<Set<BlankNode>> hashNodeMap1 = getHashNodes(bNodePropMap1, bNodeHashMap);
        IntHashMap<Set<BlankNode>> hashNodeMap2 = getHashNodes(bNodePropMap2, bNodeHashMap);
        if (!hashNodeMap1.keySet().equals(hashNodeMap2.keySet())) {
            return null;
        }

        matchingGroups = new HashMap<Set<BlankNode>, Set<BlankNode>>();
        IntIterator hashIter = hashNodeMap1.keySet().intIterator();
        while (hashIter.hasNext()) {
            int hash = hashIter.next();
            Set<BlankNode> nodes1 = hashNodeMap1.get(hash);
            Set<BlankNode> nodes2 = hashNodeMap2.get(hash);
            if (nodes1.size() != nodes2.size()) {
                return null;
            }
            if (nodes1.size() != 1) {
                matchingGroups.put(nodes1, nodes2);
                continue;
            }
            final BlankNode bNode1 = nodes1.iterator().next();
            final BlankNode bNode2 = nodes2.iterator().next();
            matchings.put(bNode1, bNode2);
            //in the graphs replace node occurences with grounded node,
            BlankNodeOrIRI mappedNode = new MappedNode(bNode1, bNode2);
            replaceNode(g1, bNode1, mappedNode);
            replaceNode(g2, bNode2, mappedNode);
            //remove grounded triples
            if (!Utils.removeGrounded(g1, g2)) {
                return null;
            }
        }
        Map<BlankNode, Integer> result = new HashMap<BlankNode, Integer>();
        addInverted(result, hashNodeMap1);
        addInverted(result, hashNodeMap2);
        return result;
    }

    private static int computeHash(Set<Property> propertySet, Map<BlankNode, Integer> bNodeHashMap) {
        int result = 0;
        for (Property property : propertySet) {
            result += property.hashCode(bNodeHashMap);
        }
        return result;
    }

    private static Map<BlankNode, Set<Property>> getBNodePropMap(Graph g) {
        Set<BlankNode> bNodes = Utils.getBNodes(g);
        Map<BlankNode, Set<Property>> result = new HashMap<BlankNode, Set<Property>>();
        for (BlankNode bNode : bNodes) {
            result.put(bNode, getProperties(bNode, g));
        }
        return result;
    }

    private static Set<Property> getProperties(BlankNode bNode, Graph g) {
        Set<Property> result = new HashSet<Property>();
        Iterator<Triple> ti = g.filter(bNode, null, null);
        while (ti.hasNext()) {
            Triple triple = ti.next();
            result.add(new ForwardProperty(triple.getPredicate(), triple.getObject()));
        }
        ti = g.filter(null, null, bNode);
        while (ti.hasNext()) {
            Triple triple = ti.next();
            result.add(new BackwardProperty(triple.getSubject(), triple.getPredicate()));
        }
        return result;
    }

    private static int nodeHash(RDFTerm resource, Map<BlankNode, Integer> bNodeHashMap) {
        if (resource instanceof BlankNode) {
            Integer mapValue = bNodeHashMap.get((BlankNode) resource);
            if (mapValue == null) {
                return 0;
            } else {
                return mapValue;
            }
        } else {
            return resource.hashCode();
        }
    }

    private static void replaceNode(Graph graph, BlankNode bNode, BlankNodeOrIRI replacementNode) {
        Set<Triple> triplesToRemove = new HashSet<Triple>();
        for (Triple triple : graph) {
            Triple replacementTriple = getReplacement(triple, bNode, replacementNode);
            if (replacementTriple != null) {
                triplesToRemove.add(triple);
                graph.add(replacementTriple);
            }
        }
        graph.removeAll(triplesToRemove);
    }

    private static Triple getReplacement(Triple triple, BlankNode bNode, BlankNodeOrIRI replacementNode) {
        if (triple.getSubject().equals(bNode)) {
            if (triple.getObject().equals(bNode)) {
                return new TripleImpl(replacementNode, triple.getPredicate(), replacementNode);
            } else {
                return new TripleImpl(replacementNode, triple.getPredicate(), triple.getObject());
            }
        } else {
            if (triple.getObject().equals(bNode)) {
                return new TripleImpl(triple.getSubject(), triple.getPredicate(), replacementNode);
            } else {
                return null;
            }
        }
    }

    private static void addInverted(Map<BlankNode, Integer> result, IntHashMap<Set<BlankNode>> hashNodeMap) {
        for (int hash : hashNodeMap.keySet()) {
            Set<BlankNode> bNodes = hashNodeMap.get(hash);
            for (BlankNode bNode : bNodes) {
                result.put(bNode, hash);
            }
        }
    }

    private static class BackwardProperty implements Property {
        private BlankNodeOrIRI subject;
        private IRI predicate;

        public BackwardProperty(BlankNodeOrIRI subject, IRI predicate) {
            this.subject = subject;
            this.predicate = predicate;
        }

        @Override
        public int hashCode(Map<BlankNode, Integer> bNodeHashMap) {
            return 0xFF ^ predicate.hashCode() ^ nodeHash(subject, bNodeHashMap);
        }

    }

    private static class ForwardProperty implements Property {
        private IRI predicate;
        private RDFTerm object;

        public ForwardProperty(IRI predicate, RDFTerm object) {
            this.predicate = predicate;
            this.object = object;
        }

        @Override
        public int hashCode(Map<BlankNode, Integer> bNodeHashMap) {
            return predicate.hashCode() ^ nodeHash(object, bNodeHashMap);
        }
    }

    private static class MappedNode implements BlankNodeOrIRI {
        private BlankNode bNode1, bNode2;

        public MappedNode(BlankNode bNode1, BlankNode bNode2) {
            this.bNode1 = bNode1;
            this.bNode2 = bNode2;
        }

    }

    private static interface Property {
        public int hashCode(Map<BlankNode, Integer> bNodeHashMap);
    }
}


<|start_filename|>test.utils/src/main/java/org/apache/clerezza/test/utils/LockableMGraphWrapperForTesting.java<|end_filename|>
/*
 * 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.clerezza.test.utils;

import org.apache.clerezza.*;

import java.util.Iterator;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantReadWriteLock;

/**
 * Wrappes an Graph as a LockableGraph. If a method is called that reads
 * or modifies the wrapped graph and the appropriate lock is not set, then a
 * RuntimeException is thrown.
 *
 * @author rbn, mir
 */
public class LockableMGraphWrapperForTesting extends GraphWrapper {

    private final ReentrantReadWriteLock lock = (ReentrantReadWriteLock) getLock();
    private final Lock readLock = lock.readLock();
    private final Graph wrapped;

    /**
     * Constructs a LocalbleGraph for an Graph.
     *
     * @param providedGraph a non-lockable mgraph
     */
    public LockableMGraphWrapperForTesting(final Graph providedGraph) {
        super(providedGraph);
        this.wrapped = providedGraph;
    }

    @Override
    public Iterator<Triple> filter(BlankNodeOrIRI subject, IRI predicate, RDFTerm object) {
        LockChecker.checkIfReadLocked(lock);
        readLock.lock();
        try {
            return new LockingIteratorForTesting(wrapped.filter(subject, predicate, object), lock);
        } finally {
            readLock.unlock();
        }
    }

    @Override
    public Iterator<Triple> iterator() {
        LockChecker.checkIfReadLocked(lock);
        readLock.lock();
        try {
            return new LockingIteratorForTesting(wrapped.iterator(), lock);
        } finally {
            readLock.unlock();
        }
    }

}


<|start_filename|>sparql/src/main/java/org/apache/clerezza/sparql/query/PropertyPathExpressionOrVariable.java<|end_filename|>
/*
 * 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.clerezza.sparql.query;

/**
 * Wraps either a {@link PropertyPathExpression} or a {@link Variable}
 *
 * @author hasan
 */
public class PropertyPathExpressionOrVariable {

    private final PropertyPathExpression propertyPathExpression;
    private final Variable variable;

    public PropertyPathExpressionOrVariable(PropertyPathExpression propertyPathExpression) {
        if (propertyPathExpression == null) {
            throw new IllegalArgumentException("Invalid propertyPathExpression: null");
        }
        this.propertyPathExpression = propertyPathExpression;
        variable = null;
    }

    public PropertyPathExpressionOrVariable(Variable variable) {
        if (variable == null) {
            throw new IllegalArgumentException("Invalid variable: null");
        }
        this.variable = variable;
        propertyPathExpression = null;
    }

    /**
     *
     * @return
     *        true if it is a {@link Variable}, false if it is a {@link PropertyPathExpression}
     */
    public boolean isVariable() {
        return propertyPathExpression == null;
    }

    /**
     * 
     * @return
     *        the wrapped PropertyPathExpression if it is a PropertyPathExpression, null otherwise
     */
    public PropertyPathExpression getPropertyPathExpression() {
        return propertyPathExpression;
    }
    
    /**
     * 
     * @return
     *        the wrapped Variable if it is a Variable, null otherwise
     */
    public Variable getVariable() {
        return variable;
    }

    @Override
    public boolean equals(Object obj) {
        if (obj == null) {
            return false;
        }
        if (!(obj instanceof PropertyPathExpressionOrVariable)) {
            return false;
        }
        final PropertyPathExpressionOrVariable other = (PropertyPathExpressionOrVariable) obj;
        if (this.isVariable() != other.isVariable()) {
            return false;
        }
        if (this.isVariable()) {
            if (!this.getVariable().equals(other.getVariable())) {
                return false;
            }
        } else {
            if (!this.getPropertyPathExpression().equals(other.getPropertyPathExpression())) {
                return false;
            }
        }
        return true;
    }

    @Override
    public int hashCode() {
        return (isVariable()
                ? 13 * getVariable().hashCode() + 17
                : 13 * getPropertyPathExpression().hashCode() + 17);
    }
}


<|start_filename|>jaxrs.rdf.providers/src/main/java/org/apache/clerezza/jaxrs/rdf/providers/ImmutableGraphReader.java<|end_filename|>
/*
 * 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.clerezza.jaxrs.rdf.providers;

import org.apache.clerezza.ImmutableGraph;
import org.apache.clerezza.representation.Parser;
import org.apache.clerezza.representation.SupportedFormat;
import org.osgi.service.component.annotations.Component;
import org.osgi.service.component.annotations.Reference;

import javax.ws.rs.Consumes;
import javax.ws.rs.WebApplicationException;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.MultivaluedMap;
import javax.ws.rs.ext.MessageBodyReader;
import javax.ws.rs.ext.Provider;
import java.io.IOException;
import java.io.InputStream;
import java.lang.annotation.Annotation;
import java.lang.reflect.Type;
import java.util.Objects;

@Component(service = Object.class, property = {"javax.ws.rs=true"})
@Provider
@Consumes({SupportedFormat.N3, SupportedFormat.N_TRIPLE,
        SupportedFormat.RDF_XML, SupportedFormat.TURTLE,
        SupportedFormat.X_TURTLE, SupportedFormat.RDF_JSON})
public class ImmutableGraphReader implements MessageBodyReader<ImmutableGraph> {

    private Parser parser;

    @Reference
    public synchronized void setParser(Parser parser) {
        this.parser = parser;
    }

    public synchronized void unsetParser(Parser parser) {
        if (Objects.equals(this.parser, parser)) {
            this.parser = null;
        }
    }

    @Override
    public boolean isReadable(Class<?> type, Type genericType,
                              Annotation[] annotations, MediaType mediaType) {
        return type.isAssignableFrom(ImmutableGraph.class);
    }

    @Override
    public ImmutableGraph readFrom(Class<ImmutableGraph> type, Type genericType,
                                   Annotation[] annotations, MediaType mediaType,
                                   MultivaluedMap<String, String> httpHeaders,
                                   InputStream entityStream)
            throws IOException, WebApplicationException {
        return parser.parse(entityStream, mediaType.toString());
    }
}


<|start_filename|>sparql/src/main/java/org/apache/clerezza/sparql/query/Query.java<|end_filename|>
/*
 * 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.clerezza.sparql.query;

/**
 * <p>This interface represents a SPARQL query.</p>
 * <p>There are four types of SPARQL queries: {@link SelectQuery},
 * {@link ConstructQuery}, {@link DescribeQuery}, and {@link AskQuery}.</p>
 *
 * @author hasan
 */
public interface Query {

    /**
     * <p>Gets {@link DataSet} containing the specification of the default
     * ImmutableGraph and named graphs, if any.</p>
     * @see <a href="http://www.w3.org/TR/rdf-sparql-query/#specifyingDataset">
     * SPARQL Query Language: 8.2 Specifying RDF Datasets</a>
     * @return
     *        null if no data set is specified, indicating the use of
     *        system default ImmutableGraph. Otherwise a {@link DataSet} object is returned.
     */
    public DataSet getDataSet();

    /**
     * <p>Gets the query pattern of the WHERE clause for the query.</p>
     * @see <a href="http://www.w3.org/TR/rdf-sparql-query/#GraphPattern">
     * SPARQL Query Language: 5 ImmutableGraph Patterns</a>
     * @return
     *        the {@link GroupGraphPattern} of the WHERE clause for this query.
     *        If the WHERE clause is not specified, null is returned.
     */
    public GroupGraphPattern getQueryPattern();
    
    public InlineData getInlineData();

    /**
     * 
     * @return A valid String representation of the query.
     */
    @Override
    public abstract String toString();
}


<|start_filename|>api-implementation/src/main/java/org/apache/clerezza/implementation/graph/WriteBlockedGraph.java<|end_filename|>
/*
 * 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.clerezza.implementation.graph;

import org.apache.clerezza.*;

import java.util.Collection;
import java.util.Iterator;

/**
 * This is a wrapper object for <code>Graph</code>. If <code>SecurityManger</code>
 * is not <code>null</code> <code>TcManager</code> checks the <code>TcPermission</code>.
 * If read-only permissions are set this wrapper is used instead of <code>Graph</code>
 * and throws exceptions when add or remove methods are called.
 *
 * @author tsuy
 */
public class WriteBlockedGraph extends AbstractGraph
        implements Graph {

    private Graph triples;

    public WriteBlockedGraph(Graph triples) {
        this.triples = triples;
    }

    @Override
    protected int performSize() {
        return triples.size();
    }

    @Override
    protected Iterator<Triple> performFilter(BlankNodeOrIRI subject, IRI predicate, RDFTerm object) {
        final Iterator<Triple> baseIter = triples.filter(subject, predicate, object);
        return new Iterator<Triple>() {

            @Override
            public boolean hasNext() {
                return baseIter.hasNext();
            }

            @Override
            public Triple next() {
                return baseIter.next();
            }

            @Override
            public void remove() {
                throw new ReadOnlyException("remove");
            }


        };
    }

    @Override
    public boolean add(Triple e) {
        throw new ReadOnlyException("add");
    }

    @Override
    public boolean addAll(Collection<? extends Triple> c) {
        throw new ReadOnlyException("add all");
    }

    @Override
    public void clear() {
        throw new ReadOnlyException("clear");
    }

    @Override
    public boolean remove(Object o) {
        throw new ReadOnlyException("remove");
    }

    @Override
    public boolean removeAll(Collection<?> c) {
        throw new ReadOnlyException("remove all");
    }

    @Override
    public boolean retainAll(Collection<?> c) {
        throw new ReadOnlyException("retain all");
    }

    @Override
    public Iterator iterator() {
        return filter(null, null, null);
    }

    @Override
    public ImmutableGraph getImmutableGraph() {
        return this.triples.getImmutableGraph();
    }

}


<|start_filename|>sparql/src/main/java/org/apache/clerezza/sparql/query/impl/SimpleStringQuerySerializer.java<|end_filename|>
/*
 * 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.clerezza.sparql.query.impl;

import org.apache.clerezza.BlankNode;
import org.apache.clerezza.IRI;
import org.apache.clerezza.RDFTerm;
import org.apache.clerezza.sparql.StringQuerySerializer;
import org.apache.clerezza.sparql.query.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.List;
import java.util.Set;

/**
 * This class implements abstract methods of {@link StringQuerySerializer}
 * to serialize specific {@link Query} types.
 *
 * @author hasan
 */
public class SimpleStringQuerySerializer extends StringQuerySerializer {

    private final Logger logger = LoggerFactory.getLogger(this.getClass());

    @Override
    public String serialize(SelectQuery selectQuery) {
        StringBuffer s = new StringBuffer("SELECT ");
        if (selectQuery.isDistinct()) {
            s.append("DISTINCT\n");
        }
        if (selectQuery.isReduced()) {
            s.append("REDUCED\n");
        }
        if (selectQuery.isSelectAll()) {
            s.append("*");
        } else {
            for (Variable v : selectQuery.getSelection()) {
                appendVariable(s, v);
                s.append(" ");
            }
        }
        s.append("\n");

        appendDataSet(s, (SimpleQuery) selectQuery);
        appendWhere(s, (SimpleQuery) selectQuery);
        appendModifier(s, (SimpleQueryWithSolutionModifier) selectQuery);

        return s.toString();
    }

    private void appendVariable(StringBuffer s, Variable v) {
        s.append("?").append(v.getName());
    }

    private void appendDataSet(StringBuffer s, SimpleQuery q) {
        DataSet dataSet = q.getDataSet();
        if (dataSet != null) {
            for (IRI dg : dataSet.getDefaultGraphs()) {
                s.append("FROM ").append(dg.toString()).append("\n");
            }
            for (IRI ng : dataSet.getNamedGraphs()) {
                s.append("FROM NAMED ").append(ng.toString()).append("\n");
            }
        }
    }

    private void appendWhere(StringBuffer s, SimpleQuery q) {
        GroupGraphPattern queryPattern = q.getQueryPattern();
        if (queryPattern == null) {
            return;
        }
        s.append("WHERE\n");
        appendGroupGraphPattern(s, q.getQueryPattern());
    }

    private void appendGroupGraphPattern(StringBuffer s,
            GroupGraphPattern groupGraphPattern) {

        s.append("{ ");
        for (GraphPattern graphPattern : groupGraphPattern.getGraphPatterns()) {
            appendGraphPattern(s, graphPattern);
        }
        for (Expression e : groupGraphPattern.getFilter()) {
            boolean brackettedExpr = !((e instanceof BuiltInCall)
                    || (e instanceof FunctionCall));
            s.append("FILTER ");
            if (brackettedExpr) {
                s.append("(");
            }
            appendExpression(s, e);
            if (brackettedExpr) {
                s.append(")");
            }
            s.append("\n");
        }
        s.append("} ");
    }

    private void appendGraphPattern(StringBuffer s, GraphPattern graphPattern) {
        if (graphPattern instanceof BasicGraphPattern) {
            appendTriplePatterns(s,
                    ((BasicGraphPattern) graphPattern).getTriplePatterns());
        } else if (graphPattern instanceof GroupGraphPattern) {
            appendGroupGraphPattern(s, (GroupGraphPattern) graphPattern);
        } else if (graphPattern instanceof OptionalGraphPattern) {
            appendGraphPattern(s,
                    ((OptionalGraphPattern) graphPattern).getMainGraphPattern());
            s.append(" OPTIONAL ");
            appendGroupGraphPattern(s,
                    ((OptionalGraphPattern) graphPattern).getOptionalGraphPattern());
        } else if (graphPattern instanceof AlternativeGraphPattern) {
            List<GroupGraphPattern> alternativeGraphPatterns =
                    ((AlternativeGraphPattern) graphPattern).getAlternativeGraphPatterns();
            if ((alternativeGraphPatterns != null) &&
                    (!alternativeGraphPatterns.isEmpty())) {
                appendGroupGraphPattern(s, alternativeGraphPatterns.get(0));
                int size = alternativeGraphPatterns.size();
                int i = 1;
                while (i < size) {
                    s.append(" UNION ");
                    appendGroupGraphPattern(s, alternativeGraphPatterns.get(i));
                    i++;
                }
            }
        } else if (graphPattern instanceof GraphGraphPattern) {
            s.append("ImmutableGraph ");
            appendResourceOrVariable(s, ((GraphGraphPattern) graphPattern).getGraph());
            s.append(" ");
            appendGroupGraphPattern(s, ((GraphGraphPattern) graphPattern).getGroupGraphPattern());
        } else {
            logger.warn("Unsupported GraphPattern {}", graphPattern.getClass());
        }
    }

    private void appendTriplePatterns(StringBuffer s,
            Set<TriplePattern> triplePatterns) {

        for (TriplePattern p : triplePatterns) {
            appendResourceOrVariable(s, p.getSubject());
            s.append(" ");
            appendResourceOrVariable(s, p.getPredicate());
            s.append(" ");
            appendResourceOrVariable(s, p.getObject());
            s.append(" .\n");
        }
    }

    private void appendResourceOrVariable(StringBuffer s, ResourceOrVariable n) {
        if (n.isVariable()) {
            appendVariable(s, n.getVariable());
        } else {
            RDFTerm r = n.getResource();
            if (r instanceof BlankNode) {
                s.append("_:").append(r.toString().replace("@", "."));
            } else {
                s.append(r.toString());
            }
        }
    }

    private void appendExpression(StringBuffer s, Expression e) {
        if (e instanceof Variable) {
            appendVariable(s, (Variable) e);
        } else if (e instanceof BinaryOperation) {
            BinaryOperation bo = (BinaryOperation) e;
            s.append("(");
            appendExpression(s, bo.getLhsOperand());
            s.append(") ").append(bo.getOperatorString()).append(" (");
            appendExpression(s, bo.getRhsOperand());
            s.append(")");
        } else if (e instanceof UnaryOperation) {
            UnaryOperation uo = (UnaryOperation) e;
            s.append(uo.getOperatorString()).append(" (");
            appendExpression(s, uo.getOperand());
            s.append(")");
        } else if (e instanceof BuiltInCall) {
            BuiltInCall b = (BuiltInCall) e;
            appendCall(s, b.getName(), b.getArguements());
        } else if (e instanceof FunctionCall) {
            FunctionCall f = (FunctionCall) e;
            appendCall(s, f.getName().getUnicodeString(), f.getArguements());
        } else if (e instanceof LiteralExpression) {
            appendLiteralExpression(s, (LiteralExpression) e);
        } else if (e instanceof UriRefExpression) {
            s.append(((UriRefExpression) e).getUriRef().toString());
        }
    }

    private void appendCall(StringBuffer s, String name, List<Expression> expr) {
        s.append(name).append("(");
        for (Expression e : expr) {
            appendExpression(s, e);
            s.append(",");
        }
        if (expr.isEmpty()) {
            s.append(")");
        } else {
            s.setCharAt(s.length()-1, ')');
        }
    }

    private void appendLiteralExpression(StringBuffer s, LiteralExpression le) {
        s.append(le.getLiteral().toString());
    }

    private void appendModifier(StringBuffer s, SimpleQueryWithSolutionModifier q) {
        List<OrderCondition> orderConditions = q.getOrderConditions();
        if ((orderConditions != null) && (!orderConditions.isEmpty())) {
            s.append("ORDER BY ");
            for (OrderCondition oc : orderConditions) {
                appendOrderCondition(s, oc);
                s.append("\n");
            }
        }
        if (q.getOffset() > 0) {
            s.append("OFFSET ").append(q.getOffset()).append("\n");
        }
        if (q.getLimit() >= 0) {
            s.append("LIMIT ").append(q.getLimit()).append("\n");
        }
    }

    private void appendOrderCondition(StringBuffer s, OrderCondition oc) {
        if (!oc.isAscending()) {
            s.append("DESC(");
        }
        appendExpression(s, oc.getExpression());
        if (!oc.isAscending()) {
            s.append(")");
        }
        s.append(" ");
    }

    @Override
    public String serialize(ConstructQuery constructQuery) {
        StringBuffer s = new StringBuffer("CONSTRUCT\n");
        Set<TriplePattern> triplePatterns = constructQuery.getConstructTemplate();
        s.append("{ ");
        if (triplePatterns != null && !triplePatterns.isEmpty()) {
            appendTriplePatterns(s, triplePatterns);
        }
        s.append("}\n");

        appendDataSet(s, (SimpleQuery) constructQuery);
        appendWhere(s, (SimpleQuery) constructQuery);
        appendModifier(s, (SimpleQueryWithSolutionModifier) constructQuery);

        return s.toString();
    }

    @Override
    public String serialize(DescribeQuery describeQuery) {
        StringBuffer s = new StringBuffer("DESCRIBE\n");

        if (describeQuery.isDescribeAll()) {
            s.append("*");
        } else {
            for (ResourceOrVariable n : describeQuery.getResourcesToDescribe()) {
                appendResourceOrVariable(s, n);
                s.append(" ");
            }
        }
        appendDataSet(s, (SimpleQuery) describeQuery);
        appendWhere(s, (SimpleQuery) describeQuery);
        appendModifier(s, (SimpleQueryWithSolutionModifier) describeQuery);

        return s.toString();
    }

    @Override
    public String serialize(AskQuery askQuery) {
        StringBuffer s = new StringBuffer("ASK\n");
        appendDataSet(s, (SimpleQuery) askQuery);
        appendWhere(s, (SimpleQuery) askQuery);

        return s.toString();
    }
}


<|start_filename|>api-implementation/src/main/java/org/apache/clerezza/implementation/literal/LiteralFactory.java<|end_filename|>
/*
 * 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.clerezza.implementation.literal;

import org.apache.clerezza.Literal;

/**
 * This class provides methods to convert java objects to typed literals and
 * vice versa. While the default implementation will provide literal objects
 * storing the data's lexical form in memory, other implementations may
 * create literal optimized for processing within the store.
 * <p>
 * Note: this class uses the notion of "Convertor" (in the Exception naming),
 * but does not currently provide a mechanism to register such
 * <code>Convertor</code>s. An implementation is said to provide
 * <code>Convertor</code>s for the types it supports.
 *
 * @author reto
 * @since 0.3
 */
public abstract class LiteralFactory {

    private static LiteralFactory instance = new SimpleLiteralFactory();

    /**
     * Get a <code>LiteralFactory</code>. If this has not been set using
     * setInstance it returns an instance of
     * {@link org.apache.clerezza.model.impl.SimpleLiteralFactory}.
     *
     * @return a concrete <code>LiteralFactory</code>
     */
    public static LiteralFactory getInstance() {
        return instance;
    }

    /**
     * Set the instance returned by <code>getInstance</code>.
     *
     * @param instance the new default <code>LiteralFactory</code>
     */
    public static void setInstance(LiteralFactory instance) {
        LiteralFactory.instance = instance;
    }

    /**
     * Create a typed literal for the specified object
     *
     * @param value the value of the literal to be created
     * @return a TypedLiteral representing the value
     * @throws NoConvertorException thrown if <code>value</code> is of an invalid type
     */
    public abstract Literal createTypedLiteral(Object value)
            throws NoConvertorException;

    /**
     * Converts a literal to an instance of the specified class
     *
     * @param <T>
     * @param type    the <code>Class</code> of the returned object
     * @param literal the literal to be converted
     * @return a java object representing the value of the literal
     * @throws NoConvertorException        thrown if <code>type</code> is unsupported
     * @throws InvalidLiteralTypeException if the literal type doesn't match the requested java type
     */
    public abstract <T> T createObject(Class<T> type, Literal literal)
            throws NoConvertorException, InvalidLiteralTypeException;
}


<|start_filename|>api-implementation/src/test/java/org/apache/clerezza/implementation/graphmatching/Utils4Testing.java<|end_filename|>
/*
 * 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.clerezza.implementation.graphmatching;

import org.apache.clerezza.BlankNode;
import org.apache.clerezza.BlankNodeOrIRI;
import org.apache.clerezza.Graph;
import org.apache.clerezza.IRI;
import org.apache.clerezza.implementation.TripleImpl;
import org.apache.clerezza.implementation.in_memory.SimpleGraph;

/**
 * @author reto
 */
public class Utils4Testing {

    static Graph generateLine(int size, final BlankNodeOrIRI firstNode) {
        if (size < 1) {
            throw new IllegalArgumentException();
        }
        Graph result = new SimpleGraph();
        BlankNodeOrIRI lastNode = firstNode;
        for (int i = 0; i < size; i++) {
            final BlankNode newNode = new BlankNode();
            result.add(new TripleImpl(lastNode, u1, newNode));
            lastNode = newNode;
        }
        return result;
    }

    final static IRI u1 = new IRI("http://example.org/u1");

}


<|start_filename|>api.utils/src/main/java/org/apache/clerezza/utils/smushing/SameAsSmusher.java<|end_filename|>
/*
 * 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.clerezza.utils.smushing;

import org.apache.clerezza.BlankNodeOrIRI;
import org.apache.clerezza.Graph;
import org.apache.clerezza.IRI;
import org.apache.clerezza.Triple;
import org.apache.clerezza.ontologies.OWL;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.*;

/**
 * A utility to equate duplicate nodes in an Mgraph. This unifies owl:sameAs
 * resources.
 *
 * @author reto
 */
public class SameAsSmusher extends BaseSmusher {

    static final Logger log = LoggerFactory.getLogger(SameAsSmusher.class);

    /**
     * This will ensure that all properties of sameAs resources are associated
     * to the preferedIRI as returned by {@code getPreferedIRI}
     *
     * @param mGraph
     * @param owlSameStatements
     * @param addCanonicalSameAsStatements if true owl:sameAsStatements with the preferedIRI as object will be added
     */
    public void smush(Graph mGraph,
                      Graph owlSameStatements,
                      boolean addCanonicalSameAsStatements) {

        log.info("Starting smushing");

        // This hashmap contains a uri (key) and the set of equivalent uris (value)
        final Map<BlankNodeOrIRI, Set<BlankNodeOrIRI>> node2EquivalenceSet = new HashMap<BlankNodeOrIRI, Set<BlankNodeOrIRI>>();

        log.info("Creating the sets of equivalent uris of each subject or object in the owl:sameAs statements");
        // Determines for each subject and object in all the owl:sameAs statements the set of ewquivalent uris
        for (Iterator<Triple> it = owlSameStatements.iterator(); it.hasNext(); ) {
            final Triple triple = it.next();
            final IRI predicate = triple.getPredicate();
            if (!predicate.equals(OWL.sameAs)) {
                throw new RuntimeException("Statements must use only <http://www.w3.org/2002/07/owl#sameAs> predicate.");
            }
            final BlankNodeOrIRI subject = triple.getSubject();
            //literals not yet supported
            final BlankNodeOrIRI object = (BlankNodeOrIRI) triple.getObject();

            Set<BlankNodeOrIRI> equivalentNodes = node2EquivalenceSet.get(subject);

            // if there is not a set of equivalent uris then create a new set
            if (equivalentNodes == null) {
                equivalentNodes = node2EquivalenceSet.get(object);
                if (equivalentNodes == null) {
                    equivalentNodes = new HashSet<BlankNodeOrIRI>();
                }
            } else {
                Set<BlankNodeOrIRI> objectSet = node2EquivalenceSet.get(object);
                if ((objectSet != null) && (objectSet != equivalentNodes)) {
                    //merge two sets
                    for (BlankNodeOrIRI res : objectSet) {
                        node2EquivalenceSet.remove(res);
                    }
                    for (BlankNodeOrIRI res : objectSet) {
                        node2EquivalenceSet.put(res, equivalentNodes);
                    }
                    equivalentNodes.addAll(objectSet);
                }
            }

            // add both subject and object of the owl:sameAs statement to the set of equivalent uris
            equivalentNodes.add(subject);
            equivalentNodes.add(object);

            // use both uris in the owl:sameAs statement as keys for the set of equivalent uris
            node2EquivalenceSet.put(subject, equivalentNodes);
            node2EquivalenceSet.put(object, equivalentNodes);

            log.info("Sets of equivalent uris created.");

        }

        // This set contains the sets of equivalent uris
        Set<Set<BlankNodeOrIRI>> unitedEquivalenceSets = new HashSet<Set<BlankNodeOrIRI>>(node2EquivalenceSet.values());
        smush(mGraph, unitedEquivalenceSets, addCanonicalSameAsStatements);
    }
}


<|start_filename|>api/src/main/java/org/apache/clerezza/IRI.java<|end_filename|>
/*
 * 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.clerezza;

import java.io.Serializable;

/**
 * Represents an RDF URI Reference
 * <p>
 * RDF URI References are defined in section 6.4 RDF URI References of
 * http://www.w3.org/TR/2004/REC-rdf-concepts-20040210/#section-Graph-URIref
 * <p>
 * Note that an RDF URI Reference is not the same as defined by RFC3986,
 * RDF URI References support most unicode characters
 *
 * @author reto
 */
public class IRI implements BlankNodeOrIRI, Serializable {

    private String unicodeString;

    public IRI(String unicodeString) {
        this.unicodeString = unicodeString;
    }

    /**
     * @return the unicode string that produces the URI
     */
    public String getUnicodeString() {
        return unicodeString;
    }

    /**
     * Returns true iff <code>obj</code> == <code>UriRef</code>
     *
     * @param obj
     * @return true if obj is an instanceof UriRef with
     * the same unicode-string, false otherwise
     */
    @Override
    public boolean equals(Object obj) {

        if (!(obj instanceof IRI)) {
            return false;
        }

        return unicodeString.equals(((IRI) obj).getUnicodeString());
    }

    /**
     * @return 5 + the hashcode of the string
     */
    @Override
    public int hashCode() {
        int hash = 5 + unicodeString.hashCode();
        return hash;
    }

    @Override
    public String toString() {
        StringBuilder buffer = new StringBuilder();
        buffer.append('<');
        buffer.append(unicodeString);
        buffer.append('>');
        return buffer.toString();
    }
}

<|start_filename|>sparql/src/main/java/org/apache/clerezza/sparql/query/DescribeQuery.java<|end_filename|>
/*
 * 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.clerezza.sparql.query;

import java.util.List;

/**
 * <p>This interface represents a SPARQL SELECT query.</p>
 *
 * @see <a href="http://www.w3.org/TR/rdf-sparql-query/#describe">
 * SPARQL Query Language: 10.4 DESCRIBE (Informative)</a>
 *
 * @author hasan
 */
public interface DescribeQuery extends QueryWithSolutionModifier {

    /**
     * <p>Tests if all variables in the query should be described.</p>
     * @see <a href="http://www.w3.org/TR/rdf-sparql-query/#describe">
     * SPARQL Query Language: 10.4 DESCRIBE (Informative)</a>
     * @return <code>true</code> if the query should return all variables.
     */
    public boolean isDescribeAll();

    /**
     * <p>Gets the list of {@link ResourceOrVariable}s to describe.
     * If {@link #isDescribeAll()} returns <code>true</code> then
     * this list contains all the variables from the query.</p>
     * @see <a href="http://www.w3.org/TR/rdf-sparql-query/#describe">
     * SPARQL Query Language: 10.4 DESCRIBE (Informative)</a>
     * @return A list of {@link ResourceOrVariable}s to describe.
     */
    public List<ResourceOrVariable> getResourcesToDescribe();
}


<|start_filename|>api-implementation/src/main/java/org/apache/clerezza/implementation/graphmatching/Utils.java<|end_filename|>
/*
 * 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.clerezza.implementation.graphmatching;

import org.apache.clerezza.BlankNode;
import org.apache.clerezza.Triple;

import java.util.Collection;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;

public class Utils {

    static Set<BlankNode> getBNodes(Collection<Triple> s) {
        Set<BlankNode> result = new HashSet<BlankNode>();
        for (Triple triple : s) {
            if (triple.getSubject() instanceof BlankNode) {
                result.add((BlankNode) triple.getSubject());
            }
            if (triple.getObject() instanceof BlankNode) {
                result.add((BlankNode) triple.getObject());
            }
        }
        return result;
    }

    /**
     * removes the common grounded triples from s1 and s2. returns false if
     * a grounded triple is not in both sets, true otherwise
     */
    static boolean removeGrounded(Collection<Triple> s1, Collection<Triple> s2) {
        Iterator<Triple> triplesIter = s1.iterator();
        while (triplesIter.hasNext()) {
            Triple triple = triplesIter.next();
            if (!isGrounded(triple)) {
                continue;
            }
            if (!s2.remove(triple)) {
                return false;
            }
            triplesIter.remove();
        }
        //for efficiency we might skip this (redefine method)
        for (Triple triple : s2) {
            if (isGrounded(triple)) {
                return false;
            }
        }
        return true;
    }

    private static boolean isGrounded(Triple triple) {
        if (triple.getSubject() instanceof BlankNode) {
            return false;
        }
        if (triple.getObject() instanceof BlankNode) {
            return false;
        }
        return true;
    }

}


<|start_filename|>jaxrs.rdf.providers/src/main/java/org/apache/clerezza/jaxrs/rdf/providers/GraphNodeWriter.java<|end_filename|>
/*
 * 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.clerezza.jaxrs.rdf.providers;

import org.apache.clerezza.Graph;
import org.apache.clerezza.IRI;
import org.apache.clerezza.RDFTerm;
import org.apache.clerezza.Triple;
import org.apache.clerezza.implementation.in_memory.SimpleGraph;
import org.apache.clerezza.utils.GraphNode;
import org.apache.clerezza.representation.Serializer;
import org.apache.clerezza.representation.SupportedFormat;
import org.osgi.service.component.annotations.Component;
import org.osgi.service.component.annotations.Reference;

import javax.ws.rs.Produces;
import javax.ws.rs.WebApplicationException;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.MultivaluedMap;
import javax.ws.rs.core.UriInfo;
import javax.ws.rs.ext.MessageBodyWriter;
import javax.ws.rs.ext.Provider;
import java.io.IOException;
import java.io.OutputStream;
import java.lang.annotation.Annotation;
import java.lang.reflect.Type;
import java.util.HashSet;
import java.util.List;
import java.util.Objects;
import java.util.Set;

/**
 * By default this returns a serialization of the context of the GraphNode.
 * <p>
 * The expansion can be widened by using the query parameters xPropObj and
 * xProSubj. These parameters specify property uris (both parameters might be
 * repeated). For the specified properties their objects respectively subjects
 * are expanded as if they were bnodes.
 *
 * @author reto
 */

@Component(service = Object.class, property = {"javax.ws.rs=true"})
@Provider
@Produces({SupportedFormat.N3, SupportedFormat.N_TRIPLE,
        SupportedFormat.RDF_XML, SupportedFormat.TURTLE,
        SupportedFormat.X_TURTLE, SupportedFormat.RDF_JSON})
public class GraphNodeWriter implements MessageBodyWriter<GraphNode> {

    public static final String OBJ_EXP_PARAM = "xPropObj";
    public static final String SUBJ_EXP_PARAM = "xPropSubj";

    private UriInfo uriInfo;

    private Serializer serializer = Serializer.getInstance();

    @Reference
    public synchronized void setSerializer(Serializer serializer) {
        this.serializer = serializer;
    }

    public synchronized void unsetSerializer(Serializer serializer) {
        if (Objects.equals(this.serializer, serializer)) {
            this.serializer = Serializer.getInstance();
        }
    }

    @Override
    public boolean isWriteable(Class<?> type, Type genericType,
                               Annotation[] annotations, MediaType mediaType) {
        return GraphNode.class.isAssignableFrom(type);
    }

    @Override
    public long getSize(GraphNode n, Class<?> type, Type genericType,
                        Annotation[] annotations, MediaType mediaType) {
        return -1;
    }

    @Override
    public void writeTo(GraphNode node, Class<?> type, Type genericType,
                        Annotation[] annotations, MediaType mediaType,
                        MultivaluedMap<String, Object> httpHeaders,
                        OutputStream entityStream) throws IOException, WebApplicationException {
        serializer.serialize(entityStream, getExpandedContext(node), mediaType.toString());
    }

    @Context
    public void setUriInfo(UriInfo uriInfo) {
        this.uriInfo = uriInfo;
    }

    private Graph getExpandedContext(GraphNode node) {
        final Graph result = new SimpleGraph(node.getNodeContext());
        final Set<RDFTerm> expandedResources = new HashSet<RDFTerm>();
        expandedResources.add(node.getNode());
        while (true) {
            Set<RDFTerm> additionalExpansionRes = getAdditionalExpansionResources(result);
            additionalExpansionRes.removeAll(expandedResources);
            if (additionalExpansionRes.size() == 0) {
                return result;
            }
            for (RDFTerm resource : additionalExpansionRes) {
                final GraphNode additionalNode = new GraphNode(resource, node.getGraph());
                result.addAll(additionalNode.getNodeContext());
                expandedResources.add(resource);
            }
        }
    }

    private Set<RDFTerm> getAdditionalExpansionResources(Graph tc) {
        final Set<IRI> subjectExpansionProperties = getSubjectExpansionProperties();
        final Set<IRI> objectExpansionProperties = getObjectExpansionProperties();
        final Set<RDFTerm> result = new HashSet<RDFTerm>();
        if ((subjectExpansionProperties.size() > 0)
                || (objectExpansionProperties.size() > 0)) {
            for (Triple triple : tc) {
                final IRI predicate = triple.getPredicate();
                if (subjectExpansionProperties.contains(predicate)) {
                    result.add(triple.getSubject());
                }
                if (objectExpansionProperties.contains(predicate)) {
                    result.add(triple.getObject());
                }
            }
        }
        return result;
    }

    private Set<IRI> getSubjectExpansionProperties() {
        final MultivaluedMap<String, String> queryParams = uriInfo.getQueryParameters();
        final List<String> paramValues = queryParams.get(SUBJ_EXP_PARAM);
        if (paramValues == null) {
            return new HashSet<IRI>(0);
        }
        final Set<IRI> result = new HashSet<IRI>(paramValues.size());
        for (String uriString : paramValues) {
            result.add(new IRI(uriString));
        }
        return result;
    }

    private Set<IRI> getObjectExpansionProperties() {
        final MultivaluedMap<String, String> queryParams = uriInfo.getQueryParameters();
        final List<String> paramValues = queryParams.get(OBJ_EXP_PARAM);
        if (paramValues == null) {
            return new HashSet<IRI>(0);
        }
        final Set<IRI> result = new HashSet<IRI>(paramValues.size());
        for (String uriString : paramValues) {
            result.add(new IRI(uriString));
        }
        return result;
    }
}


<|start_filename|>api-implementation/src/main/java/org/apache/clerezza/implementation/graph/AbstractImmutableGraph.java<|end_filename|>
/*
 * 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.clerezza.implementation.graph;

import org.apache.clerezza.RDFTerm;
import org.apache.clerezza.BlankNode;
import org.apache.clerezza.ImmutableGraph;
import org.apache.clerezza.Triple;
import org.apache.clerezza.implementation.graphmatching.GraphMatcher;

import java.util.Collection;
import java.util.Iterator;

/**
 * <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;
    }
}


<|start_filename|>sparql/src/main/java/org/apache/clerezza/sparql/query/ResourceOrVariable.java<|end_filename|>
/*
 * 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.clerezza.sparql.query;

import org.apache.clerezza.RDFTerm;

/**
 * Wraps either a {@link RDFTerm} or a {@link Variable}
 *
 * @author hasan
 */
public class ResourceOrVariable {

    private final RDFTerm resource;
    private final Variable variable;

    public ResourceOrVariable(RDFTerm resource) {
        if (resource == null) {
            throw new IllegalArgumentException("Invalid resource: null");
        }
        this.resource = resource;
        variable = null;
    }

    public ResourceOrVariable(Variable variable) {
        if (variable == null) {
            throw new IllegalArgumentException("Invalid variable: null");
        }
        this.variable = variable;
        resource = null;
    }

    /**
     *
     * @return
     *        true if it is a {@link Variable}, false if it is a {@link RDFTerm}
     */
    public boolean isVariable() {
        return resource == null;
    }

    /**
     * 
     * @return
     *        the wrapped Resource if it is a Resource, null otherwise
     */
    public RDFTerm getResource() {
        return resource;
    }
    
    /**
     * 
     * @return
     *        the wrapped Variable if it is a Variable, null otherwise
     */
    public Variable getVariable() {
        return variable;
    }

    @Override
    public boolean equals(Object obj) {
        if (obj == null) {
            return false;
        }
        if (!(obj instanceof ResourceOrVariable)) {
            return false;
        }
        final ResourceOrVariable other = (ResourceOrVariable) obj;
        if (this.isVariable() != other.isVariable()) {
            return false;
        }
        if (this.isVariable()) {
            if (!this.getVariable().equals(other.getVariable())) {
                return false;
            }
        } else {
            if (!this.getResource().equals(other.getResource())) {
                return false;
            }
        }
        return true;
    }

    @Override
    public int hashCode() {
        return (isVariable()
                ? 13 * getVariable().hashCode() + 7
                : 13 * getResource().hashCode() + 7);
    }
}


<|start_filename|>api.utils/src/main/java/org/apache/clerezza/utils/RdfList.java<|end_filename|>
/*
 * 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.clerezza.utils;

import org.apache.clerezza.*;
import org.apache.clerezza.implementation.TripleImpl;
import org.apache.clerezza.ontologies.OWL;
import org.apache.clerezza.ontologies.RDF;
import org.apache.clerezza.representation.Serializer;
import org.apache.clerezza.representation.SupportedFormat;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.FileOutputStream;
import java.security.AccessController;
import java.security.PrivilegedAction;
import java.util.*;

/**
 * An implementation of an <code>java.util.List</code> backed by an RDF
 * collection (rdf:List). The list allows modification that are reflected
 * to the underlying <code>Graph</code>. It reads the data from the
 * <code>Graph</code> when it is first needed, so changes to the
 * Graph affecting the rdf:List may or may not have an effect on the
 * values returned by instances of this class. For that reason only one
 * instance of this class should be used for accessing an rdf:List of sublists
 * thereof when the lists are being modified, having multiple lists exclusively
 * for read operations (such as for immutable <code>Graph</code>s) is
 * not problematic.
 *
 * @author rbn, mir
 */
public class RdfList extends AbstractList<RDFTerm> {

    private static final Logger logger = LoggerFactory.getLogger(RdfList.class);

    private final static IRI RDF_NIL =
            new IRI("http://www.w3.org/1999/02/22-rdf-syntax-ns#nil");
    /**
     * a list of the linked rdf:List elements in order
     */
    private List<BlankNodeOrIRI> listList = new ArrayList<BlankNodeOrIRI>();
    private List<RDFTerm> valueList = new ArrayList<RDFTerm>();
    private BlankNodeOrIRI firstList;
    private Graph tc;
    private boolean totallyExpanded = false;

    /**
     * Get a list for the specified resource.
     * <p>
     * If the list is modified using the created instance
     * <code>listRDFTerm</code> will always be the first list.
     *
     * @param listRDFTerm
     * @param tc
     */
    public RdfList(BlankNodeOrIRI listRDFTerm, Graph tc) {
        firstList = listRDFTerm;
        this.tc = tc;
    }

    /**
     * Get a list for the specified resource node.
     *
     * @param listNode
     */
    public RdfList(GraphNode listNode) {
        this((BlankNodeOrIRI) listNode.getNode(), listNode.getGraph());
    }

    /**
     * Creates an empty RdfList by writing a triple
     * "{@code listRDFTerm} owl:sameAs rdf.nil ." to {@code tc}.
     *
     * @param listRDFTerm
     * @param tc
     * @return an empty rdf:List.
     * @throws IllegalArgumentException if the provided {@code  listRDFTerm} is a non-empty rdf:List.
     */
    public static RdfList createEmptyList(BlankNodeOrIRI listRDFTerm, Graph tc)
            throws IllegalArgumentException {

        if (!tc.filter(listRDFTerm, RDF.first, null).hasNext()) {
            RdfList list = new RdfList(listRDFTerm, tc);
            list.tc.add(new TripleImpl(listRDFTerm, OWL.sameAs, RDF_NIL));
            return list;
        } else {
            throw new IllegalArgumentException(listRDFTerm + "is a non-empty rdf:List.");
        }
    }

    private void expandTill(int pos) {
        if (totallyExpanded) {
            return;
        }
        BlankNodeOrIRI currentList;
        if (listList.size() > 0) {
            currentList = listList.get(listList.size() - 1);
        } else {
            currentList = firstList;
            if (!tc.filter(currentList, RDF.first, null).hasNext()) {
                return;
            }
            listList.add(currentList);
            valueList.add(getFirstEntry(currentList));
        }
        if (listList.size() >= pos) {
            return;
        }
        while (true) {
            currentList = getRest(currentList);
            if (currentList.equals(RDF_NIL)) {
                totallyExpanded = true;
                break;
            }
            if (listList.size() == pos) {
                break;
            }
            valueList.add(getFirstEntry(currentList));
            listList.add(currentList);
        }
    }


    @Override
    public RDFTerm get(int index) {
        expandTill(index + 1);
        return valueList.get(index);
    }

    @Override
    public int size() {
        expandTill(Integer.MAX_VALUE);
        return valueList.size();
    }

    @Override
    public void add(int index, RDFTerm element) {
        expandTill(index);
        if (index == 0) {
            //special casing to make sure the first list remains the same resource
            if (listList.size() == 0) {
                tc.remove(new TripleImpl(firstList, OWL.sameAs, RDF_NIL));
                tc.add(new TripleImpl(firstList, RDF.rest, RDF_NIL));
                tc.add(new TripleImpl(firstList, RDF.first, element));
                listList.add(firstList);
            } else {
                tc.remove(new TripleImpl(listList.get(0), RDF.first, valueList.get(0)));
                tc.add(new TripleImpl(listList.get(0), RDF.first, element));
                addInRdfList(1, valueList.get(0));
            }
        } else {
            addInRdfList(index, element);
        }
        valueList.add(index, element);
    }

    /**
     * @param index   is > 0
     * @param element
     */
    private void addInRdfList(int index, RDFTerm element) {
        expandTill(index + 1);
        BlankNodeOrIRI newList = new BlankNode() {
        };
        tc.add(new TripleImpl(newList, RDF.first, element));
        if (index < listList.size()) {
            tc.add(new TripleImpl(newList, RDF.rest, listList.get(index)));
            tc.remove(new TripleImpl(listList.get(index - 1), RDF.rest, listList.get(index)));
        } else {
            tc.remove(new TripleImpl(listList.get(index - 1), RDF.rest, RDF_NIL));
            tc.add(new TripleImpl(newList, RDF.rest, RDF_NIL));

        }
        tc.add(new TripleImpl(listList.get(index - 1), RDF.rest, newList));
        listList.add(index, newList);
    }

    @Override
    public RDFTerm remove(int index) {
        //keeping the first list resource
        tc.remove(new TripleImpl(listList.get(index), RDF.first, valueList.get(index)));
        if (index == (listList.size() - 1)) {
            tc.remove(new TripleImpl(listList.get(index), RDF.rest, RDF_NIL));
            if (index > 0) {
                tc.remove(new TripleImpl(listList.get(index - 1), RDF.rest, listList.get(index)));
                tc.add(new TripleImpl(listList.get(index - 1), RDF.rest, RDF_NIL));
            } else {
                tc.add(new TripleImpl(listList.get(index), OWL.sameAs, RDF_NIL));
            }
            listList.remove(index);
        } else {
            tc.add(new TripleImpl(listList.get(index), RDF.first, valueList.get(index + 1)));
            tc.remove(new TripleImpl(listList.get(index), RDF.rest, listList.get(index + 1)));
            tc.remove(new TripleImpl(listList.get(index + 1), RDF.first, valueList.get(index + 1)));
            if (index == (listList.size() - 2)) {
                tc.remove(new TripleImpl(listList.get(index + 1), RDF.rest, RDF_NIL));
                tc.add(new TripleImpl(listList.get(index), RDF.rest, RDF_NIL));
            } else {
                tc.remove(new TripleImpl(listList.get(index + 1), RDF.rest, listList.get(index + 2)));
                tc.add(new TripleImpl(listList.get(index), RDF.rest, listList.get(index + 2)));
            }
            listList.remove(index + 1);
        }
        return valueList.remove(index);
    }

    private BlankNodeOrIRI getRest(BlankNodeOrIRI list) {
        return (BlankNodeOrIRI) tc.filter(list, RDF.rest, null).next().getObject();
    }

    private RDFTerm getFirstEntry(final BlankNodeOrIRI listRDFTerm) {
        try {
            return tc.filter(listRDFTerm, RDF.first, null).next().getObject();
        } catch (final NullPointerException e) {
            RuntimeException runtimeEx = AccessController.doPrivileged(new PrivilegedAction<RuntimeException>() {
                @Override
                public RuntimeException run() {
                    try {
                        final FileOutputStream fileOutputStream = new FileOutputStream("/tmp/broken-list.nt");
                        final GraphNode graphNode = new GraphNode(listRDFTerm, tc);
                        Serializer.getInstance().serialize(fileOutputStream, graphNode.getNodeContext(), SupportedFormat.N_TRIPLE);
                        fileOutputStream.flush();
                        logger.warn("GraphNode: " + graphNode);
                        final Iterator<IRI> properties = graphNode.getProperties();
                        while (properties.hasNext()) {
                            logger.warn("available: " + properties.next());
                        }
                        return new RuntimeException("broken list " + listRDFTerm, e);
                    } catch (Exception ex) {
                        return new RuntimeException(ex);
                    }

                }
            });
            throw runtimeEx;
        }
    }

    public BlankNodeOrIRI getListRDFTerm() {
        return firstList;
    }

    @Override
    public boolean equals(Object obj) {
        if (obj == null) {
            return false;
        }
        if (getClass() != obj.getClass()) {
            return false;
        }
        final RdfList other = (RdfList) obj;

        if (!other.firstList.equals(this.firstList)) {
            return false;
        }

        if (!other.tc.equals(this.tc)) {
            return false;
        }

        return true;
    }

    @Override
    public int hashCode() {
        return 17 * this.firstList.hashCode() + this.tc.hashCode();
    }

    /**
     * Returns the rdf lists of which the specified <code>GraphNode</code> is
     * an element of. Sublists of other lists are not returned.
     *
     * @param element
     * @return
     */
    public static Set<RdfList> findContainingLists(GraphNode element) {
        Set<GraphNode> listNodes = findContainingListNodes(element);
        if (listNodes.isEmpty()) {
            return null;
        }

        Set<RdfList> rdfLists = new HashSet<RdfList>();
        for (Iterator<GraphNode> it = listNodes.iterator(); it.hasNext(); ) {
            GraphNode listNode = it.next();
            rdfLists.add(new RdfList(listNode));
        }
        return rdfLists;
    }

    /**
     * Returns a set of <code>GraphNode</code>S which are the first list nodes (meaning
     * they are not the beginning of a sublist) of the list containing the specified
     * <code>GraphNode</code> as an element.
     *
     * @param element
     * @return
     */
    public static Set<GraphNode> findContainingListNodes(GraphNode element) {
        Iterator<GraphNode> partOfaListNodesIter = element.getSubjectNodes(RDF.first);
        if (!partOfaListNodesIter.hasNext()) {
            return null;
        }
        Set<GraphNode> listNodes = new HashSet<GraphNode>();

        while (partOfaListNodesIter.hasNext()) {
            listNodes.addAll(findAllListNodes(partOfaListNodesIter.next()));
        }
        return listNodes;
    }

    private static Set<GraphNode> findAllListNodes(GraphNode listPart) {
        Iterator<GraphNode> invRestNodesIter;
        Set<GraphNode> listNodes = new HashSet<GraphNode>();
        do {
            invRestNodesIter = listPart.getSubjectNodes(RDF.rest);
            if (invRestNodesIter.hasNext()) {
                listPart = invRestNodesIter.next();
                while (invRestNodesIter.hasNext()) {
                    GraphNode graphNode = invRestNodesIter.next();
                    listNodes.addAll(findAllListNodes(graphNode));
                }
            } else {
                listNodes.add(listPart);
                break;
            }
        } while (true);
        return listNodes;
    }
}


<|start_filename|>impl.sparql/src/main/java/org/apache/clerezza/commons/rdf/impl/sparql/SparqlResultParser.java<|end_filename|>
/*
 * Copyright 2016 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.clerezza.commons.rdf.impl.sparql;

import java.io.IOException;
import java.io.InputStream;
import java.io.StringWriter;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;
import org.apache.clerezza.commons.rdf.BlankNode;
import org.apache.clerezza.commons.rdf.IRI;
import org.apache.clerezza.commons.rdf.Language;
import org.apache.clerezza.commons.rdf.RDFTerm;
import org.apache.clerezza.commons.rdf.impl.utils.AbstractLiteral;
import org.apache.http.util.EntityUtils;
import org.xml.sax.Attributes;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
import org.xml.sax.XMLReader;
import org.xml.sax.helpers.DefaultHandler;

/**
 *
 * @author user
 */
public class SparqlResultParser {

    static Object parse(InputStream in) throws IOException {
        try {
            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));
            return sparqlsResultsHandler.getResults();
        } catch (ParserConfigurationException | SAXException ex) {
            throw new RuntimeException(ex);
        }
    }

    final public static class SparqlsResultsHandler extends DefaultHandler {

        private String currentBindingName;
        private Map<String, RDFTerm> currentResult = null;
        private Object results = null;
        private boolean readingValue;
        private String lang; //the xml:lang attribute of a literal
        private StringWriter valueWriter;
        private Map<String, BlankNode> bNodeMap = new HashMap<>();
        private static final IRI XSD_STRING = new IRI("http://www.w3.org/2001/XMLSchema#string");
        private static final IRI RDF_LANG_STRING = new IRI("http://www.w3.org/1999/02/22-rdf-syntax-ns#langString");

        private RDFTerm getBNode(String value) {
            if (!bNodeMap.containsKey(value)) {
                bNodeMap.put(value, new BlankNode());
            }
            return bNodeMap.get(value);
        }

        private Object getResults() {
            return results;
        }

        private List<Map<String, RDFTerm>> getResultValueMaps() {
            return (List<Map<String, RDFTerm>>) 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 ("boolean".equals(localName)) {
                    if (results != null) {
                        throw new SAXException("unexpected tag <boolean>");
                    }
                    //results will have Boolean value assigned once value is read
                    readingValue = true;
                    valueWriter = new StringWriter();
                } else if ("results".equals(localName)) {
                    if (results != null) {
                        throw new SAXException("unexpected tag <result>");
                    }
                    results = new ArrayList<Map<String, RDFTerm>>();
                } else if ("result".equals(localName)) {
                    if (currentResult != null) {
                        throw new SAXException("unexpected tag <result>");
                    }
                    currentResult = new HashMap<String, RDFTerm>();
                } 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 + ">");
                    }
                    lang = atts.getValue("http://www.w3.org/XML/1998/namespace", "lang");
                    readingValue = true;
                    valueWriter = new StringWriter();
                }
            }

            //System.out.println(namespaceURI);
            //System.out.println(qName);
        }

        @Override
        public void characters(char[] chars, int start, int length) throws SAXException {
            if (readingValue) {
                valueWriter.write(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)) {
                    ((List<Map<String, RDFTerm>>) results).add(currentResult);
                    currentResult = null;
                } else if ("binding".equals(localName)) {
                    if (currentBindingName == null) {
                        throw new SAXException("unexpected tag </binding>");
                    }
                    currentBindingName = null;
                } else if ("boolean".equals(localName)) {
                    results = new Boolean(valueWriter.toString());
                    valueWriter = null;
                    readingValue = false;
                } else {
                    try {
                        BindingType b = BindingType.valueOf(localName);
                        RDFTerm rdfTerm = null;
                        final Language language = lang == null ? null : new Language(lang);;
                        switch (b) {
                            case uri:
                                rdfTerm = new IRI(valueWriter.toString());
                                valueWriter = null;
                                break;
                            case bnode:
                                rdfTerm = getBNode(valueWriter.toString());
                                valueWriter = null;
                                break;
                            case literal:
                                final String lf = valueWriter.toString();
                                rdfTerm = new AbstractLiteral() {

                                    @Override
                                    public String getLexicalForm() {
                                        return lf;
                                    }

                                    @Override
                                    public IRI getDataType() {
                                        if (language != null) {
                                            return RDF_LANG_STRING;
                                        }
                                        //TODO implement
                                        return XSD_STRING;
                                    }

                                    @Override
                                    public Language getLanguage() {
                                        return language;
                                    }

                                    @Override
                                    public String toString() {
                                        return "\"" + getLexicalForm() + "\"@" + getLanguage();
                                    }
                                };
                                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());
        }

    }
}


<|start_filename|>api-implementation/src/main/java/org/apache/clerezza/implementation/util/W3CDateFormat.java<|end_filename|>
//taken from GVS MillisDateFormat.java, modified to support different precision

/*
 (c) Copyright 2005, 2006, Hewlett-Packard Development Company, LP
 [See end of file]
 $Id: W3CDateFormat.java,v 1.6 2007/05/07 18:45:22 rebach Exp $
 */
/*
 *
 * 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.clerezza.implementation.util;

import java.text.DateFormat;
import java.text.FieldPosition;
import java.text.ParsePosition;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * @author reto implements http://www.w3.org/TR/NOTE-datetime with the
 * limitation that it expects exactly a three digits decimal fraction of
 * seconds. if a time zone designator other than 'Z' is present it must
 * contain a column
 */
public class W3CDateFormat extends DateFormat {
    /**
     * An instance of this class
     */
    public static final W3CDateFormat instance = new W3CDateFormat();

    private static final SimpleDateFormat dateFormatWithMillis = new SimpleDateFormat(
            "yyyy-MM-dd'T'HH:mm:ss.SSSZ");
    private static final SimpleDateFormat dateFormatNoMillis = new SimpleDateFormat(
            "yyyy-MM-dd'T'HH:mm:ssZ");

    private static final long serialVersionUID = 3258407344076372025L;

    private static final TimeZone utcTZ = new SimpleTimeZone(0, "UTC");

    static {
        dateFormatWithMillis.setTimeZone(utcTZ);
        dateFormatNoMillis.setTimeZone(utcTZ);
    }

    @Override
    public void setTimeZone(TimeZone zone) {
        super.setTimeZone(zone);
    }


    /**
     * @see java.text.DateFormat#format(java.util.Date, java.lang.StringBuffer,
     * java.text.FieldPosition)
     */
    @Override
    public StringBuffer format(Date date, StringBuffer toAppendTo,
                               FieldPosition fieldPosition) {

        final DateFormat dateFormat = (date.getTime() % 1000) == 0 ?
                dateFormatNoMillis : dateFormatWithMillis;
        String string = dateFormat.format(date);
        if (string.endsWith("0000")) {
            StringBuffer result = new StringBuffer(string.substring(0, string.length() - 5));
            result.append('Z');
            return result;
        } else {
            StringBuffer result = new StringBuffer(string);
            result.insert(string.length() - 2, ':');
            return result;
        }
    }

    /**
     * @see java.text.DateFormat#parse(java.lang.String,
     * java.text.ParsePosition)
     */
    public Date parse(String dateString, ParsePosition parsePos) {

        int position = parsePos.getIndex();

        int y1 = dateString.charAt(position++) - '0';
        int y2 = dateString.charAt(position++) - '0';
        int y3 = dateString.charAt(position++) - '0';
        int y4 = dateString.charAt(position++) - '0';
        int year = 1000 * y1 + 100 * y2 + 10 * y3 + y4;
        position++; // skip '-'
        int m1 = dateString.charAt(position++) - '0';
        int m2 = dateString.charAt(position++) - '0';
        int month = 10 * m1 + m2;
        position++; // skip '-'
        int d1 = dateString.charAt(position++) - '0';
        int d2 = dateString.charAt(position++) - '0';
        int day = 10 * d1 + d2;
        position++; // skip 'T'
        int h1 = dateString.charAt(position++) - '0';
        int h2 = dateString.charAt(position++) - '0';
        int hour = 10 * h1 + h2;
        position++; // skip ':'
        int min1 = dateString.charAt(position++) - '0';
        int min2 = dateString.charAt(position++) - '0';
        int minutes = 10 * min1 + min2;
        position++; // skip ':'
        int s1 = dateString.charAt(position++) - '0';
        int s2 = dateString.charAt(position++) - '0';
        int secs = 10 * s1 + s2;
        Calendar resultCalendar = new GregorianCalendar(year, month - 1, day,
                hour, minutes, secs);
        resultCalendar.setTimeZone(utcTZ);
        char afterSecChar = dateString.charAt(position++);
        int msecs = 0;
        char tzd1;
        if (afterSecChar == '.') {
            int startPos = position;
            //read decimal part, this is till there is a 'Z', a '+' or a '-'
            char nextChar = dateString.charAt(position++);
            while ((nextChar != 'Z') && (nextChar != '-') && (nextChar != '+')) {
                msecs += (nextChar - '0') * Math.pow(10, 3 + startPos - position);
                nextChar = dateString.charAt(position++);
            }
            tzd1 = nextChar;
        } else {
            tzd1 = afterSecChar;
        }
        long timeInMillis = resultCalendar.getTimeInMillis() + msecs;
        if (tzd1 != 'Z') {
            int htz1 = dateString.charAt(position++) - '0';
            int htz2 = dateString.charAt(position++) - '0';
            int hourtz = 10 * htz1 + htz2;
            position++; // skip ':'
            int mintz1 = dateString.charAt(position++) - '0';
            int mintz2 = dateString.charAt(position++) - '0';
            int minutestz = 10 * mintz1 + mintz2;
            int offSetInMillis = (hourtz * 60 + minutestz) * 60000;
            if (tzd1 == '+') {
                timeInMillis -= offSetInMillis;
            } else {
                timeInMillis += offSetInMillis;
            }
        }
        parsePos.setIndex(position);
        return new Date(timeInMillis);

    }
}

/*
 * (c) Copyright 2005, 2006 Hewlett-Packard Development Company, LP All rights
 * reserved.
 * 
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 * 
 * 1. Redistributions of source code must retain the above copyright notice,
 * this list of conditions and the following disclaimer.
 * 
 * 2. Redistributions in binary form must reproduce the above copyright notice,
 * this list of conditions and the following disclaimer in the documentation
 * and/or other materials provided with the distribution.
 * 
 * 3. The name of the author may not be used to endorse or promote products
 * derived from this software without specific prior written permission.
 * 
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
 * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */



<|start_filename|>dataset/src/main/java/org/apache/clerezza/simple/storage/SimpleTcProvider.java<|end_filename|>
/*
 * 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.clerezza.simple.storage;

import org.apache.clerezza.Graph;
import org.apache.clerezza.IRI;
import org.apache.clerezza.ImmutableGraph;
import org.apache.clerezza.implementation.in_memory.SimpleGraph;
import org.apache.clerezza.implementation.in_memory.SimpleImmutableGraph;
import org.apache.clerezza.dataset.*;
import org.osgi.service.component.annotations.Component;

import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;

@Component(service = WeightedTcProvider.class, property = TcManager.GENERAL_PURPOSE_TC+"=true")
public class SimpleTcProvider implements WeightedTcProvider {

    private Map<IRI, Graph> tripleMap = new HashMap<IRI, Graph>();

    @Override
    public ImmutableGraph createImmutableGraph(IRI name, Graph triples)
            throws EntityAlreadyExistsException {
        if ((name == null) || (name.getUnicodeString() == null)
                || (name.getUnicodeString().trim().length() == 0)) {
            throw new IllegalArgumentException("Name must not be null");
        }

        try {
            // throws NoSuchEntityException if a Graph with that name
            // already exists
            this.getGraph(name);
        } catch (NoSuchEntityException e) {
            ImmutableGraph result;
            if (triples == null) {
                result = new SimpleImmutableGraph(new SimpleGraph());
            } else {
                if (ImmutableGraph.class.isAssignableFrom(triples.getClass())) {
                    result = (ImmutableGraph) triples;
                } else {
                    result = new SimpleImmutableGraph(triples);
                }
            }
            tripleMap.put(name, result);

            return result;
        }
        throw new EntityAlreadyExistsException(name);
    }

    @Override
    public Graph createGraph(IRI name) throws EntityAlreadyExistsException {
        if ((name == null) || (name.getUnicodeString() == null)
                || (name.getUnicodeString().trim().length() == 0)) {
            throw new IllegalArgumentException("Name must not be null");
        }

        try {
            // throws NoSuchEntityException if a Graph with that name
            // already exists
            this.getGraph(name);
        } catch (NoSuchEntityException e) {
            Graph result = new SimpleGraph();
            tripleMap.put(name, result);
            return result;
        }
        throw new EntityAlreadyExistsException(name);
    }

    @Override
    public void deleteGraph(IRI name)
            throws NoSuchEntityException, EntityUndeletableException {
        if (tripleMap.remove(name) == null) {
            throw new NoSuchEntityException(name);
        }
    }

    @Override
    public ImmutableGraph getImmutableGraph(IRI name) throws NoSuchEntityException {
        Graph tripleCollection = tripleMap.get(name);
        if (tripleCollection == null) {
            throw new NoSuchEntityException(name);
        } else if (ImmutableGraph.class.isAssignableFrom(tripleCollection.getClass())) {
            return (ImmutableGraph) tripleCollection;
        }
        throw new NoSuchEntityException(name);
    }

    @Override
    public Graph getMGraph(IRI name) throws NoSuchEntityException {
        Graph tripleCollection = tripleMap.get(name);
        if (tripleCollection == null) {
            throw new NoSuchEntityException(name);
        } else if (!ImmutableGraph.class.isAssignableFrom(tripleCollection.getClass())) {
            return (Graph) tripleCollection;
        }
        throw new NoSuchEntityException(name);
    }

    @Override
    public Set<IRI> getNames(ImmutableGraph graph) {
        throw new UnsupportedOperationException(
                "Not supported yet. equals() has to be implemented first");
    }

    @Override
    public Graph getGraph(IRI name)
            throws NoSuchEntityException {
        Graph tripleCollection = tripleMap.get(name);
        if (tripleCollection == null) {
            throw new NoSuchEntityException(name);
        } else {
            return tripleCollection;
        }
    }

    @Override
    public int getWeight() {
        return 1;
    }

    @Override
    public Set<IRI> listImmutableGraphs() {
        Set<IRI> result = new HashSet<IRI>();
        for (IRI uriRef : listGraphs()) {
            if (tripleMap.get(uriRef) instanceof ImmutableGraph) {
                result.add(uriRef);
            }
        }
        return result;
    }

    @Override
    public Set<IRI> listMGraphs() {
        Set<IRI> result = new HashSet<IRI>();
        for (IRI uriRef : listGraphs()) {
            if (!(tripleMap.get(uriRef) instanceof ImmutableGraph)) {
                result.add(uriRef);
            }
        }
        return result;
    }

    @Override
    public Set<IRI> listGraphs() {
        return tripleMap.keySet();
    }
}


<|start_filename|>sparql/src/main/java/org/apache/clerezza/sparql/query/impl/SimpleMinusGraphPattern.java<|end_filename|>
/*
 * 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.clerezza.sparql.query.impl;

import org.apache.clerezza.sparql.query.GraphPattern;
import org.apache.clerezza.sparql.query.GroupGraphPattern;
import org.apache.clerezza.sparql.query.MinusGraphPattern;

/**
 * This class implements {@link MinusGraphPattern}.
 *
 * @author hasan
 */
public class SimpleMinusGraphPattern implements MinusGraphPattern {

    private GraphPattern minuendGraphPattern;
    private GroupGraphPattern subtrahendGraphPattern;

    /**
     * Constructs a {@link MinusGraphPattern} out of a {@link GraphPattern}
     * as the minuend ImmutableGraph pattern and a {@link GroupGraphPattern} as the 
     * subtrahend pattern.
     * 
     * @param minuendGraphPattern
     *        a {@link GraphPattern} specifying the minuend pattern.
     * @param subtrahendGraphPattern
     *        a {@link GroupGraphPattern} specifying the subtrahend pattern.
     */
    public SimpleMinusGraphPattern(GraphPattern minuendGraphPattern, GroupGraphPattern subtrahendGraphPattern) {
        if (subtrahendGraphPattern == null) {
            throw new IllegalArgumentException("Subtrahend ImmutableGraph pattern may not be null");
        }
        if (minuendGraphPattern == null) {
            this.minuendGraphPattern = new SimpleGroupGraphPattern();
        } else {
            this.minuendGraphPattern = minuendGraphPattern;
        }
        this.subtrahendGraphPattern = subtrahendGraphPattern;
    }

    @Override
    public GraphPattern getMinuendGraphPattern() {
        return minuendGraphPattern;
    }

    @Override
    public GroupGraphPattern getSubtrahendGraphPattern() {
        return subtrahendGraphPattern;
    }

}


<|start_filename|>api-implementation/src/main/java/org/apache/clerezza/implementation/graphmatching/GraphMatcher.java<|end_filename|>
/*
 * 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.clerezza.implementation.graphmatching;

import org.apache.clerezza.*;
import org.apache.clerezza.implementation.TripleImpl;
import org.apache.clerezza.implementation.in_memory.SimpleGraph;

import java.util.Iterator;
import java.util.Map;
import java.util.Set;
import java.util.logging.Level;
import java.util.logging.Logger;

/**
 * @author reto
 */
public class GraphMatcher {

    private final static Logger log = Logger.getLogger(GraphMatcher.class.getName());

    /**
     * get a mapping from g1 to g2 or null if the graphs are not isomorphic. The
     * returned map maps each <code>BNode</code>s from g1 to one
     * of g2. If the graphs are ground graphs the method return an empty map if
     * the ImmutableGraph are equals and null otherwise.
     * <p/>
     * NOTE: This method does not returned mapping from blank nodes to grounded
     * nodes, a bnode in g1 is not a vraiable that may match any node, but must
     * match a bnode in g2.
     * <p/>
     * <p>
     * On the algorithm:<br/>
     * - In a first step it checked if every grounded triple in g1 matches one
     * in g2<br/>
     * - [optional] blank node blind matching</br>
     * - in a map mbng1 bnode of g1 is mapped to a set of of its
     * properties and inverse properties, this is the predicate and the object
     * or subject respectively, analoguosly in mbgn2 every bnode of g2<br/>
     * - based on the incoming and outgoing properties a hash is calculated for
     * each bnode, in the first step when calculating the hash  aconstant value
     * is taken for the bnodes that might be subject or object in the (inverse properties)
     * - hash-classes:
     *
     * @param g1
     * @param g2
     * @return a Set of NodePairs
     */
    public static Map<BlankNode, BlankNode> getValidMapping(Graph og1, Graph og2) {
        Graph g1 = new SimpleGraph(og1);
        Graph g2 = new SimpleGraph(og2);
        if (!Utils.removeGrounded(g1, g2)) {
            return null;
        }
        final HashMatching hashMatching;
        try {
            hashMatching = new HashMatching(g1, g2);
        } catch (GraphNotIsomorphicException ex) {
            return null;
        }
        Map<BlankNode, BlankNode> matchings = hashMatching.getMatchings();
        if (g1.size() > 0) {
            //start trial an error matching
            //TODO (CLEREZZA-81) at least in the situation where one matching
            //group is big (approx > 5) we should switch back to hash-based matching
            //after a first guessed matching, rather than try all permutations
            Map<BlankNode, BlankNode> remainingMappings = trialAndErrorMatching(g1, g2, hashMatching.getMatchingGroups());
            if (remainingMappings == null) {
                return null;
            } else {
                matchings.putAll(remainingMappings);
            }
        }
        return matchings;
    }

    private static Map<BlankNode, BlankNode> trialAndErrorMatching(Graph g1, Graph g2,
                                                                   Map<Set<BlankNode>, Set<BlankNode>> matchingGroups) {
        if (log.isLoggable(Level.FINE)) {
            Set<BlankNode> bn1 = Utils.getBNodes(g1);
            log.log(Level.FINE, "doing trial and error matching for {0}" + " bnodes, " + "in graphs of size: {1}.", new Object[]{bn1.size(), g1.size()});
        }
        Iterator<Map<BlankNode, BlankNode>> mappingIter
                = GroupMappingIterator.create(matchingGroups);
        while (mappingIter.hasNext()) {
            Map<BlankNode, BlankNode> map = mappingIter.next();
            if (checkMapping(g1, g2, map)) {
                return map;
            }
        }
        return null;
    }

    private static boolean checkMapping(Graph g1, Graph g2, Map<BlankNode, BlankNode> map) {
        for (Triple triple : g1) {
            if (!g2.contains(map(triple, map))) {
                return false;
            }
        }
        return true;
    }

    private static Triple map(Triple triple, Map<BlankNode, BlankNode> map) {
        final BlankNodeOrIRI oSubject = triple.getSubject();

        BlankNodeOrIRI subject = oSubject instanceof BlankNode ?
                map.get((BlankNode) oSubject) : oSubject;

        RDFTerm oObject = triple.getObject();
        RDFTerm object = oObject instanceof BlankNode ?
                map.get((BlankNode) oObject) : oObject;
        return new TripleImpl(subject, triple.getPredicate(), object);
    }
}


<|start_filename|>test.utils/src/main/java/org/apache/clerezza/test/utils/GraphWrapper.java<|end_filename|>
/*
 * 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.clerezza.test.utils;

import org.apache.clerezza.*;

import java.util.Collection;
import java.util.Iterator;
import java.util.concurrent.locks.ReadWriteLock;

/**
 *
 * @author mir
 */
class GraphWrapper implements Graph {

    protected Graph wrapped;

    public GraphWrapper(Graph tc) {
        this.wrapped = tc;
    }

    @Override
    public Iterator<Triple> filter(BlankNodeOrIRI subject, IRI predicate, RDFTerm object) {
        return wrapped.filter(subject, predicate, object);
    }

    
    @Override
    public int size() {
        return wrapped.size();
    }

    @Override
    public boolean isEmpty() {
        return wrapped.isEmpty();
    }

    @Override
    public boolean contains(Object o) {
        return wrapped.contains(o);
    }

    @Override
    public Iterator<Triple> iterator() {
        return wrapped.iterator();
    }

    @Override
    public Object[] toArray() {
        return wrapped.toArray();
    }

    @Override
    public <T> T[] toArray(T[] a) {
        return wrapped.toArray(a);
    }

    @Override
    public boolean add(Triple e) {
        return wrapped.add(e);
    }

    @Override
    public boolean remove(Object o) {
        return wrapped.remove(o);
    }

    @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 removeAll(Collection<?> c) {
        return wrapped.removeAll(c);
    }

    @Override
    public boolean retainAll(Collection<?> c) {
        return wrapped.retainAll(c);
    }

    @Override
    public void clear() {
        wrapped.clear();
    }

    @Override
    public ImmutableGraph getImmutableGraph() {
        return wrapped.getImmutableGraph();
    }

    @Override
    public ReadWriteLock getLock() {
        return wrapped.getLock();
    }

}


<|start_filename|>api.utils/src/main/java/org/apache/clerezza/utils/Smusher.java<|end_filename|>
/*
 * 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.clerezza.utils;

import org.apache.clerezza.Graph;
import org.apache.clerezza.utils.smushing.IfpSmusher;
import org.apache.clerezza.utils.smushing.SameAsSmusher;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * A utility to smush equivalent resources. For greater flexibility use the
 * classes in the smushing package.
 *
 * @author reto
 */
public class Smusher {

    static final Logger log = LoggerFactory.getLogger(Smusher.class);

    /**
     * smush mGaph given the ontological facts. Currently it does only one step
     * ifp smushin, i.e. only ifps are taken in account and only nodes that have
     * the same node as ifp object in the orignal graph are equates. (calling
     * the method a second time might lead to additional smushings.)
     *
     * @param mGraph
     * @param tBox
     */
    public static void smush(Graph mGraph, Graph tBox) {
        new IfpSmusher().smush(mGraph, tBox);
    }

    /**
     * Smushes the specified graph adding owl:sameAs statements pointing to the new canonical IRI
     *
     * @param mGraph
     * @param owlSameStatements
     */
    public static void sameAsSmush(Graph mGraph, Graph owlSameStatements) {
        new SameAsSmusher().smush(mGraph, owlSameStatements, true);
    }
}


<|start_filename|>api-implementation/src/main/java/org/apache/clerezza/implementation/graphmatching/GroupMappingIterator.java<|end_filename|>
/*
 * 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.clerezza.implementation.graphmatching;

import java.util.*;

/**
 * Iterates over all mappings from each element of every Set<T> to each
 * elemenent of their corresponding Set<U>.
 *
 * @author reto
 */
class GroupMappingIterator<T, U> implements Iterator<Map<T, U>> {

    private Iterator<Map<T, U>> firstPartIter;
    private Map<T, U> currentFirstPart;
    final private Map<Set<T>, Set<U>> restMap;
    private Iterator<Map<T, U>> currentRestPartIter;

    static <T, U> Iterator<Map<T, U>> create(Map<Set<T>, Set<U>> matchingGroups) {
        if (matchingGroups.size() > 1) {
            return new GroupMappingIterator<T, U>(matchingGroups);
        } else {
            if (matchingGroups.size() == 0) {
                return new ArrayList<Map<T, U>>(0).iterator();
            }
            Map.Entry<Set<T>, Set<U>> entry = matchingGroups.entrySet().iterator().next();
            return new MappingIterator<T, U>(entry.getKey(),
                    entry.getValue());
        }
    }

    private GroupMappingIterator(Map<Set<T>, Set<U>> matchingGroups) {
        if (matchingGroups.size() == 0) {
            throw new IllegalArgumentException("matchingGroups must not be empty");
        }
        restMap = new HashMap<Set<T>, Set<U>>();
        boolean first = true;
        for (Map.Entry<Set<T>, Set<U>> entry : matchingGroups.entrySet()) {
            if (first) {
                firstPartIter = new MappingIterator<T, U>(entry.getKey(),
                        entry.getValue());
                first = false;
            } else {
                restMap.put(entry.getKey(), entry.getValue());
            }
        }
        currentRestPartIter = create(restMap);
        currentFirstPart = firstPartIter.next();
    }

    @Override
    public boolean hasNext() {
        return firstPartIter.hasNext() || currentRestPartIter.hasNext();
    }

    @Override
    public Map<T, U> next() {
        Map<T, U> restPart;
        if (currentRestPartIter.hasNext()) {
            restPart = currentRestPartIter.next();
        } else {
            if (firstPartIter.hasNext()) {
                currentFirstPart = firstPartIter.next();
                currentRestPartIter = create(restMap);
                restPart = currentRestPartIter.next();
            } else {
                throw new NoSuchElementException();
            }
        }
        Map<T, U> result = new HashMap<T, U>(restPart);
        result.putAll(currentFirstPart);
        return result;
    }

    @Override
    public void remove() {
        throw new UnsupportedOperationException("Not supported.");
    }

}


<|start_filename|>api.utils/src/test/java/org/apache/clerezza/utils/UnionGraphTest.java<|end_filename|>
/*
 * 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.clerezza.utils;

import org.apache.clerezza.BlankNode;
import org.apache.clerezza.Graph;
import org.apache.clerezza.IRI;
import org.apache.clerezza.Triple;
import org.apache.clerezza.implementation.TripleImpl;
import org.apache.clerezza.implementation.in_memory.SimpleGraph;
import org.junit.Assert;
import org.junit.Test;

import java.util.Iterator;

/**
 * @author hasan
 */
public class UnionGraphTest {

    private final IRI uriRef1 =
            new IRI("http://example.org/ontology#res1");
    private final IRI uriRef2 =
            new IRI("http://example.org/ontology#res2");
    private final IRI uriRef3 =
            new IRI("http://example.org/ontology#res3");
    private final IRI uriRef4 =
            new IRI("http://example.org/ontology#res4");

    @Test
    public void readAccess() {
        Graph graph = new SimpleGraph();
        Graph graph2 = new SimpleGraph();
        BlankNode bnode = new BlankNode() {
        };
        graph.add(new TripleImpl(uriRef1, uriRef2, uriRef1));
        graph2.add(new TripleImpl(bnode, uriRef1, uriRef3));
        Graph unionGraph = new UnionGraph(graph, graph2);
        Iterator<Triple> unionTriples = unionGraph.iterator();
        Assert.assertTrue(unionTriples.hasNext());
        unionTriples.next();
        Assert.assertTrue(unionTriples.hasNext());
        unionTriples.next();
        Assert.assertFalse(unionTriples.hasNext());
        Assert.assertEquals(2, unionGraph.size());
    }

    @Test
    public void writeAccess() {
        Graph graph = new SimpleGraph();
        Graph graph2 = new SimpleGraph();
        BlankNode bnode = new BlankNode() {
        };
        graph2.add(new TripleImpl(bnode, uriRef1, uriRef3));
        Graph unionGraph = new UnionGraph(graph, graph2);
        Assert.assertEquals(1, unionGraph.size());
        unionGraph.add(new TripleImpl(uriRef4, uriRef1, uriRef3));
        Assert.assertEquals(1, graph.size());
        Assert.assertEquals(2, unionGraph.size());
        Assert.assertEquals(1, graph2.size());
    }
}

<|start_filename|>api.utils/src/main/java/org/apache/clerezza/utils/smushing/BaseSmusher.java<|end_filename|>
/*
 * 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.clerezza.utils.smushing;

import org.apache.clerezza.*;
import org.apache.clerezza.implementation.TripleImpl;
import org.apache.clerezza.implementation.in_memory.SimpleGraph;
import org.apache.clerezza.ontologies.OWL;

import java.util.*;
import java.util.concurrent.locks.Lock;

/**
 * @author Reto
 */
public class BaseSmusher {

    /**
     * Smushes the resources in mGraph that belong to the same set in equivalenceSets,
     * i.e. it adds all properties to one of the resources in the equivalence set.
     * <p>
     * Optionally owl:sameAs statement are added that point from the IRIs that
     * no longer have properties to the one with properties. If addOwlSameAs
     * is false the IRIs will just disappear from the graph.
     *
     * @param mGraph          the graph to smush
     * @param equivalenceSets sets of equivalent resources
     * @param addOwlSameAs    whether owl:sameAs statements should be added
     */
    public void smush(Graph mGraph, Set<Set<BlankNodeOrIRI>> equivalenceSets, boolean addOwlSameAs) {
        Map<BlankNodeOrIRI, BlankNodeOrIRI> current2ReplacementMap = new HashMap<BlankNodeOrIRI, BlankNodeOrIRI>();
        final Graph owlSameAsGraph = new SimpleGraph();
        for (Set<BlankNodeOrIRI> equivalenceSet : equivalenceSets) {
            final BlankNodeOrIRI replacement = getReplacementFor(equivalenceSet, owlSameAsGraph);
            for (BlankNodeOrIRI current : equivalenceSet) {
                if (!current.equals(replacement)) {
                    current2ReplacementMap.put(current, replacement);
                }
            }
        }
        final Set<Triple> newTriples = new HashSet<Triple>();
        Lock l = mGraph.getLock().writeLock();
        l.lock();
        try {
            for (Iterator<Triple> it = mGraph.iterator(); it.hasNext(); ) {
                final Triple triple = it.next();
                final BlankNodeOrIRI subject = triple.getSubject();
                BlankNodeOrIRI subjectReplacement = current2ReplacementMap.get(subject);
                final RDFTerm object = triple.getObject();
                @SuppressWarnings(value = "element-type-mismatch")
                RDFTerm objectReplacement = current2ReplacementMap.get(object);
                if ((subjectReplacement != null) || (objectReplacement != null)) {
                    it.remove();
                    if (subjectReplacement == null) {
                        subjectReplacement = subject;
                    }
                    if (objectReplacement == null) {
                        objectReplacement = object;
                    }
                    newTriples.add(new TripleImpl(subjectReplacement, triple.getPredicate(), objectReplacement));
                }
            }
            for (Triple triple : newTriples) {
                mGraph.add(triple);
            }
            mGraph.addAll(owlSameAsGraph);
        } finally {
            l.unlock();
        }
    }

    private BlankNodeOrIRI getReplacementFor(Set<BlankNodeOrIRI> equivalenceSet,
                                             Graph owlSameAsGraph) {
        final Set<IRI> uriRefs = new HashSet<IRI>();
        for (BlankNodeOrIRI nonLiteral : equivalenceSet) {
            if (nonLiteral instanceof IRI) {
                uriRefs.add((IRI) nonLiteral);
            }
        }
        switch (uriRefs.size()) {
            case 1:
                return uriRefs.iterator().next();
            case 0:
                return new BlankNode();
        }
        final IRI preferedIRI = getPreferedIRI(uriRefs);
        final Iterator<IRI> uriRefIter = uriRefs.iterator();
        while (uriRefIter.hasNext()) {
            IRI uriRef = uriRefIter.next();
            if (!uriRef.equals(preferedIRI)) {
                owlSameAsGraph.add(new TripleImpl(uriRef, OWL.sameAs, preferedIRI));
            }
        }
        return preferedIRI;
    }


    /**
     * Returns a prefered IRI for the IRIs in a set. Typically and in the
     * default implementation the IRI will be one of the set. Note however that
     * subclass implementations may also return another IRI to be used.
     *
     * @param uriRefs
     * @return
     */
    protected IRI getPreferedIRI(Set<IRI> uriRefs) {
        final Iterator<IRI> uriRefIter = uriRefs.iterator();
        //instead of an arbitrary one we might either decide lexicographically
        //or look at their frequency in mGraph
        return uriRefIter.next();
    }

}


<|start_filename|>representation/src/main/java/org/apache/clerezza/representation/ParsingProvider.java<|end_filename|>
/*
 * 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.clerezza.representation;

import org.apache.clerezza.Graph;
import org.apache.clerezza.IRI;

import java.io.InputStream;

/**
 * An instance of this class parses RDF-ImmutableGraph from one or more serialization
 * formats. The supported formats are indicated using the {@link SupportedFormat}
 * annotation.
 *
 * @author reto
 */
public interface ParsingProvider {

    /**
     * Parses a stream as the specified RDF-format. This method will be invoked
     * for a supported format, a format is considered as supported if the part
     * before a ';'-character in the <code>formatIdentifier</code> matches
     * a <code>SupportedFormat</code> annotation of the implementing class.
     *
     * @param target the mutable ImmutableGraph to which the read triples shall be added
     * @param serializedGraph the stream from which the serialized ImmutableGraph is read
     * @param formatIdentifier a String identifying the format
     * @param baseUri the baseUri for interpreting relative uris, may be null
     */
    void parse(Graph target, InputStream serializedGraph,
               String formatIdentifier, IRI baseUri);

}


<|start_filename|>api.utils/src/main/java/org/apache/clerezza/utils/SeeAlsoExpander.java<|end_filename|>
/*
 * 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.clerezza.utils;

import org.apache.clerezza.IRI;
import org.apache.clerezza.RDFTerm;
import org.apache.clerezza.Graph;
import org.apache.clerezza.dataset.NoSuchEntityException;
import org.apache.clerezza.dataset.TcManager;
import org.apache.clerezza.ontologies.RDFS;

import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;
import java.util.concurrent.locks.Lock;

/**
 * Expands a GraphNode expanding SeeAlso-References of the node.
 *
 * @author reto
 */
public class SeeAlsoExpander {
    /**
     * using TcManger instead of TcProvider as this ensures LockableGraphs
     */
    private final TcManager tcManager;

    public SeeAlsoExpander(TcManager tcManager) {
        this.tcManager = tcManager;
    }

    /**
     * expands a node dereferencing its rdfs:seeAlso references using the
     * tcManager associated to this instance. If the added TripleCollections
     * also associate rdfs:seeAlso properties to node this are expanded till
     * the maximum recursion depth specified.
     *
     * @param node      the node to be expanded
     * @param recursion the maximum recursion depth
     * @return a new GraphNode over the union of the original and all expansion graphs
     */
    public GraphNode expand(GraphNode node, int recursion) {
        Set<IRI> alreadyVisited = new HashSet();
        Set<Graph> resultTripleCollections = new HashSet<Graph>();
        resultTripleCollections.add(node.getGraph());
        for (IRI uriRef : expand(node, alreadyVisited, recursion)) {
            try {
                resultTripleCollections.add(tcManager.getGraph(uriRef));
            } catch (NoSuchEntityException e) {
                //ignore
            }
        }
        return new GraphNode(node.getNode(),
                new UnionGraph(resultTripleCollections.toArray(
                        new Graph[resultTripleCollections.size()])));
    }

    private Set<IRI> getSeeAlsoObjectUris(GraphNode node) {
        Set<IRI> result = new HashSet<IRI>();
        Lock l = node.readLock();
        l.lock();
        try {
            Iterator<RDFTerm> objects = node.getObjects(RDFS.seeAlso);
            while (objects.hasNext()) {
                RDFTerm next = objects.next();
                if (next instanceof IRI) {
                    result.add((IRI) next);
                }
            }
        } finally {
            l.unlock();
        }
        return result;
    }

    private Set<IRI> expand(GraphNode node, Set<IRI> alreadyVisited, int recursion) {
        Set<IRI> rdfSeeAlsoTargets = getSeeAlsoObjectUris(node);
        Set<IRI> result = new HashSet<IRI>();
        result.addAll(rdfSeeAlsoTargets);
        recursion++;
        if (recursion > 0) {
            rdfSeeAlsoTargets.removeAll(alreadyVisited);
            alreadyVisited.addAll(rdfSeeAlsoTargets);
            for (IRI target : rdfSeeAlsoTargets) {
                try {
                    result.addAll(expand(new GraphNode(node.getNode(),
                            tcManager.getGraph(target)), alreadyVisited, recursion));
                } catch (NoSuchEntityException e) {
                    //ignore
                }
            }
        }
        return result;
    }

}


<|start_filename|>api-implementation/src/main/java/org/apache/clerezza/implementation/in_memory/SimpleImmutableGraph.java<|end_filename|>
/*
 * 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.clerezza.implementation.in_memory;

import org.apache.clerezza.*;
import org.apache.clerezza.implementation.graph.AbstractImmutableGraph;
import org.apache.clerezza.implementation.in_memory.SimpleGraph;

import java.util.Iterator;

/**
 * @author reto
 */
public class SimpleImmutableGraph extends AbstractImmutableGraph {

    private Graph graph;

    /**
     * Creates a ImmutableGraph with the triples in Graph
     *
     * @param Graph the collection of triples this ImmutableGraph shall consist of
     */
    public SimpleImmutableGraph(Graph Graph) {
        this.graph = new SimpleGraph(Graph.iterator());
    }

    /**
     * Creates a ImmutableGraph with the triples in Graph.
     * <p>
     * This construction allows to specify if the Graph might change
     * in future. If GraphWillNeverChange is set to true it will
     * assume that the collection never changes, in this case the collection
     * isn't copied making things more efficient.
     *
     * @param Graph                the collection of triples this ImmutableGraph shall consist of
     * @param GraphWillNeverChange true if the caller promises Graph will never change
     */
    public SimpleImmutableGraph(Graph Graph, boolean GraphWillNeverChange) {
        if (!GraphWillNeverChange) {
            this.graph = new SimpleGraph(Graph.iterator());
        } else {
            this.graph = Graph;
        }
    }

    public SimpleImmutableGraph(Iterator<Triple> tripleIter) {
        this.graph = new SimpleGraph(tripleIter);
    }

    @Override
    public int performSize() {
        return graph.size();
    }

    @Override
    public Iterator<Triple> performFilter(BlankNodeOrIRI subject, IRI predicate, RDFTerm object) {
        return graph.filter(subject, predicate, object);
    }
}


<|start_filename|>api-implementation/src/main/java/org/apache/clerezza/implementation/literal/TypedLiteralImpl.java<|end_filename|>
/*
 * 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.clerezza.implementation.literal;

import org.apache.clerezza.IRI;
import org.apache.clerezza.Language;

import java.io.Serializable;

/**
 * @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 = super.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;
    }

}


<|start_filename|>api-implementation/src/main/java/org/apache/clerezza/implementation/graph/ReadOnlyException.java<|end_filename|>
/*
 * 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.clerezza.implementation.graph;

import java.security.AccessControlException;

/**
 * is thrown on an attempt to add or remove triples to a
 * read-only mutable ImmutableGraph
 *
 * @author tsuy
 */
public class ReadOnlyException extends AccessControlException {

    private String action;

    /**
     * creates an exception indicating that the mutable ImmutableGraph is read-only
     *
     * @param action
     */
    public ReadOnlyException(String action) {
        super("read only mutable ImmutableGraph, not allowed to " + action);
        this.action = action;
    }

    /**
     * @return the name of the action
     */
    public String getAction() {
        return action;
    }
}


<|start_filename|>api-implementation/src/main/java/org/apache/clerezza/implementation/debug/WriteLockDebug.java<|end_filename|>
/*
 * 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.clerezza.implementation.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;
    }


}


<|start_filename|>api.utils/src/main/java/org/apache/clerezza/utils/GraphUtils.java<|end_filename|>
/*
 * 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.clerezza.utils;

import org.apache.clerezza.*;
import org.apache.clerezza.implementation.in_memory.SimpleGraph;

import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;

/**
 * Utility methods to manipulate <code>Graph</code>s
 *
 * @author reto
 */
public class GraphUtils {

    /**
     * Removes a subGraph from an Graph. The subGraph must match a subgraph of
     * Graph so that for every node in <code>subGraph</code>
     * each triple it appears in is also present in <code>mGraph</code>. Two
     * bnodes are considered equals if their contexts (as returned by
     * <code>GraphNode.getNodeContext</code> are equals.
     *
     * @param mGraph
     * @param subGraph
     * @throws org.apache.clerezza.rdf.utils.GraphUtils.NoSuchSubGraphException
     */
    public static void removeSubGraph(Graph mGraph, Graph subGraph)
            throws NoSuchSubGraphException {
        //point to triples of mGraph that are to be removed (if something is removed)
        final Set<Triple> removingTriples = new HashSet<Triple>();
        //we first check only the grounded triples and put the non-grounded in here:
        final Graph unGroundedTriples = new SimpleGraph();
        for (Triple triple : subGraph) {
            if (isGrounded(triple)) {
                if (!mGraph.contains(triple)) {
                    throw new NoSuchSubGraphException();
                }
                removingTriples.add(triple);
            } else {
                unGroundedTriples.add(triple);
            }
        }

        //we first remove the context of bnodes we find in object position
        OBJ_BNODE_LOOP:
        while (true) {
            final Triple triple = getTripleWithBlankNodeObject(unGroundedTriples);
            if (triple == null) {
                break;
            }
            final GraphNode objectGN = new GraphNode(triple.getObject(), unGroundedTriples);
            BlankNodeOrIRI subject = triple.getSubject();
            ImmutableGraph context = objectGN.getNodeContext();
            Iterator<Triple> potentialIter = mGraph.filter(subject, triple.getPredicate(), null);
            while (potentialIter.hasNext()) {
                try {
                    final Triple potentialTriple = potentialIter.next();
                    BlankNode potentialMatch = (BlankNode) potentialTriple.getObject();
                    final ImmutableGraph potentialContext = new GraphNode(potentialMatch, mGraph).getNodeContext();
                    if (potentialContext.equals(context)) {
                        removingTriples.addAll(potentialContext);
                        unGroundedTriples.removeAll(context);
                        continue OBJ_BNODE_LOOP;
                    }
                } catch (ClassCastException e) {
                    continue;
                }
            }
            throw new NoSuchSubGraphException();
        }
        SUBJ_BNODE_LOOP:
        while (true) {
            final Triple triple = getTripleWithBlankNodeSubject(unGroundedTriples);
            if (triple == null) {
                break;
            }
            final GraphNode subjectGN = new GraphNode(triple.getSubject(), unGroundedTriples);
            RDFTerm object = triple.getObject();
            if (object instanceof BlankNode) {
                object = null;
            }
            ImmutableGraph context = subjectGN.getNodeContext();
            Iterator<Triple> potentialIter = mGraph.filter(null, triple.getPredicate(), object);
            while (potentialIter.hasNext()) {
                try {
                    final Triple potentialTriple = potentialIter.next();
                    BlankNode potentialMatch = (BlankNode) potentialTriple.getSubject();
                    final ImmutableGraph potentialContext = new GraphNode(potentialMatch, mGraph).getNodeContext();
                    if (potentialContext.equals(context)) {
                        removingTriples.addAll(potentialContext);
                        unGroundedTriples.removeAll(context);
                        continue SUBJ_BNODE_LOOP;
                    }
                } catch (ClassCastException e) {
                    continue;
                }
            }
            throw new NoSuchSubGraphException();
        }
        mGraph.removeAll(removingTriples);
    }

    private static boolean isGrounded(Triple triple) {
        if (triple.getSubject() instanceof BlankNode) {
            return false;
        }
        if (triple.getObject() instanceof BlankNode) {
            return false;
        }
        return true;
    }

    /**
     * retrun triples with a bnode only at object position
     *
     * @param triples
     * @return
     */
    private static Triple getTripleWithBlankNodeObject(Graph triples) {
        for (Triple triple : triples) {
            if (triple.getSubject() instanceof BlankNode) {
                continue;
            }
            if (triple.getObject() instanceof BlankNode) {
                return triple;
            }
        }
        return null;
    }

    private static Triple getTripleWithBlankNodeSubject(Graph triples) {
        for (Triple triple : triples) {
            if (triple.getSubject() instanceof BlankNode) {
                return triple;
            }
        }
        return null;
    }

    public static class NoSuchSubGraphException extends Exception {
    }

}


<|start_filename|>api-implementation/src/main/java/org/apache/clerezza/implementation/in_memory/SimpleGraph.java<|end_filename|>
/*
 * 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.clerezza.implementation.in_memory;

import org.apache.clerezza.*;
import org.apache.clerezza.implementation.graph.AbstractGraph;

import java.lang.ref.SoftReference;
import java.util.*;

/**
 * For now this is a minimalistic implementation, without any indexes or other
 * optimizations.
 *
 * @author reto
 */
public class SimpleGraph extends AbstractGraph {

    final Set<Triple> triples;

    private boolean checkConcurrency = false;

    class SimpleIterator implements Iterator<Triple> {

        private Iterator<Triple> listIter;
        private boolean isValid = true;

        public SimpleIterator(Iterator<Triple> listIter) {
            this.listIter = listIter;
        }

        private Triple currentNext;

        @Override
        public boolean hasNext() {
            checkValidity();
            return listIter.hasNext();
        }

        @Override
        public Triple next() {
            checkValidity();
            currentNext = listIter.next();
            return currentNext;
        }

        @Override
        public void remove() {
            checkValidity();
            listIter.remove();
            triples.remove(currentNext);
            invalidateIterators(this);
        }

        private void checkValidity() throws ConcurrentModificationException {
            if (checkConcurrency && !isValid) {
                throw new ConcurrentModificationException();
            }
        }

        private void invalidate() {
            isValid = false;
        }
    }

    private final Set<SoftReference<SimpleIterator>> iterators =
            Collections.synchronizedSet(new HashSet<SoftReference<SimpleIterator>>());

    /**
     * Creates an empty SimpleGraph
     */
    public SimpleGraph() {
        triples = Collections.synchronizedSet(new HashSet<Triple>());
    }

    /**
     * Creates a SimpleGraph using the passed iterator, the iterator
     * is consumed before the constructor returns
     *
     * @param iterator
     */
    public SimpleGraph(Iterator<Triple> iterator) {
        triples = new HashSet<Triple>();
        while (iterator.hasNext()) {
            Triple triple = iterator.next();
            triples.add(triple);
        }
    }

    /**
     * Creates a SimpleGraph for the specified set of triples,
     * subsequent modification of baseSet do affect the created instance.
     *
     * @param baseSet
     */
    public SimpleGraph(Set<Triple> baseSet) {
        this.triples = baseSet;
    }

    /**
     * Creates a SimpleGraph for the specified collection of triples,
     * subsequent modification of baseSet do not affect the created instance.
     *
     * @param baseSet
     */
    public SimpleGraph(Collection<Triple> baseCollection) {
        this.triples = new HashSet<Triple>(baseCollection);
    }

    @Override
    public int performSize() {
        return triples.size();
    }

    @Override
    public Iterator<Triple> performFilter(final BlankNodeOrIRI subject, final IRI predicate, final RDFTerm object) {
        final List<Triple> tripleList = new ArrayList<Triple>();
        synchronized (triples) {
            Iterator<Triple> baseIter = triples.iterator();
            while (baseIter.hasNext()) {
                Triple triple = baseIter.next();
                if ((subject != null)
                        && (!triple.getSubject().equals(subject))) {
                    continue;
                }
                if ((predicate != null)
                        && (!triple.getPredicate().equals(predicate))) {
                    continue;
                }
                if ((object != null)
                        && (!triple.getObject().equals(object))) {
                    continue;
                }
                tripleList.add(triple);
            }

            final Iterator<Triple> listIter = tripleList.iterator();
            SimpleIterator resultIter = new SimpleIterator(listIter);
            if (checkConcurrency) {
                iterators.add(new SoftReference<SimpleIterator>(resultIter));
            }
            return resultIter;
        }
    }


    @Override
    public boolean performAdd(Triple e) {
        boolean modified = triples.add(e);
        if (modified) {
            invalidateIterators(null);
        }
        return modified;
    }

    private void invalidateIterators(SimpleIterator caller) {
        if (!checkConcurrency) {
            return;
        }
        Set<SoftReference> oldReferences = new HashSet<SoftReference>();
        synchronized (iterators) {
            for (SoftReference<SimpleGraph.SimpleIterator> softReference : iterators) {
                SimpleIterator simpleIterator = softReference.get();
                if (simpleIterator == null) {
                    oldReferences.add(softReference);
                    continue;
                }
                if (simpleIterator != caller) {
                    simpleIterator.invalidate();
                }
            }
        }
        iterators.removeAll(oldReferences);
    }

    /**
     * Specifies whether or not to throw <code>ConcurrentModificationException</code>s,
     * if this simple triple collection is modified concurrently. Concurrency
     * check is set to false by default.
     *
     * @param bool Specifies whether or not to check concurrent modifications.
     */
    public void setCheckConcurrency(boolean bool) {
        checkConcurrency = bool;
    }


    @Override
    public ImmutableGraph getImmutableGraph() {
        return new SimpleImmutableGraph(this);
    }
}


<|start_filename|>api-implementation/src/main/java/org/apache/clerezza/implementation/literal/SimpleLiteralFactory.java<|end_filename|>
/*
 * 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.clerezza.implementation.literal;

import org.apache.clerezza.IRI;
import org.apache.clerezza.Literal;
import org.apache.clerezza.implementation.util.Base64;
import org.apache.clerezza.implementation.util.W3CDateFormat;

import java.math.BigInteger;
import java.text.DateFormat;
import java.text.ParseException;
import java.util.*;

/**
 * An implementation of literal factory currently supporting only
 * byte[]/base64Binary and Java.util.Date/date
 *
 * @author reto
 */

public class SimpleLiteralFactory extends LiteralFactory {

    private static final String XSD = "http://www.w3.org/2001/XMLSchema#";
    final private static IRI xsdInteger = xsd("integer");
    final private static IRI xsdInt = xsd("int");
    final private static IRI xsdShort = xsd("short");
    final private static IRI xsdByte = xsd("byte");
    final private static IRI xsdLong = xsd("long");


    final private static Set<IRI> decimalTypes = new HashSet<IRI>();

    final private static Map<Class<?>, TypeConverter<?>> typeConverterMap = new HashMap<Class<?>, TypeConverter<?>>();
    final static Class<? extends byte[]> byteArrayType;

    static {
        Collections.addAll(decimalTypes, xsdInteger, xsdInt, xsdByte, xsdShort, xsdLong);

        byte[] byteArray = new byte[0];
        byteArrayType = byteArray.getClass();
        typeConverterMap.put(byteArrayType, new ByteArrayConverter());
        typeConverterMap.put(Date.class, new DateConverter());
        typeConverterMap.put(Boolean.class, new BooleanConverter());
        typeConverterMap.put(String.class, new StringConverter());
        typeConverterMap.put(Integer.class, new IntegerConverter());
        typeConverterMap.put(BigInteger.class, new BigIntegerConverter());
        typeConverterMap.put(Long.class, new LongConverter());
        typeConverterMap.put(Double.class, new DoubleConverter());
        typeConverterMap.put(Float.class, new FloatConverter());
        typeConverterMap.put(IRI.class, new UriRefConverter());
    }

    final private static IRI xsdDouble = xsd("double");
    final private static IRI xsdFloat = xsd("float");
    final private static IRI xsdAnyURI = xsd("anyURI");

    final private static IRI xsd(String name) {
        return new IRI(XSD + name);
    }

    private static interface TypeConverter<T> {
        Literal createLiteral(T value);

        T createObject(Literal literal);
    }

    private static class ByteArrayConverter implements TypeConverter<byte[]> {

        private static final IRI base64Uri = xsd("base64Binary");

        @Override
        public Literal createLiteral(byte[] value) {
            return new TypedLiteralImpl(Base64.encode((byte[]) value), base64Uri);
        }

        @Override
        public byte[] createObject(Literal literal) {
            if (!literal.getDataType().equals(base64Uri)) {
                throw new InvalidLiteralTypeException(byteArrayType, literal.getDataType());
            }
            return (byte[]) Base64.decode(literal.getLexicalForm());
        }


    }

    private static class DateConverter implements TypeConverter<Date> {

        private static final IRI dateTimeUri = xsd("dateTime");
        private static final DateFormat DATE_FORMAT = new W3CDateFormat();

        @Override
        public Literal createLiteral(Date value) {
            return new TypedLiteralImpl(DATE_FORMAT.format(value), dateTimeUri);
        }

        @Override
        public Date createObject(Literal literal) {
            if (!literal.getDataType().equals(dateTimeUri)) {
                throw new InvalidLiteralTypeException(Date.class, literal.getDataType());
            }
            try {
                return DATE_FORMAT.parse(literal.getLexicalForm());
            } catch (ParseException ex) {
                throw new RuntimeException("Exception parsing literal as date", ex);
            }
        }


    }

    private static class BooleanConverter implements TypeConverter<Boolean> {

        private static final IRI booleanUri = xsd("boolean");
        public static final TypedLiteralImpl TRUE = new TypedLiteralImpl("true", booleanUri);
        public static final TypedLiteralImpl FALSE = new TypedLiteralImpl("false", booleanUri);

        @Override
        public Literal createLiteral(Boolean value) {
            if (value) return TRUE;
            else return FALSE;
        }

        @Override
        public Boolean createObject(Literal literal) {
            if (literal == TRUE) return true;
            else if (literal == FALSE) return false;
            else if (!literal.getDataType().equals(booleanUri)) {
                throw new InvalidLiteralTypeException(Boolean.class, literal.getDataType());
            }
            return Boolean.valueOf(literal.getLexicalForm());
        }
    }

    private static class StringConverter implements TypeConverter<String> {

        private static final IRI stringUri = xsd("string");

        @Override
        public Literal createLiteral(String value) {
            return new TypedLiteralImpl(value, stringUri);
        }

        @Override
        public String createObject(Literal literal) {
            if (!literal.getDataType().equals(stringUri)) {
                throw new InvalidLiteralTypeException(String.class, literal.getDataType());
            }
            return literal.getLexicalForm();
        }
    }

    private static class IntegerConverter implements TypeConverter<Integer> {


        @Override
        public Literal createLiteral(Integer value) {
            return new TypedLiteralImpl(value.toString(), xsdInt);
        }

        @Override
        public Integer createObject(Literal literal) {
            if (!decimalTypes.contains(literal.getDataType())) {
                throw new InvalidLiteralTypeException(Integer.class, literal.getDataType());
            }
            return new Integer(literal.getLexicalForm());
        }
    }

    private static class LongConverter implements TypeConverter<Long> {


        @Override
        public Literal createLiteral(Long value) {
            return new TypedLiteralImpl(value.toString(), xsdLong);
        }

        @Override
        public Long createObject(Literal literal) {
            if (!decimalTypes.contains(literal.getDataType())) {
                throw new InvalidLiteralTypeException(Long.class, literal.getDataType());
            }
            return new Long(literal.getLexicalForm());
        }
    }


    private static class FloatConverter implements TypeConverter<Float> {

        @Override
        public Literal createLiteral(Float value) {
            return new TypedLiteralImpl(value.toString(), xsdFloat);
        }

        @Override
        public Float createObject(Literal literal) {
            if (!literal.getDataType().equals(xsdFloat)) {
                throw new InvalidLiteralTypeException(Float.class, literal.getDataType());
            }
            return Float.valueOf(literal.getLexicalForm());
        }
    }

    private static class DoubleConverter implements TypeConverter<Double> {


        @Override
        public Literal createLiteral(Double value) {
            return new TypedLiteralImpl(value.toString(), xsdDouble);
        }

        @Override
        public Double createObject(Literal literal) {
            if (!literal.getDataType().equals(xsdDouble)) {
                throw new InvalidLiteralTypeException(Double.class, literal.getDataType());
            }
            return new Double(literal.getLexicalForm());
        }
    }

    private static class BigIntegerConverter implements TypeConverter<BigInteger> {


        @Override
        public Literal createLiteral(BigInteger value) {
            return new TypedLiteralImpl(value.toString(), xsdInteger);
        }

        @Override
        public BigInteger createObject(Literal literal) {
            if (!literal.getDataType().equals(xsdInteger)) {
                throw new InvalidLiteralTypeException(Double.class, literal.getDataType());
            }
            return new BigInteger(literal.getLexicalForm());
        }
    }

    private static class UriRefConverter implements TypeConverter<IRI> {


        @Override
        public Literal createLiteral(IRI value) {
            return new TypedLiteralImpl(value.getUnicodeString(), xsdAnyURI);
        }

        @Override
        public IRI createObject(Literal literal) {
            if (!literal.getDataType().equals(xsdAnyURI)) {
                throw new InvalidLiteralTypeException(IRI.class, literal.getDataType());
            }
            return new IRI(literal.getLexicalForm());
        }
    }


    @SuppressWarnings("unchecked")
    @Override
    public Literal createTypedLiteral(Object value) throws NoConvertorException {
        TypeConverter converter = getConverterFor(value.getClass());
        return converter.createLiteral(value);
    }


    @Override
    public <T> T createObject(Class<T> type, Literal literal)
            throws NoConvertorException, InvalidLiteralTypeException {
        final TypeConverter<T> converter = getConverterFor(type);
        return converter.createObject(literal);

    }

    @SuppressWarnings("unchecked")
    private <T> TypeConverter<T> getConverterFor(Class<T> type) throws NoConvertorException {
        TypeConverter<T> convertor = (TypeConverter<T>) typeConverterMap.get(type);
        if (convertor != null) {
            return convertor;
        }
        for (Map.Entry<Class<?>, TypeConverter<?>> converterEntry : typeConverterMap.entrySet()) {
            if (type.isAssignableFrom(converterEntry.getKey())) {
                return (TypeConverter<T>) converterEntry.getValue();
            }
        }
        throw new NoConvertorException(type);
    }
}


<|start_filename|>api.utils/src/test/java/org/apache/clerezza/utils/RdfListTest.java<|end_filename|>
/*
 * 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.clerezza.utils;

import junit.framework.Assert;
import org.apache.clerezza.RDFTerm;
import org.apache.clerezza.BlankNode;
import org.apache.clerezza.Graph;
import org.apache.clerezza.IRI;
import org.apache.clerezza.implementation.in_memory.SimpleGraph;
import org.apache.clerezza.implementation.literal.PlainLiteralImpl;
import org.junit.Test;

import java.util.List;
import java.util.Set;

import static org.junit.Assert.assertEquals;

/**
 * @author rbn
 */
public class RdfListTest {

    @Test
    public void listCreationAndAccess() {
        Graph tc = new SimpleGraph();
        List<RDFTerm> list = new RdfList(new IRI("http://example.org/mytest"), tc);
        assertEquals(0, list.size());
        list.add(new PlainLiteralImpl("hello"));
        list.add(new PlainLiteralImpl("world"));
        assertEquals(new PlainLiteralImpl("hello"), list.get(0));
        assertEquals(new PlainLiteralImpl("world"), list.get(1));
        assertEquals(2, list.size());
        list.add(new PlainLiteralImpl("welcome"));
        assertEquals(3, list.size());
        assertEquals(new PlainLiteralImpl("welcome"), list.get(2));
        list.add(1, new PlainLiteralImpl("interesting"));
        assertEquals(4, list.size());
        assertEquals(new PlainLiteralImpl("interesting"), list.get(1));
        assertEquals(new PlainLiteralImpl("world"), list.get(2));
        assertEquals(new PlainLiteralImpl("welcome"), list.get(3));
        list.add(0, new PlainLiteralImpl("start"));
        assertEquals(5, list.size());
        assertEquals(new PlainLiteralImpl("hello"), list.get(1));
        assertEquals(new PlainLiteralImpl("interesting"), list.get(2));
        List<RDFTerm> list2 = new RdfList(new IRI("http://example.org/mytest"), tc);
        assertEquals(5, list2.size());
        assertEquals(new PlainLiteralImpl("hello"), list2.get(1));
        assertEquals(new PlainLiteralImpl("interesting"), list2.get(2));
        list2.remove(2);
        assertEquals(4, list2.size());
        assertEquals(new PlainLiteralImpl("hello"), list2.get(1));
        assertEquals(new PlainLiteralImpl("world"), list2.get(2));
        while (list2.size() > 0) {
            list2.remove(0);
        }
        assertEquals(1, tc.size()); //list = rdf:nil statement
        list2.add(0, new PlainLiteralImpl("restart"));
        list2.add(1, new PlainLiteralImpl("over"));
        assertEquals(2, list2.size());
        list2.add(new PlainLiteralImpl("2"));
        list2.add(new PlainLiteralImpl("3"));
        assertEquals(4, list2.size());
        list2.add(new PlainLiteralImpl("4"));
        list2.add(new PlainLiteralImpl("5"));
        assertEquals(new PlainLiteralImpl("3"), list2.get(3));
    }

    @Test
    public void listCreationAndAccess2() {
        Graph tc = new SimpleGraph();
        List<RDFTerm> list = new RdfList(new IRI("http://example.org/mytest"), tc);
        assertEquals(0, list.size());
        list.add(0, new PlainLiteralImpl("world"));
        list = new RdfList(new IRI("http://example.org/mytest"), tc);
        list.add(0, new PlainLiteralImpl("beautifuly"));
        list = new RdfList(new IRI("http://example.org/mytest"), tc);
        list.add(0, new PlainLiteralImpl("hello"));
        assertEquals(new PlainLiteralImpl("hello"), list.get(0));
        assertEquals(new PlainLiteralImpl("beautifuly"), list.get(1));
        assertEquals(new PlainLiteralImpl("world"), list.get(2));
    }

    @Test
    public void listCreationAndAccess3() {
        Graph tc = new SimpleGraph();
        List<RDFTerm> list = new RdfList(new IRI("http://example.org/mytest"), tc);
        assertEquals(0, list.size());
        BlankNode node0 = new BlankNode() {
        };
        BlankNode node1 = new BlankNode() {
        };
        BlankNode node2 = new BlankNode() {
        };
        list.add(0, node2);
        list.add(0, node1);
        list.add(0, node0);
        assertEquals(node0, list.get(0));
        assertEquals(node1, list.get(1));
        assertEquals(node2, list.get(2));
    }

    @Test
    public void secondButLastElementAccessTest() {
        Graph tc = new SimpleGraph();
        List<RDFTerm> list = new RdfList(new IRI("http://example.org/mytest2"), tc);
        list.add(new PlainLiteralImpl("hello"));
        list.add(new PlainLiteralImpl("world"));
        list.remove(1);
        assertEquals(1, list.size());
    }

    @Test
    public void cleanGraphAfterRemoval() {
        Graph tc = new SimpleGraph();
        List<RDFTerm> list = new RdfList(new IRI("http://example.org/mytest"), tc);
        list.add(new PlainLiteralImpl("hello"));
        list.add(new PlainLiteralImpl("world"));
        list.remove(1);
        Assert.assertEquals(2, tc.size());

    }

    @Test
    public void findContainingListNodesAndfindContainingListsTest() {
        Graph tc = new SimpleGraph();
        GraphNode listA = new GraphNode(new IRI("http:///listA"), tc);
        GraphNode listB = new GraphNode(new IRI("http:///listB"), tc);
        BlankNode element1 = new BlankNode();
        BlankNode element2 = new BlankNode();
        BlankNode element3 = new BlankNode();
        BlankNode element4 = new BlankNode();
        BlankNode element5 = new BlankNode();

        RdfList rdfListA = new RdfList(listA);
        rdfListA.add(element1);
        rdfListA.add(element2);
        rdfListA.add(element3);
        rdfListA.add(element4);

        RdfList rdfListB = new RdfList(listB);
        rdfListB.add(element2);
        rdfListB.add(element4);
        rdfListB.add(element5);

        Set<GraphNode> containingListNodes = RdfList.findContainingListNodes(
                new GraphNode(element3, tc));
        Assert.assertEquals(1, containingListNodes.size());
        Assert.assertTrue(containingListNodes.contains(listA));

        Set<RdfList> containingLists = RdfList.findContainingLists(
                new GraphNode(element3, tc));
        Assert.assertEquals(1, containingLists.size());
        Assert.assertTrue(containingLists.contains(rdfListA));

        containingListNodes = RdfList.findContainingListNodes(
                new GraphNode(element4, tc));
        Assert.assertEquals(2, containingListNodes.size());
        Assert.assertTrue(containingListNodes.contains(listA));
        Assert.assertTrue(containingListNodes.contains(listB));

        containingLists = RdfList.findContainingLists(
                new GraphNode(element4, tc));
        Assert.assertEquals(2, containingLists.size());
        Assert.assertTrue(containingLists.contains(rdfListA));
        Assert.assertTrue(containingLists.contains(rdfListB));
    }
}

<|start_filename|>api.utils/src/main/java/org/apache/clerezza/utils/UnionGraph.java<|end_filename|>
/*
 * 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.clerezza.utils;

import org.apache.clerezza.*;
import org.apache.clerezza.implementation.graph.AbstractGraph;

import java.util.*;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReadWriteLock;

/**
 * This class represents the union of multiple triple collections. A UnionGraph
 * appears like a merge of the different graphs (see.
 * http://www.w3.org/TR/rdf-mt/#graphdefs).
 *
 * @author hasan
 */
public class UnionGraph extends AbstractGraph {

    protected Graph[] baseTripleCollections;
    private Lock readLock;
    private Lock writeLock;

    /**
     * Constructs a UnionGraph over the specified baseTripleCollections. Write
     * and delete operations are forwarded to the first baseTripleCollections.
     *
     * @param baseTripleCollections the baseTripleCollections
     */
    public UnionGraph(Graph... baseTripleCollections) {
        this.baseTripleCollections = baseTripleCollections;
        readLock = getPartialReadLock(0);
        writeLock = createWriteLock();
    }

    @Override
    public int performSize() {
        int size = 0;
        for (Graph graph : baseTripleCollections) {
            size += graph.size();
        }
        return size;
    }

    @Override
    public Iterator<Triple> performFilter(final BlankNodeOrIRI subject,
                                          final IRI predicate, final RDFTerm object) {
        if (baseTripleCollections.length == 0) {
            return new HashSet<Triple>(0).iterator();
        }
        return new Iterator<Triple>() {

            int currentBaseTC = 0;
            Iterator<Triple> currentBaseIter = baseTripleCollections[0].filter(
                    subject, predicate, object);
            private Triple lastReturned;

            @Override
            public boolean hasNext() {
                if (currentBaseIter.hasNext()) {
                    return true;
                }
                if (currentBaseTC == baseTripleCollections.length - 1) {
                    return false;
                }
                currentBaseTC++;
                currentBaseIter = baseTripleCollections[currentBaseTC].filter(
                        subject, predicate, object);
                return hasNext();
            }

            @Override
            public Triple next() {
                lastReturned = hasNext() ? currentBaseIter.next() : null;
                return lastReturned;
            }

            @Override
            public void remove() {
                if (lastReturned == null) {
                    throw new IllegalStateException();
                }
                if (currentBaseTC == 0) {
                    currentBaseIter.remove();
                }
                lastReturned = null;
            }
        };
    }

    @Override
    public boolean add(Triple e) {
        if (baseTripleCollections.length == 0) {
            throw new RuntimeException("no base graph for adding triples");
        }
        return baseTripleCollections[0].add(e);
    }

    @Override
    public boolean remove(Object e) {
        if (baseTripleCollections.length == 0) {
            throw new RuntimeException("no base graph for removing triples");
        }
        return baseTripleCollections[0].remove(e);
    }

    @Override
    public boolean equals(Object obj) {
        if (!(obj.getClass().equals(getClass()))) {
            return false;
        }
        UnionGraph other = (UnionGraph) obj;
        Set<Graph> otherGraphs
                = new HashSet(Arrays.asList(other.baseTripleCollections));
        Set<Graph> thisGraphs
                = new HashSet(Arrays.asList(baseTripleCollections));
        return thisGraphs.equals(otherGraphs)
                && baseTripleCollections[0].equals(other.baseTripleCollections[0]);
    }

    @Override
    public int hashCode() {
        int hash = 0;
        for (Graph graph : baseTripleCollections) {
            hash += graph.hashCode();
        }
        hash *= baseTripleCollections[0].hashCode();
        return hash;
    }

    @Override
    public ReadWriteLock getLock() {
        return readWriteLock;
    }

    private ReadWriteLock readWriteLock = new ReadWriteLock() {

        @Override
        public Lock readLock() {
            return readLock;
        }

        @Override
        public Lock writeLock() {
            return writeLock;
        }
    };

    private Lock getPartialReadLock(int startPos) {
        ArrayList<Lock> resultList = new ArrayList<Lock>();
        for (int i = startPos; i < baseTripleCollections.length; i++) {
            Graph graph = baseTripleCollections[i];

            final Lock lock = graph.getLock().readLock();
            resultList.add(lock);
        }
        return new UnionLock(resultList.toArray(new Lock[resultList.size()]));
    }

    private Lock createWriteLock() {
        Lock partialReadLock = getPartialReadLock(1);

        Lock baseWriteLock
                = (baseTripleCollections[0]).getLock().writeLock();
        return new UnionLock(baseWriteLock, partialReadLock);

    }

    private static class UnionLock implements Lock {

        Lock[] locks;

        public UnionLock(Lock... locks) {
            this.locks = locks;
        }

        @Override
        public void lock() {
            boolean isLocked = false;
            while (!isLocked) {
                try {
                    isLocked = tryLock(10000, TimeUnit.NANOSECONDS);
                } catch (InterruptedException ex) {

                }
            }
        }

        @Override
        public void lockInterruptibly() throws InterruptedException {
            Set<Lock> aquiredLocks = new HashSet<Lock>();
            try {
                for (Lock lock : locks) {
                    lock.lockInterruptibly();
                    aquiredLocks.add(lock);
                }
            } catch (InterruptedException e) {
                for (Lock lock : aquiredLocks) {
                    lock.unlock();
                }
                throw e;
            }
        }

        @Override
        public boolean tryLock() {
            Set<Lock> aquiredLocks = new HashSet<Lock>();
            for (Lock lock : locks) {
                if (!lock.tryLock()) {
                    for (Lock aquiredLock : aquiredLocks) {
                        aquiredLock.unlock();
                    }
                    return false;
                }
                aquiredLocks.add(lock);
            }
            return true;
        }

        @Override
        public boolean tryLock(long time, TimeUnit unit) throws InterruptedException {
            Set<Lock> aquiredLocks = new HashSet<Lock>();
            long timeInNanos = unit.convert(time, TimeUnit.NANOSECONDS);
            long startTime = System.nanoTime();
            try {
                for (Lock lock : locks) {
                    if (!lock.tryLock((timeInNanos + startTime) - System.nanoTime(),
                            TimeUnit.NANOSECONDS)) {
                        for (Lock aquiredLock : aquiredLocks) {
                            aquiredLock.unlock();
                        }
                        return false;
                    }
                    aquiredLocks.add(lock);
                }
            } catch (InterruptedException e) {
                for (Lock lock : aquiredLocks) {
                    lock.unlock();
                }
                throw e;
            }
            return true;
        }

        @Override
        public void unlock() {
            for (Lock lock : locks) {
                lock.unlock();
            }
        }

        @Override
        public Condition newCondition() {
            throw new UnsupportedOperationException("Conditions not supported.");
        }
    }
}


<|start_filename|>api-implementation/src/main/java/org/apache/clerezza/implementation/literal/AbstractLiteral.java<|end_filename|>
/*
 * Copyright 2015 The Apache Software Foundation.
 *
 * 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.clerezza.implementation.literal;

import org.apache.clerezza.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;
        }
    }

}


<|start_filename|>api.utils/src/main/java/org/apache/clerezza/utils/smushing/IfpSmusher.java<|end_filename|>
/*
 * 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.clerezza.utils.smushing;

import org.apache.clerezza.*;
import org.apache.clerezza.ontologies.OWL;
import org.apache.clerezza.ontologies.RDF;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.*;

/**
 * A utility to equate duplicate nodes in an Mgarph, currently only nodes with
 * a shared ifp are equated.
 *
 * @author reto
 */
public class IfpSmusher extends BaseSmusher {

    static final Logger log = LoggerFactory.getLogger(IfpSmusher.class);

    /**
     * smush mGaph given the ontological facts. Currently it does only
     * one step ifp smushin, i.e. only ifps are taken in account and only
     * nodes that have the same node as ifp object in the orignal graph are
     * equates. (calling the method a second time might lead to additional
     * smushings.)
     *
     * @param mGraph
     * @param tBox
     */
    public void smush(Graph mGraph, Graph tBox) {
        final Set<IRI> ifps = getIfps(tBox);
        final Map<PredicateObject, Set<BlankNodeOrIRI>> ifp2nodesMap = new HashMap<PredicateObject, Set<BlankNodeOrIRI>>();
        for (Iterator<Triple> it = mGraph.iterator(); it.hasNext(); ) {
            final Triple triple = it.next();
            final IRI predicate = triple.getPredicate();
            if (!ifps.contains(predicate)) {
                continue;
            }
            final PredicateObject po = new PredicateObject(predicate, triple.getObject());
            Set<BlankNodeOrIRI> equivalentNodes = ifp2nodesMap.get(po);
            if (equivalentNodes == null) {
                equivalentNodes = new HashSet<BlankNodeOrIRI>();
                ifp2nodesMap.put(po, equivalentNodes);
            }
            equivalentNodes.add(triple.getSubject());
        }
        Set<Set<BlankNodeOrIRI>> unitedEquivalenceSets = uniteSetsWithCommonElement(ifp2nodesMap.values());
        smush(mGraph, unitedEquivalenceSets, true);
    }

    private Set<IRI> getIfps(Graph tBox) {
        final Iterator<Triple> ifpDefinitions = tBox.filter(null, RDF.type,
                OWL.InverseFunctionalProperty);
        final Set<IRI> ifps = new HashSet<IRI>();
        while (ifpDefinitions.hasNext()) {
            final Triple triple = ifpDefinitions.next();
            ifps.add((IRI) triple.getSubject());
        }
        return ifps;
    }

    private <T> Set<Set<T>> uniteSetsWithCommonElement(
            Collection<Set<T>> originalSets) {
        Set<Set<T>> result = new HashSet<Set<T>>();
        Iterator<Set<T>> iter = originalSets.iterator();
        while (iter.hasNext()) {
            Set<T> originalSet = iter.next();
            //TODO this could be done more efficiently with a map
            Set<T> matchingSet = getMatchinSet(originalSet, result);
            if (matchingSet != null) {
                matchingSet.addAll(originalSet);
            } else {
                result.add(new HashSet<T>(originalSet));
            }
        }
        if (result.size() < originalSets.size()) {
            return uniteSetsWithCommonElement(result);
        } else {
            return result;
        }
    }

    private <T> Set<T> getMatchinSet(Set<T> set, Set<Set<T>> setOfSet) {
        for (Set<T> current : setOfSet) {
            if (shareElements(set, current)) {
                return current;
            }
        }
        return null;
    }

    private <T> boolean shareElements(Set<T> set1, Set<T> set2) {
        for (T elem : set2) {
            if (set1.contains(elem)) {
                return true;
            }
        }
        return false;
    }

    class PredicateObject {

        final IRI predicate;
        final RDFTerm object;

        public PredicateObject(IRI predicate, RDFTerm object) {
            this.predicate = predicate;
            this.object = object;
        }

        @Override
        public boolean equals(Object obj) {
            if (obj == null) {
                return false;
            }
            if (getClass() != obj.getClass()) {
                return false;
            }
            final PredicateObject other = (PredicateObject) obj;
            if (this.predicate != other.predicate && !this.predicate.equals(other.predicate)) {
                return false;
            }
            if (this.object != other.object && !this.object.equals(other.object)) {
                return false;
            }
            return true;
        }

        @Override
        public int hashCode() {
            int hash = 3;
            hash = 29 * hash + this.predicate.hashCode();
            hash = 13 * hash + this.object.hashCode();
            return hash;
        }

        @Override
        public String toString() {
            return "(" + predicate + ", " + object + ")";
        }
    }
}


<|start_filename|>representation/src/main/java/org/apache/clerezza/representation/Serializer.java<|end_filename|>
/*
 * 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.clerezza.representation;

import org.apache.clerezza.Graph;
import org.osgi.service.cm.ConfigurationAdmin;
import org.osgi.service.component.ComponentContext;
import org.osgi.service.component.annotations.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.IOException;
import java.io.OutputStream;
import java.util.*;

/**
 * This singleton class provides a method <code>serialize</code> to transform a
 * {@link ImmutableGraph} into serialized RDF forms.
 * 
 * Functionality is delegated to registered {@link SerializingProvider}s. Such
 * <code>SerializingProvider</code>s can be registered and unregistered, later
 * registered <code>SerializingProvider</code>s shadow previously registered
 * providers for the same format.
 * 
 * Note on synchronization: <code>SerializingProvider</code>s must be able to
 * handle concurrent requests.
 * 
 * @author mir
 * 
 */
@Component(service = Serializer.class)
public class Serializer {
    
    private ConfigurationAdmin configurationAdmin;

    /**
     * The list of providers in the order of registration
     */
    private List<SerializingProvider> providerList = new ArrayList<SerializingProvider>();

    /**
     * A map to quickly locate a provider
     */
    private volatile Map<String, SerializingProvider> providerMap = new HashMap<String, SerializingProvider>();

    /**
     * The singleton instance
     */
    private volatile static Serializer instance;
    
    private static final Logger log = LoggerFactory.getLogger(Serializer.class);
    
    private boolean active;

    /**
     * the constructor sets the singleton instance to allow instantiation
     * by OSGi-DS. This constructor should not be called except by OSGi-DS,
     * otherwise the static <code>getInstance</code> method should be used.
     */
    public Serializer() {
        Serializer.instance = this;
    }

    /**
     * A constructor for tests, which doesn't set the singleton instance
     * 
     * @param dummy
     *            an ignored argument to distinguish this from the other
     *            constructor
     */
    Serializer(Object dummy) {
        active = true;
    }

    /**
     * This returns the singleton instance, if an instance has been previously
     * created (e.g. by OSGi declarative services) this instance is returned,
     * otherwise a new instance is created and providers are injected using the
     * service provider interface (META-INF/services/)
     * 
     * @return the singleton Serializer instance
     */
    public static Serializer getInstance() {
        if (instance == null) {
            synchronized (Serializer.class) {
                if (instance == null) {
                    new Serializer();
                    Iterator<SerializingProvider> SerializingProviders = ServiceLoader
                            .load(SerializingProvider.class).iterator();
                    while (SerializingProviders.hasNext()) {
                        SerializingProvider SerializingProvider = SerializingProviders
                                .next();
                        instance.bindSerializingProvider(SerializingProvider);
                    }
                    instance.active = true;
                    instance.refreshProviderMap();
                }
            }
        }
        return instance;

    }
 
    @Activate
    protected void activate(final ComponentContext componentContext) {
        active = true;
        refreshProviderMap();
    }

    @Deactivate
    protected void deactivate(final ComponentContext componentContext) {
        active = false;
    }
    
    @Modified
    void modified(ComponentContext ctx) {
        log.debug("modified");
    }

    /**
     * Serializes a ImmutableGraph into an OutputStream. This delegates the
     * processing to the provider registered for the specified format, if
     * the formatIdentifier contains a ';'-character only the section before
     * that character is used for choosing the provider.
     * 
     * @param serializedGraph
     *            an outputStream into which the ImmutableGraph will be serialized
     * @param tc  the <code>Graph</code> to be serialized
     * @param formatIdentifier
     *            a string specifying the serialization format (usually the
     *            MIME-type)
     * @throws UnsupportedFormatException
     */
    public void serialize(OutputStream serializedGraph, Graph tc,
            String formatIdentifier) throws UnsupportedFormatException {
        String deParameterizedIdentifier;
        int semicolonPos = formatIdentifier.indexOf(';');
        if (semicolonPos > -1) {
            deParameterizedIdentifier = formatIdentifier.substring(0, semicolonPos);
        } else {
            deParameterizedIdentifier = formatIdentifier;
        }
        SerializingProvider provider = providerMap.get(deParameterizedIdentifier);
        if (provider == null) {
            throw new UnsupportedSerializationFormatException(formatIdentifier);
        }
        provider.serialize(serializedGraph, tc, formatIdentifier);
    }

    /**
     * Get a set of supported formats
     *
     * @return a set if stings identifying formats (usually the MIME-type)
     */
    public Set<String> getSupportedFormats() {
        return Collections.unmodifiableSet(providerMap.keySet());
    }
    
    /**
     * Registers a Serializing provider
     * 
     * @param provider
     *            the provider to be registered
     */
    @Reference(policy = ReferencePolicy.DYNAMIC, 
            cardinality = ReferenceCardinality.MULTIPLE)
    public void bindSerializingProvider(SerializingProvider provider) {
        providerList.add(provider);
        refreshProviderMap();

    }

    /**
     * Unregister a Serializing provider
     * 
     * @param provider
     *            the provider to be unregistered
     */
    public void unbindSerializingProvider(SerializingProvider provider) {
        providerList.remove(provider);
        refreshProviderMap();

    }

    private void refreshProviderMap() {
        if (active) {
            final Map<String, SerializingProvider> newProviderMap = new HashMap<String, SerializingProvider>();
            //we want more generic providers first so they get overridden by more specific ones
            Collections.sort(providerList, new Comparator<SerializingProvider>() {
                @Override
                public int compare(SerializingProvider s1, SerializingProvider s2) {
                    return getFormatIdentifiers(s2).length - getFormatIdentifiers(s1).length;
                }
            });
            for (SerializingProvider provider : providerList) {
                String[] formatIdentifiers = getFormatIdentifiers(provider);
                for (String formatIdentifier : formatIdentifiers) {
                    newProviderMap.put(formatIdentifier, provider);
                }
            }
            providerMap = newProviderMap;
            if (configurationAdmin != null) { //we are in OSGi environment
                try {
                    Dictionary<String, Object> newConfig = configurationAdmin.getConfiguration(getClass().getName()).getProperties();
                    if (newConfig == null) {
                        newConfig = new Hashtable<String, Object>();
                    }
                    Set<String> supportedFormats = getSupportedFormats();
                    String[] supportedFromatsArray = supportedFormats.toArray(new String[supportedFormats.size()]);
                    newConfig.put(SupportedFormat.supportedFormat, supportedFromatsArray);
                    configurationAdmin.getConfiguration(getClass().getName()).update(newConfig);
                } catch (IOException ex) {
                    throw new RuntimeException(ex);
                }
            }
        }
    }

    private String[] getFormatIdentifiers(
            SerializingProvider SerializingProvider) {
        Class<? extends SerializingProvider> clazz = SerializingProvider
                .getClass();
        SupportedFormat supportedFormatAnnotation = clazz
                .getAnnotation(SupportedFormat.class);
        String[] formatIdentifiers = supportedFormatAnnotation.value();
        return formatIdentifiers;
    }
    
    @Reference
    protected void bindConfigurationAdmin(ConfigurationAdmin configurationAdmin) {
        this.configurationAdmin = configurationAdmin;
    }

    protected void unbindConfigurationAdmin(ConfigurationAdmin configurationAdmin) {
        this.configurationAdmin = null;
    }
}


<|start_filename|>api/src/main/java/org/apache/clerezza/Triple.java<|end_filename|>
/*
 * 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.clerezza;

/**
 * A structure containing a subject, a predicate, and an object.
 * Also known as a statement.
 *
 * @author reto
 */
public interface Triple {

    BlankNodeOrIRI getSubject();

    IRI getPredicate();

    RDFTerm getObject();

    /**
     * @param obj
     * @return true iff subject, predicate, and object of both triples are equal
     */
    @Override
    boolean equals(Object obj);

    /**
     * The hash code is computed as follow
     * (subject.hashCode() >> 1) ^  predicate.hashCode() ^ object.hashCode() << 1)
     * <p>
     * Note that the hash returned is computed including the hash of BNodes, so
     * it is not blank-node blind as in Graph.
     * <p>
     * This would have to change if triple should extend Graph
     *
     * @return hash code
     */
    @Override
    int hashCode();
}


<|start_filename|>representation/src/main/java/org/apache/clerezza/representation/SerializingProvider.java<|end_filename|>
/*
 * 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.clerezza.representation;

import org.apache.clerezza.Graph;

import java.io.OutputStream;

/**
 * An instance of this class serializes <code>Graph</code>s to a
 * specified serialization format. The supported formats are indicated using the
 * {@link SupportedFormat} annotation.
 *
 * @author mir
 */
public interface SerializingProvider {
    
    /** Serializes a <code>Graph</code> to a specified
     * <code>OutputStream</code> in the format identified by
     * <code>formatIdentifier</code>. This method will be invoked
     * for a supported format, a format is considered as supported if the part
     * before a ';'-character in the <code>formatIdentifier</code> matches
     * a <code>SupportedFormat</code> annotation of the implementing class.
     * 
     * @param outputStream
     * @param tc
     * @param formatIdentifier
     */
    public void serialize(OutputStream outputStream, Graph tc,
                          String formatIdentifier);

}


<|start_filename|>api.utils/src/test/java/org/apache/clerezza/utils/SameAsSmushTest.java<|end_filename|>
/*
 * 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.clerezza.utils;

import org.apache.clerezza.Graph;
import org.apache.clerezza.IRI;
import org.apache.clerezza.Literal;
import org.apache.clerezza.Triple;
import org.apache.clerezza.implementation.TripleImpl;
import org.apache.clerezza.implementation.in_memory.SimpleGraph;
import org.apache.clerezza.implementation.literal.PlainLiteralImpl;
import org.apache.clerezza.ontologies.FOAF;
import org.apache.clerezza.ontologies.OWL;
import org.apache.clerezza.ontologies.RDFS;
import org.junit.Assert;
import org.junit.Test;

import java.util.Iterator;

/**
 * @author reto
 */
public class SameAsSmushTest {

    private final IRI uriA = new IRI("http://example.org/A");
    private final IRI uriB = new IRI("http://example.org/B");
    private final Literal lit = new PlainLiteralImpl("That's me (and you)");

    private Graph sameAsStatements = new SimpleGraph();

    {
        sameAsStatements.add(new TripleImpl(uriA, OWL.sameAs, uriB));
    }

    private Graph dataGraph = new SimpleGraph();

    {
        dataGraph.add(new TripleImpl(uriA, FOAF.knows, uriB));
        dataGraph.add(new TripleImpl(uriB, RDFS.label, lit));
        dataGraph.add(new TripleImpl(uriA, RDFS.label, lit));
    }

    @Test
    public void simple() {
        Assert.assertEquals(3, dataGraph.size());
        Smusher.sameAsSmush(dataGraph, sameAsStatements);
        Assert.assertEquals(3, dataGraph.size());
        Assert.assertTrue(dataGraph.filter(null, OWL.sameAs, null).hasNext());
        //exactly one statement with literal 
        Iterator<Triple> litStmts = dataGraph.filter(null, null, lit);
        Assert.assertTrue(litStmts.hasNext());
        Triple litStmt = litStmts.next();
        Assert.assertFalse(litStmts.hasNext());
        Iterator<Triple> knowsStmts = dataGraph.filter(null, FOAF.knows, null);
        Assert.assertTrue(knowsStmts.hasNext());
        Triple knowStmt = knowsStmts.next();
        Assert.assertEquals(knowStmt.getSubject(), knowStmt.getObject());
        Assert.assertEquals(litStmt.getSubject(), knowStmt.getObject());
        Assert.assertEquals(litStmt.getSubject(), dataGraph.filter(null, OWL.sameAs, null).next().getObject());
    }
}


<|start_filename|>api-implementation/src/main/java/org/apache/clerezza/implementation/TripleImpl.java<|end_filename|>
/*
 * 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.clerezza.implementation;

import org.apache.clerezza.BlankNodeOrIRI;
import org.apache.clerezza.IRI;
import org.apache.clerezza.RDFTerm;
import org.apache.clerezza.Triple;

/**
 * @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 + ".";
    }
}


<|start_filename|>jaxrs.rdf.providers/src/main/java/org/apache/clerezza/jaxrs/sparql/providers/ResultSetTsvMessageBodyWriter.java<|end_filename|>
/*
 * 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.clerezza.jaxrs.sparql.providers;

import org.apache.clerezza.BlankNode;
import org.apache.clerezza.IRI;
import org.apache.clerezza.Literal;
import org.apache.clerezza.RDFTerm;
import org.apache.clerezza.sparql.ResultSet;
import org.apache.clerezza.sparql.SolutionMapping;
import org.osgi.service.component.annotations.Component;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.ws.rs.Produces;
import javax.ws.rs.WebApplicationException;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.MultivaluedMap;
import javax.ws.rs.ext.MessageBodyWriter;
import javax.ws.rs.ext.Provider;
import java.io.IOException;
import java.io.OutputStream;
import java.io.UnsupportedEncodingException;
import java.lang.annotation.Annotation;
import java.lang.reflect.Type;
import java.util.List;

/**
 * MessageBodyWirter for <code>ResultSet</code>. Resulting output is tsv and
 * conforms to:
 * http://www.w3.org/TR/2013/REC-sparql11-results-csv-tsv-20130321/#tsv
 * <p>
 * Also see: http://www.iana.org/assignments/media-types/text/tab-separated-values
 *
 * @author misl
 */
@Component(service = Object.class, property = {"javax.ws.rs=true"})
@Produces({"text/tab-separated-values"})
@Provider
public class ResultSetTsvMessageBodyWriter implements MessageBodyWriter<ResultSet> {

    private static final Logger logger = LoggerFactory
            .getLogger(ResultSetTsvMessageBodyWriter.class);

    private String textEncoding = "UTF-8";
    private byte[] separator;

    public ResultSetTsvMessageBodyWriter() {
        try {
            buildSeparatorConformEncoding(textEncoding);
        } catch (UnsupportedEncodingException e) {
            logger.error("Developer error", e);
        }
    }

    // --------------------------------------------------------------------------
    // Implementing MessageBodyWriter
    // --------------------------------------------------------------------------

    @Override
    public boolean isWriteable(Class<?> type, Type genericType, Annotation[] annotations,
                               MediaType mediaType) {
        return ResultSet.class.isAssignableFrom(type);
    }

    @Override
    public long getSize(ResultSet t, Class<?> type, Type genericType, Annotation[] annotations,
                        MediaType mediaType) {
        return -1;
    }

    @Override
    public void writeTo(ResultSet resultSet, Class<?> type, Type genericType,
                        Annotation[] annotations, MediaType mediaType, MultivaluedMap<String, Object> httpHeaders,
                        OutputStream entityStream) throws IOException, WebApplicationException {

        // According to spec header is mandatory.
        writeTsvHeader(entityStream, resultSet.getResultVars());
        while (resultSet.hasNext()) {
            writeTsvLine(entityStream, resultSet.getResultVars(), resultSet.next());
        }
    }

    // --------------------------------------------------------------------------
    // Public interface
    // --------------------------------------------------------------------------

    /**
     * Sets the text encoding for the resource. This setting must only used
     * if the resource response represents text.
     *
     * @param textEncoding character encoding of text body
     * @throws UnsupportedEncodingException when the given encoding is not supported.
     */
    public void setTextEncoding(String textEncoding) throws UnsupportedEncodingException {
        buildSeparatorConformEncoding(textEncoding);
        this.textEncoding = textEncoding;
    }

    /**
     * @return text encoding for resource
     */
    protected String getTextEncoding() {
        return textEncoding;
    }

    // --------------------------------------------------------------------------
    // Private methods
    // --------------------------------------------------------------------------

    /**
     * Builds the column separator according to the given text encoding.
     *
     * @param encoding the text encoding to be used.
     * @throws UnsupportedEncodingException when the given encoding is not supported.
     */
    private void buildSeparatorConformEncoding(String encoding) throws UnsupportedEncodingException {
        separator = ",".getBytes(encoding);
    }

    /**
     * Write resultset header to the given output stream.
     *
     * @param outputStream stream to write to.
     * @param headers      the headers to write.
     * @throws IOException
     */
    private void writeTsvHeader(OutputStream outputStream, List<String> headers) throws IOException {
        boolean first = true;
        for (String header : headers) {
            if (!first) {
                outputStream.write(separator);
            }
            writeEscaped(outputStream, header);
            first = false;
        }
        outputStream.write("\n".getBytes(textEncoding));
    }

    /**
     * Write a single tsv line using the given line data.
     *
     * @param outputStream stream to write to.
     * @param headers      the headers to write line data for.
     * @param lineData     the line data to write.
     * @throws IOException
     */
    private void writeTsvLine(OutputStream outputStream, List<String> headers,
                              SolutionMapping lineData) throws IOException {
        boolean first = true;
        for (String header : headers) {
            if (!first) {
                outputStream.write(separator);
            }
            RDFTerm resource = lineData.get(header);
            if (resource != null) {
                writeEscaped(outputStream, getResourceValue(resource));
            }
            first = false;
        }
        outputStream.write("\n".getBytes(textEncoding));
    }

    /**
     * Helper to get the proper string representation for the given RDFTerm.
     */
    private String getResourceValue(RDFTerm resource) {
        StringBuilder value = new StringBuilder();
        if (resource instanceof IRI) {
            value.append(resource.toString());
        } else if (resource instanceof Literal) {
            value.append("\"");
            value.append(escapedDQuotes(((Literal) resource).getLexicalForm()));
            value.append("\"");
        } else if (resource instanceof BlankNode) {
            value.append("/");
        } else {
            value.append(resource.toString());
        }
        return value.toString();
    }

    /**
     * Write the given string to the output stream and escape the output where
     * necessary.
     *
     * @param outputStream stream to write to.
     * @param text         the text to write.
     * @throws IOException
     */
    private void writeEscaped(OutputStream outputStream, String text) throws IOException {
        String line = text;
        if (text.contains("\r")) {
            line = text.replaceAll("\r", "\\r");
        }
        if (text.contains("\n")) {
            line = text.replaceAll("\n", "\\n");
        }
        if (text.contains("\t")) {
            line = text.replaceAll("\t", "\\t");
        }
        outputStream.write(line.getBytes(textEncoding));
    }

    private String escapedDQuotes(String text) {
        String line = text;
        if (text.contains("\"")) {
            line = text.replaceAll("\"", "\"\"");
        }
        return line;
    }
}


<|start_filename|>api-implementation/src/main/java/org/apache/clerezza/implementation/literal/InvalidLiteralTypeException.java<|end_filename|>
/*
 * 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.clerezza.implementation.literal;

import org.apache.clerezza.IRI;

/**
 * Thrown when a literal is of the wrong type for conversion to a java-type
 *
 * @author reto
 */
public class InvalidLiteralTypeException extends RuntimeException {

    /**
     * Constructs the exception to be thrown when a literal cannot be
     * converted to an instance of the specified class
     *
     * @param javaType    the <code>Class</code> to convert to
     * @param literalType the literalType which can't be converted
     */
    public InvalidLiteralTypeException(Class<?> javaType, IRI literalType) {
        super("Cannot create a " + javaType + " from a literal of type " + literalType);
    }
}


<|start_filename|>api-implementation/src/main/java/org/apache/clerezza/implementation/literal/NoConvertorException.java<|end_filename|>
/*
 * 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.clerezza.implementation.literal;

import java.lang.reflect.Type;

/**
 * This exception is thrown when no convertor is available to do a required
 * java-object to literal or literal to java-object conversion.
 *
 * @author reto
 * @since 0.3
 */
public class NoConvertorException extends RuntimeException {

    /**
     * Create an instance of <code>NoConvertorException</code>
     * indicating that no convertor is available for the type.
     *
     * @param type the type for which no convertor is available
     */
    public NoConvertorException(Type type) {
        super("No convertor available for type " + type);
    }
}


<|start_filename|>sparql/src/main/java/org/apache/clerezza/sparql/StringQuerySerializer.java<|end_filename|>
/*
 * 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.clerezza.sparql;

import org.apache.clerezza.sparql.query.*;

/**
 * This abstract class provides a method to generate a {@link String}
 * representation of a {@link Query}.
 *
 * @author hasan
 */
public abstract class StringQuerySerializer {

    /**
     * Serializes a {@link Query} object to a {@link String}.
     *
     * @param query
     *        the Query object to be serialized
     * @return
     *        a String representation of the specified Query object.
     */
    public String serialize(Query query) {
        if (query instanceof SelectQuery) {
            return serialize((SelectQuery) query);
        } else if (query instanceof ConstructQuery) {
            return serialize((ConstructQuery) query);
        } else if (query instanceof DescribeQuery) {
            return serialize((DescribeQuery) query);
        } else {
            return serialize((AskQuery) query);
        }
    }

    /**
     * Serializes a {@link SelectQuery} object to a {@link String}.
     *
     * @param selectQuery
     *        the SelectQuery object to be serialized
     * @return
     *        a String representation of the specified SelectQuery object.
     */
    public abstract String serialize(SelectQuery selectQuery);

    /**
     * Serializes a {@link ConstructQuery} object to a {@link String}.
     *
     * @param constructQuery
     *        the ConstructQuery object to be serialized
     * @return
     *        a String representation of the specified ConstructQuery object.
     */
    public abstract String serialize(ConstructQuery constructQuery);

    /**
     * Serializes a {@link DescribeQuery} object to a {@link String}.
     *
     * @param describeQuery
     *        the DescribeQuery object to be serialized
     * @return
     *        a String representation of the specified DescribeQuery object.
     */
    public abstract String serialize(DescribeQuery describeQuery);

    /**
     * Serializes an {@link AskQuery} object to a {@link String}.
     *
     * @param askQuery
     *        the AskQuery object to be serialized
     * @return
     *        a String representation of the specified AskQuery object.
     */
    public abstract String serialize(AskQuery askQuery);
}


<|start_filename|>representation/src/main/java/org/apache/clerezza/representation/Parser.java<|end_filename|>
/*
 * 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.clerezza.representation;

import org.apache.clerezza.Graph;
import org.apache.clerezza.IRI;
import org.apache.clerezza.ImmutableGraph;
import org.apache.clerezza.implementation.in_memory.SimpleGraph;
import org.osgi.service.cm.ConfigurationAdmin;
import org.osgi.service.component.ComponentContext;
import org.osgi.service.component.annotations.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.IOException;
import java.io.InputStream;
import java.util.*;

/**
 * This singleton class provides a method
 * <code>parse</code> to transform serialized RDF forms into {@link ImmutableGraph}s.
 *
 * Functionality is delegated to registered {@link ParsingProvider}s. Such
 * <code>ParsingProvider</code>s can be registered and unregistered, later
 * registered
 * <code>ParsingProvider</code>s shadow previously registered providers for the
 * same format.
 *
 * Note on synchronization:
 * <code>ParsingProvider</code>s must be able to handle concurrent requests.
 *
 * @author reto
 *
 */
@Component(service = Parser.class)
public class Parser {

    private ConfigurationAdmin configurationAdmin;
    /**
     * The list of providers in the order of registration
     */
    private List<ParsingProvider> providerList = new ArrayList<ParsingProvider>();
    /**
     * A map to quickly locate a provider
     */
    private volatile Map<String, ParsingProvider> providerMap = new HashMap<String, ParsingProvider>();
    /**
     * The singleton instance
     */
    private volatile static Parser instance;
    private boolean active;

    private static final Logger log = LoggerFactory.getLogger(Parser.class);
    /**
     * the constructor sets the singleton instance to allow instantiation
     * by OSGi-DS. This constructor should not be called except by OSGi-DS,
     * otherwise the static <code>getInstance</code> method should be used.
     */
    public Parser() {
        log.info("constructing Parser");
        Parser.instance = this;
    }

    /**
     * A constructor for tests, which doesn't set the singleton instance
     *
     * @param dummy an ignored argument to distinguish this from the other constructor
     */
    Parser(Object dummy) {
        active = true;
    }

    /**
     * This returns the singleton instance, if an instance has been previously
     * created (e.g. by OSGi declarative services) this instance is returned,
     * otherwise a new instance is created and providers are injected using 
     * the service provider interface (META-INF/services/)
     *
     * @return the singleton Parser instance
     */
    public static Parser getInstance() {
        if (instance == null) {
            synchronized (Parser.class) {
                if (instance == null) {
                    new Parser();
                    Iterator<ParsingProvider> parsingProviders =
                            ServiceLoader.load(ParsingProvider.class).iterator();
                    while (parsingProviders.hasNext()) {
                        ParsingProvider parsingProvider = parsingProviders.next();
                        instance.bindParsingProvider(parsingProvider);
                    }
                    instance.active = true;
                    instance.refreshProviderMap();
                }
            }
        }
        return instance;

    }

    @Activate
    protected void activate(final ComponentContext componentContext) {
        active = true;
        refreshProviderMap();
        //changing the congiguration before this finshed activating causes a new instance to be created
        /*(new Thread() {
            @Override
            public void run() {
                try {
                    Thread.sleep(100);
                } catch (InterruptedException ex) {
                    return;
                }
                refreshProviderMap();
            }
            
            
        }).start();*/
    }

    @Deactivate
    protected void deactivate(final ComponentContext componentContext) {
        active = false;
    }
    
    @Modified
    void modified(ComponentContext ctx) {
        log.debug("modified");
    }

    /**
     * Parses a serialized ImmutableGraph from an InputStream. This delegates the
     * processing to the provider registered for the specified format, if
     * the formatIdentifier contains a ';'-character only the section before
     * that character is used for choosing the provider.
     *
     * @param serializedGraph an inputstream with the serialization
     * @param formatIdentifier a string identifying the format (usually the MIME-type)
     * @return the ImmutableGraph read from the stream
     * @throws UnsupportedFormatException
     */
    public ImmutableGraph parse(InputStream serializedGraph,
            String formatIdentifier) throws UnsupportedFormatException {
        return parse(serializedGraph, formatIdentifier, null);
    }

    /**
     * Parses a serialized ImmutableGraph from an InputStream. This delegates the
     * processing to the provider registered for the specified format, if
     * the formatIdentifier contains a ';'-character only the section before
     * that character is used for choosing the provider.
     *
     * @param target the Graph to which the parsed triples are added
     * @param serializedGraph an inputstream with the serialization
     * @param formatIdentifier a string identifying the format (usually the MIME-type)
     * @throws UnsupportedFormatException
     */
    public void parse(Graph target, InputStream serializedGraph,
            String formatIdentifier) throws UnsupportedFormatException {
        parse(target, serializedGraph, formatIdentifier, null);
    }

    /**
     * Parses a serialized ImmutableGraph from an InputStream. This delegates the
     * processing to the provider registered for the specified format, if
     * the formatIdentifier contains a ';'-character only the section before
     * that character is used for choosing the provider.
     *
     * @param serializedGraph an inputstream with the serialization
     * @param formatIdentifier a string identifying the format (usually the MIME-type)
     * @param baseUri the uri against which relative uri-refs are evaluated
     * @return the ImmutableGraph read from the stream
     * @throws UnsupportedFormatException
     */
    public ImmutableGraph parse(InputStream serializedGraph,
            String formatIdentifier, IRI baseUri) throws UnsupportedFormatException {
        Graph graph = new SimpleGraph();
        parse(graph, serializedGraph, formatIdentifier, baseUri);
        return graph.getImmutableGraph();
    }

    /**
     * Parses a serialized ImmutableGraph from an InputStream. This delegates the
     * processing to the provider registered for the specified format, if
     * the formatIdentifier contains a ';'-character only the section before
     * that character is used for choosing the provider.
     *
     * @param target the Graph to which the parsed triples are added
     * @param serializedGraph an inputstream with the serialization
     * @param formatIdentifier a string identifying the format (usually the MIME-type)
     * @param baseUri the uri against which relative uri-refs are evaluated
     * @throws UnsupportedFormatException
     */
    public void parse(Graph target, InputStream serializedGraph,
            String formatIdentifier, IRI baseUri) throws UnsupportedFormatException {
        String deParameterizedIdentifier;
        int semicolonPos = formatIdentifier.indexOf(';');
        if (semicolonPos > -1) {
            deParameterizedIdentifier = formatIdentifier.substring(0, semicolonPos);
        } else {
            deParameterizedIdentifier = formatIdentifier;
        }
        ParsingProvider provider = providerMap.get(deParameterizedIdentifier);
        if (provider == null) {
            throw new UnsupportedParsingFormatException(formatIdentifier);
        }
        provider.parse(target, serializedGraph, formatIdentifier, baseUri);
    }

    /**
     * Get a set of supported formats
     *
     * @return a set if stings identifying formats (usually the MIME-type)
     */
    public Set<String> getSupportedFormats() {
        return Collections.unmodifiableSet(providerMap.keySet());
    }

    /**
     * Registers a parsing provider
     *
     * @param provider the provider to be registered
     */
    @Reference(policy = ReferencePolicy.DYNAMIC,
            cardinality = ReferenceCardinality.MULTIPLE)
    public void bindParsingProvider(ParsingProvider provider) {
        providerList.add(provider);
        refreshProviderMap();
    }

    /**
     * Unregister a parsing provider
     *
     * @param provider the provider to be deregistered
     */
    public void unbindParsingProvider(ParsingProvider provider) {
        providerList.remove(provider);
        refreshProviderMap();
    }

    /**
     * Update providerMap with the providers in the providerList
     *
     */
    private void refreshProviderMap() {
        if (active) {
            try {
                final Map<String, ParsingProvider> newProviderMap = new HashMap<String, ParsingProvider>();
                for (ParsingProvider provider : providerList) {
                    String[] formatIdentifiers = getFormatIdentifiers(provider);
                    for (String formatIdentifier : formatIdentifiers) {
                        newProviderMap.put(formatIdentifier, provider);
                    }
                }
                providerMap = newProviderMap;
                if (configurationAdmin != null) { //i.e. when we are in an OSGi environment
                    Dictionary<String, Object> newConfig = configurationAdmin.getConfiguration(getClass().getName()).getProperties();
                    if (newConfig == null) {
                        newConfig = new Hashtable<String, Object>();
                    }
                    Set<String> supportedFormats = getSupportedFormats();
                    String[] supportedFromatsArray = supportedFormats.toArray(new String[supportedFormats.size()]);
                    newConfig.put(SupportedFormat.supportedFormat, supportedFromatsArray);
                    configurationAdmin.getConfiguration(getClass().getName()).update(newConfig);
                }
            } catch (IOException ex) {
                throw new RuntimeException(ex);
            }
        }
    }

    

    /**
     * Extract format identifiers for a parsing provider
     *
     * @param provider the provider to be registered
     * @return formatIdentifiers
     */
    private String[] getFormatIdentifiers(ParsingProvider parsingProvider) {
        Class<? extends ParsingProvider> clazz = parsingProvider.getClass();
        SupportedFormat supportedFormatAnnotation = clazz.getAnnotation(SupportedFormat.class);
        String[] formatIdentifiers = supportedFormatAnnotation.value();
        return formatIdentifiers;
    }

    @Reference
    protected void bindConfigurationAdmin(ConfigurationAdmin configurationAdmin) {
        this.configurationAdmin = configurationAdmin;
    }

    protected void unbindConfigurationAdmin(ConfigurationAdmin configurationAdmin) {
        this.configurationAdmin = null;
    }
}


<|start_filename|>api/src/main/java/org/apache/clerezza/BlankNode.java<|end_filename|>
/*
 * 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.clerezza;

/**
 * A Blank Node represents a resource,
 * but does not indicate a URI for the resource. Blank nodes act like
 * existentially qualified variables in first order logic.
 * <p>
 * An <a href= "http://www.w3.org/TR/rdf11-concepts/#dfn-blank-node" >RDF-1.1
 * Blank Node</a>, as defined by <a href=
 * "http://www.w3.org/TR/rdf11-concepts/#section-blank-nodes" >RDF-1.1 Concepts
 * and Abstract Syntax</a>, a W3C Recommendation published on 25 February 2014.<br>
 * <p>
 * Note that: Blank nodes are disjoint from IRIs and literals. Otherwise,
 * the set of possible blank nodes is arbitrary. RDF makes no reference to any
 * internal structure of blank nodes.
 *
 * @see <a href= "http://www.w3.org/TR/rdf11-concepts/#dfn-blank-node">RDF-1.1
 * Blank Node</a>
 */
public class BlankNode implements BlankNodeOrIRI {

}


<|start_filename|>sparql/src/main/java/org/apache/clerezza/sparql/query/PropertySet.java<|end_filename|>
/*
 * 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.clerezza.sparql.query;

import java.util.HashSet;
import java.util.Set;

/**
 * A property set is intended to store only predicate paths and inverse predicate paths.
 *
 * @author hasan
 */
public class PropertySet implements PropertyPathExpression {
    private Set<PropertyPathExpression> propertySet = new HashSet<PropertyPathExpression>();

    /**
     * 
     * @param propertyPathExpression expected value is a predicate path or an inverse predicate path
     */
    public void addElement(PropertyPathExpression propertyPathExpression) {
        this.propertySet.add(propertyPathExpression);
    }

    public Set<PropertyPathExpression> getPropertySet() {
        return propertySet;
    }

}


<|start_filename|>api-implementation/src/main/java/org/apache/clerezza/implementation/debug/ReentrantReadWriteLockTracker.java<|end_filename|>
/*
 * 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.clerezza.implementation.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;
    }


}


<|start_filename|>sparql/src/main/java/org/apache/clerezza/sparql/update/impl/LoadOperation.java<|end_filename|>
/*
 * 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.clerezza.sparql.update.impl;

import org.apache.clerezza.IRI;

/**
 * The LOAD operation reads an RDF document from a IRI and inserts its triples into the specified ImmutableGraph in the ImmutableGraph Store. 
 * If the destination ImmutableGraph already exists, then no data in that ImmutableGraph will be removed.
 * If no destination ImmutableGraph IRI is provided to load the triples into, then the data will be loaded into the default ImmutableGraph.
 * @see <a href="http://www.w3.org/TR/2013/REC-sparql11-update-20130321/#load">SPARQL 1.1 Update: 3.1.4 LOAD</a>
 * @author hasan
 */
public class LoadOperation extends SimpleUpdateOperation {

    public void setSource(IRI source) {
        setInputGraph(source);
    }

    public IRI getSource() {
        return getInputGraph(null);
    }
}


<|start_filename|>api.utils/src/main/java/org/apache/clerezza/utils/UriMutatingGraph.java<|end_filename|>
/*
 * 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.clerezza.utils;

import org.apache.clerezza.*;
import org.apache.clerezza.implementation.TripleImpl;
import org.apache.clerezza.implementation.in_memory.SimpleImmutableGraph;

import java.util.Collection;
import java.util.Iterator;
import java.util.concurrent.locks.ReadWriteLock;

/**
 * This wrapps a Triplecollection changing a prefix for the IRIs contained
 * in subject or object position.
 * <p>
 * Currently it only supports read opearations.
 *
 * @author reto
 */
public class UriMutatingGraph implements Graph {

    private final Graph base;
    private final String sourcePrefix;
    private final String targetPrefix;
    private final int sourcePrefixLength;
    private final int targetPrefixLength;

    public UriMutatingGraph(Graph base, String sourcePrefix,
                            String targetPrefix) {
        this.base = base;
        this.sourcePrefix = sourcePrefix;
        sourcePrefixLength = sourcePrefix.length();
        this.targetPrefix = targetPrefix;
        targetPrefixLength = targetPrefix.length();
    }

    private <R extends RDFTerm> R toTargetRDFTerm(final R sourceRDFTerm) {
        if (sourceRDFTerm instanceof IRI) {
            final IRI sourceIRI = (IRI) sourceRDFTerm;
            if (sourceIRI.getUnicodeString().startsWith(sourcePrefix)) {
                final String uriRest = sourceIRI.getUnicodeString()
                        .substring(sourcePrefixLength);
                return (R) new IRI(targetPrefix + uriRest);
            }
        }
        return sourceRDFTerm;
    }

    private Triple toTargetTriple(Triple triple) {
        if (triple == null) {
            return null;
        }
        return new TripleImpl(toTargetRDFTerm(triple.getSubject()),
                triple.getPredicate(), toTargetRDFTerm(triple.getObject()));
    }

    private <R extends RDFTerm> R toSourceRDFTerm(final R targetRDFTerm) {
        if (targetRDFTerm instanceof IRI) {
            final IRI sourceIRI = (IRI) targetRDFTerm;
            if (sourceIRI.getUnicodeString().startsWith(targetPrefix)) {
                final String uriRest = sourceIRI.getUnicodeString()
                        .substring(targetPrefixLength);
                return (R) new IRI(sourcePrefix + uriRest);
            }
        }
        return targetRDFTerm;
    }

    private Triple toSourceTriple(Triple triple) {
        if (triple == null) {
            return null;
        }
        return new TripleImpl(toSourceRDFTerm(triple.getSubject()),
                triple.getPredicate(), toSourceRDFTerm(triple.getObject()));
    }

    @Override
    public Iterator<Triple> filter(BlankNodeOrIRI subject, IRI predicate, RDFTerm object) {
        final Iterator<Triple> baseIter = base.filter(toSourceRDFTerm(subject),
                predicate, toSourceRDFTerm(object));
        return new WrappedIteraror(baseIter);
    }

    @Override
    public int size() {
        return base.size();
    }

    @Override
    public boolean isEmpty() {
        return base.isEmpty();
    }

    @Override
    public boolean contains(Object o) {
        return base.contains(toSourceTriple((Triple) o));
    }

    @Override
    public Iterator<Triple> iterator() {
        return filter(null, null, null);
    }

    @Override
    public Object[] toArray() {
        Object[] result = base.toArray();
        for (int i = 0; i < result.length; i++) {
            Triple triple = (Triple) result[i];
            result[i] = toTargetTriple(triple);
        }
        return result;
    }

    @Override
    public <T> T[] toArray(T[] a) {
        T[] result = base.toArray(a);
        for (int i = 0; i < result.length; i++) {
            Triple triple = (Triple) result[i];
            result[i] = (T) toTargetTriple(triple);
        }
        return result;
    }

    @Override
    public boolean add(Triple e) {
        throw new UnsupportedOperationException("Not supported.");
    }

    @Override
    public boolean remove(Object o) {
        throw new UnsupportedOperationException("Not supported.");
    }

    @Override
    public boolean containsAll(Collection<?> c) {
        for (Object object : c) {
            if (!contains(object)) {
                return false;
            }
        }
        return true;
    }

    @Override
    public boolean addAll(Collection<? extends Triple> c) {
        throw new UnsupportedOperationException("Not supported.");
    }

    @Override
    public boolean removeAll(Collection<?> c) {
        throw new UnsupportedOperationException("Not supported.");
    }

    @Override
    public boolean retainAll(Collection<?> c) {
        throw new UnsupportedOperationException("Not supported.");
    }

    @Override
    public void clear() {
        throw new UnsupportedOperationException("Not supported.");
    }

    @Override
    public ImmutableGraph getImmutableGraph() {
        return new SimpleImmutableGraph(this);
    }

    @Override
    public ReadWriteLock getLock() {
        return base.getLock();
    }

    class WrappedIteraror implements Iterator<Triple> {
        private final Iterator<Triple> baseIter;

        private WrappedIteraror(Iterator<Triple> baseIter) {
            this.baseIter = baseIter;
        }

        @Override
        public boolean hasNext() {
            return baseIter.hasNext();
        }

        @Override
        public Triple next() {
            return toTargetTriple(baseIter.next());
        }

        @Override
        public void remove() {
            throw new UnsupportedOperationException("Not supported yet.");
        }

    }
}


<|start_filename|>representation/src/main/java/org/apache/clerezza/representation/SupportedFormat.java<|end_filename|>
/*
 * 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.clerezza.representation;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

/**
 * This annotation is used to annotate {@link ParsingProvider}s to indicate
 * the format(s) they support.
 *
 * @author reto
 */
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
public @interface SupportedFormat {

    /**
     * used as a key for the OSGi service property
     */
    public static final String supportedFormat = "supportedFormat";
    public static final String RDF_XML = "application/rdf+xml";
    public static final String TURTLE = "text/turtle";
    public static final String X_TURTLE = "application/x-turtle";
    public static final String N_TRIPLE = "application/n-triples";
    /**
    * @deprecated: The mime-type for N Triples is "application/n-triples": http://www.w3.org/TR/n-triples/#sec-mediaReg-n-triples
    */
    @Deprecated
    public static final String TEXT_RDF_NT = "text/rdf+nt";
    public static final String N3 = "text/rdf+n3";
    public static final String RDF_JSON = "application/rdf+json";
    //both html and xhtml can be rdf formats with RDFa
    public static final String XHTML = "application/xhtml+xml";
    public static final String HTML = "text/html";

    /**
     * A list of format Identifiers (typically MIME-types) types without
     * parameter (without ';'-character).
     * E.g. {"application/rdf+xml","application/turtle"}
     */
    String[] value();
}


<|start_filename|>api-implementation/src/main/java/org/apache/clerezza/implementation/graph/WatchableGraphWrapper.java<|end_filename|>
/*
 * Copyright 2015 The Apache Software Foundation.
 *
 * 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.clerezza.implementation.graph;

import org.apache.clerezza.*;
import org.apache.clerezza.event.*;

import java.lang.ref.WeakReference;
import java.util.*;
import java.util.concurrent.locks.ReadWriteLock;

/**
 * @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;
        }
    }

}


<|start_filename|>api/src/main/java/org/apache/clerezza/event/GraphListener.java<|end_filename|>
/*
 * 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.clerezza.event;

import java.util.List;

/**
 * A class that is interested in graph events implements this interface and
 * is then added as listener to a <code>ListenableTripleCollection</code> or
 * one of its subclasses. When the <code>ListenableTripleCollection</code> is
 * modified, then the <code>GraphListener</code> is notified.
 *
 * @author mir
 */
public interface GraphListener {

    /**
     * This method is called when a <code>ListenableTripleCollection</code> was
     * modified, to which this <code>GraphListener</code> was added. A
     * <code>List</code> containing <code>GraphEvent</code>s are passed as
     * argument. The list contains all events in which a triple was part of
     * the modification that matched the <code>FilterTriple</code> which was passed
     * as argument when the listener was added.
     *
     * @param events
     */
    public void graphChanged(List<GraphEvent> events);
}


<|start_filename|>impl.sparql/src/test/java/org/apache/clerezza/commons/rdf/impl/sparql/BNodeCircleTest.java<|end_filename|>
/*
 * 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.clerezza.commons.rdf.impl.sparql;

import com.hp.hpl.jena.query.DatasetAccessor;
import com.hp.hpl.jena.query.DatasetAccessorFactory;
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.Iterator;
import org.apache.clerezza.commons.rdf.BlankNode;
import org.apache.clerezza.commons.rdf.BlankNodeOrIRI;
import org.apache.clerezza.commons.rdf.Graph;
import org.apache.clerezza.commons.rdf.IRI;
import org.apache.clerezza.commons.rdf.RDFTerm;
import org.apache.clerezza.commons.rdf.Triple;
import org.junit.AfterClass;
import org.junit.Assert;
import org.junit.BeforeClass;
import org.junit.Test;

/**
 *
 * @author reto
 */
public class BNodeCircleTest {

    final static int serverPort = findFreePort();
    static EmbeddedFusekiServer server;

    @BeforeClass
    public static void prepare() throws IOException {
        final String serviceURI = "http://localhost:" + serverPort + "/ds/data";
        final DatasetAccessor accessor = DatasetAccessorFactory.createHTTP(serviceURI);
        final InputStream in = BNodeCircleTest.class.getResourceAsStream("bnode-circle.ttl");
        final Model m = ModelFactory.createDefaultModel();
        String base = "http://example.org/";
        m.read(in, base, "TURTLE");
        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", 2, graph.size());
    }

    
    
    @Test
    public void nullFilter() {
        final Graph graph = new SparqlGraph("http://localhost:" + serverPort + "/ds/query");
        final Iterator<Triple> iter = graph.filter(null, null, null);
        Assert.assertTrue(iter.hasNext());
        final Triple triple1 = iter.next();
        final BlankNodeOrIRI subject = triple1.getSubject();
        final RDFTerm object = triple1.getObject();
        Assert.assertTrue(subject instanceof BlankNode);
        Assert.assertTrue(object instanceof BlankNode);
        Assert.assertNotEquals(subject, object);
        Assert.assertTrue(iter.hasNext());
    }
    
    @Test
    public void foafKnowsFilter() {
        final Graph graph = new SparqlGraph("http://localhost:" + serverPort + "/ds/query");
        
        final IRI foafKnows = new IRI("http://xmlns.com/foaf/0.1/knows");

        final Iterator<Triple> iter = graph.filter(null, foafKnows, null);
        Assert.assertTrue(iter.hasNext());
        final Triple triple1 = iter.next();
        final BlankNodeOrIRI subject = triple1.getSubject();
        final RDFTerm object = triple1.getObject();
        Assert.assertTrue(subject instanceof BlankNode);
        Assert.assertTrue(object instanceof BlankNode);
        Assert.assertNotEquals(subject, object);
        Assert.assertTrue(iter.hasNext());
    }
    

    

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

}


<|start_filename|>api-implementation/src/main/java/org/apache/clerezza/implementation/graphmatching/collections/IntHashSet.java<|end_filename|>
/*
 * Copyright 2002-2004 The Apache Software Foundation.
 *
 * 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.clerezza.implementation.graphmatching.collections;

import java.util.HashSet;
import java.util.Iterator;

/**
 * This is currently just a placeholder implementation based onm HashSet<Integer>
 * an efficient implementation is to store the primitives directly.
 *
 * @author reto
 */
public class IntHashSet extends HashSet<Integer> implements IntSet {

    @Override
    public IntIterator intIterator() {
        final Iterator<Integer> base = iterator();
        return new IntIterator() {

            @Override
            public int nextInt() {
                return base.next();
            }

            @Override
            public boolean hasNext() {
                return base.hasNext();
            }

            @Override
            public Integer next() {
                return base.next();
            }

            @Override
            public void remove() {
                base.remove();
            }
        };
    }

    @Override
    public void add(int i) {
        super.add((Integer) i);
    }

}


<|start_filename|>api-implementation/src/main/java/org/apache/clerezza/implementation/util/Base64.java<|end_filename|>
/*
 * Taken from the book:
 * <NAME>, "Java Cryptography", O'Reilly Media, Inc., 1998
 */
/*
 *
 * 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.clerezza.implementation.util;

public class Base64 {

    public static String encode(byte[] raw) {
        StringBuffer encoded = new StringBuffer();
        for (int i = 0; i < raw.length; i += 3) {
            encoded.append(encodeBlock(raw, i));
        }
        return encoded.toString();
    }

    protected static char[] encodeBlock(byte[] raw, int offset) {
        int block = 0;
        int slack = raw.length - offset - 1;
        int end = (slack >= 2) ? 2 : slack;
        for (int i = 0; i <= end; i++) {
            byte b = raw[offset + i];
            int neuter = (b < 0) ? b + 256 : b;
            block += neuter << (8 * (2 - i));
        }
        char[] base64 = new char[4];
        for (int i = 0; i < 4; i++) {
            int sixbit = (block >>> (6 * (3 - i))) & 0x3f;
            base64[i] = getChar(sixbit);
        }
        if (slack < 1) {
            base64[2] = '=';
        }
        if (slack < 2) {
            base64[3] = '=';
        }
        return base64;
    }

    protected static char getChar(int sixBit) {
        if (sixBit >= 0 && sixBit <= 25) {
            return (char) ('A' + sixBit);
        }
        if (sixBit >= 26 && sixBit <= 51) {
            return (char) ('a' + (sixBit - 26));
        }
        if (sixBit >= 52 && sixBit <= 61) {
            return (char) ('0' + (sixBit - 52));
        }
        if (sixBit == 62) {
            return '+';
        }
        if (sixBit == 63) {
            return '/';
        }
        return '?';
    }

    public static byte[] decode(String base64) {
        int pad = 0;
        for (int i = base64.length() - 1; base64.charAt(i) == '='; i--) {
            pad++;
        }
        int length = base64.length() * 6 / 8 - pad;
        byte[] raw = new byte[length];
        int rawIndex = 0;
        for (int i = 0; i < base64.length(); i += 4) {
            int block = (getValue(base64.charAt(i)) << 18) + (getValue(base64.charAt(i + 1)) << 12) + (getValue(base64.charAt(i + 2)) << 6) + (getValue(base64.charAt(i + 3)));
            for (int j = 0; j < 3 && rawIndex + j < raw.length; j++) {
                raw[rawIndex + j] = (byte) ((block >> (8 * (2 - j))) & 0xff);
            }
            rawIndex += 3;
        }
        return raw;
    }

    protected static int getValue(char c) {
        if (c >= 'A' && c <= 'Z') {
            return c - 'A';
        }
        if (c >= 'a' && c <= 'z') {
            return c - 'a' + 26;
        }
        if (c >= '0' && c <= '9') {
            return c - '0' + 52;
        }
        if (c == '+') {
            return 62;
        }
        if (c == '/') {
            return 63;
        }
        if (c == '=') {
            return 0;
        }
        return -1;
    }

}


<|start_filename|>sparql/src/main/java/org/apache/clerezza/sparql/update/impl/ModifyOperation.java<|end_filename|>
/*
 * 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.clerezza.sparql.update.impl;

import org.apache.clerezza.IRI;
import org.apache.clerezza.sparql.GraphStore;
import org.apache.clerezza.sparql.query.GroupGraphPattern;
import org.apache.clerezza.sparql.query.impl.SimpleDataSet;
import org.apache.clerezza.sparql.update.UpdateOperation;

import java.util.HashSet;
import java.util.Set;

/**
 * This ModifyOperation is a DELETE/INSERT operation.
 * @see <a href="http://www.w3.org/TR/2013/REC-sparql11-update-20130321/#deleteInsert">SPARQL 1.1 Update: 3.1.3 DELETE/INSERT</a>
 * 
 * The DELETE/INSERT operation can be used to remove or add triples from/to the ImmutableGraph Store based on bindings 
 * for a query pattern specified in a WHERE clause.
 * 
 * @author hasan
 */
public class ModifyOperation implements UpdateOperation {
    private IRI fallbackGraph = null;
    private UpdateOperationWithQuads deleteOperation = null;
    private UpdateOperationWithQuads insertOperation = null;
    private SimpleDataSet dataSet = null;
    private GroupGraphPattern queryPattern = null;

    public void setFallbackGraph(IRI fallbackGraph) {
        this.fallbackGraph = fallbackGraph;
    }

    public void setDeleteOperation(UpdateOperationWithQuads deleteOperation) {
        this.deleteOperation = deleteOperation;
    }

    public void setInsertOperation(UpdateOperationWithQuads insertOperation) {
        this.insertOperation = insertOperation;
    }

    public void setDataSet(SimpleDataSet dataSet) {
        this.dataSet = dataSet;
    }

    public void addGraphToDataSet(IRI ImmutableGraph) {
        if (dataSet == null) {
            dataSet = new SimpleDataSet();
        }
        dataSet.addDefaultGraph(ImmutableGraph);
    }

    public void addNamedGraphToDataSet(IRI namedGraph) {
        if (dataSet == null) {
            dataSet = new SimpleDataSet();
        }
        dataSet.addNamedGraph(namedGraph);
    }

    public void setQueryPattern(GroupGraphPattern queryPattern) {
        this.queryPattern = queryPattern;
    }

    @Override
    public Set<IRI> getInputGraphs(IRI defaultGraph, GraphStore graphStore) {
        Set<IRI> graphs = new HashSet<IRI>();
        if (dataSet != null) {
            graphs.addAll(dataSet.getDefaultGraphs());
            graphs.addAll(dataSet.getNamedGraphs());
        } else {
            if (fallbackGraph != null) {
                graphs.add(fallbackGraph);
            }
        }
        if (graphs.isEmpty()) {
            graphs.add(defaultGraph);
        }
        if (queryPattern != null) {
            graphs.addAll(queryPattern.getReferredGraphs());
        }
        return graphs;
    }

    @Override
    public Set<IRI> getDestinationGraphs(IRI defaultGraph, GraphStore graphStore) {
        Set<IRI> graphs = new HashSet<IRI>();
        IRI dfltGraph = (fallbackGraph != null) ? fallbackGraph : defaultGraph;
        if (deleteOperation != null) {
            graphs.addAll(deleteOperation.getDestinationGraphs(dfltGraph, graphStore));
        }
        if (insertOperation != null) {
            graphs.addAll(insertOperation.getDestinationGraphs(dfltGraph, graphStore));
        }
        return graphs;
    }
}


<|start_filename|>api.utils/src/main/java/org/apache/clerezza/utils/graphnodeprovider/GraphNodeProvider.java<|end_filename|>
/*
 * 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.clerezza.utils.graphnodeprovider;

import org.apache.clerezza.IRI;
import org.apache.clerezza.utils.GraphNode;

/**
 * A service that returns a GraphNode for a specified named resource, the
 * returned GraphNode has as BaseGraph the ContentGraph provided by the
 * ContentGraphProvider and the for remote uris the Graphs they dereference to
 * and for local URIs with a path-section starting with /user/{username}/ the
 * local-public-graph of that user.
 */
public interface GraphNodeProvider {

    /**
     * Get a GraphNode for the specified resource, see class comments for
     * details.
     */
    GraphNode get(IRI uriRef);

    /**
     * Get a GraphNode for the specified resource, The resource is assumed to be
     * local, i.e. the method behaves like get(IRI) for a Uri with an
     * authority section contained in the Set retuned by
     * <code>org.apache.clerezza.platform.config.PlatformConfig#getBaseUris()</code>
     */
    GraphNode getLocal(IRI uriRef);

    /**
     * return true iff getLocal(uriRef).getNodeContext.size > 0
     */
    boolean existsLocal(IRI uriRef);
}


<|start_filename|>api-implementation/src/main/java/org/apache/clerezza/implementation/graphmatching/collections/IntIterator.java<|end_filename|>
/*
 * Copyright 2002-2004 The Apache Software Foundation.
 *
 * 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.clerezza.implementation.graphmatching.collections;

import java.util.Iterator;

/**
 * An iterator allowing to iterate over ints, Iterator<Integer> is extended for
 * compatibility, however accessing nextInt allows faster implementations.
 *
 * @author reto
 */
public interface IntIterator extends Iterator<Integer> {
    public int nextInt();
}


<|start_filename|>api/src/main/java/org/apache/clerezza/Graph.java<|end_filename|>
/*
 * 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.clerezza;

import java.util.Collection;
import java.util.Iterator;
import java.util.concurrent.locks.ReadWriteLock;


/**
 * A set of triples (as it doesn't allow duplicates), it does however
 * not extend {@link java.util.Set} as it doesn't inherit its
 * specification for <code>hashCode()</code> and <code>equals</code>.
 * It is possible to add <code>GraphListener</code> to listen for modifications
 * in the triples.
 *
 * @author reto
 */
public interface Graph extends Collection<Triple> {

    /**
     * Filters triples given a pattern.
     * filter(null, null, null) returns the same as iterator()
     *
     * @param subject
     * @param predicate
     * @param object
     * @return <code>Iterator</code>
     */
    public Iterator<Triple> filter(BlankNodeOrIRI subject, IRI predicate,
                                   RDFTerm object);

    /**
     * Returns true if <code>other</code> describes the same graph and will
     * always describe the same graph as this instance, false otherwise.
     * It returns true if this == other or if it
     * is otherwise guaranteed that changes to one of the instances are
     * immediately reflected in the other or if both graphs are immutable.
     *
     * @param other
     * @return true if other == this
     */
    @Override
    public boolean equals(Object other);

    /**
     * Returns an ImutableGraph describing the graph at the current point in
     * time. if <code>this</code> is an instance of ImmutableGraph this can
     * safely return <code>this</code>.
     *
     * @return the current time slice of the possibly mutable graph represented by the instance.
     */
    public ImmutableGraph getImmutableGraph();

    /**
     * The lock provided by this methods allows to create read- and write-locks
     * that span multiple method calls. Having a read locks prevents other
     * threads from writing to this Graph, having a write-lock prevents other
     * threads from reading and writing. Implementations would typically
     * return a <code>java.util.concurrent.locks.ReentrantReadWriteLock</code>.
     * Immutable instances (such as instances of <code>ImmutableGraph</code>)
     * or instances used in transaction where concurrent acces of the same
     * instance is not an issue may return a no-op ReadWriteLock (i.e. one
     * which returned ReadLock and WriteLock instances of which the methods do
     * not do anything)
     *
     * @return the lock of this Graph
     */
    ReadWriteLock getLock();
}


<|start_filename|>sparql/src/main/java/org/apache/clerezza/sparql/update/impl/BaseUpdateOperation.java<|end_filename|>
/*
 * 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.clerezza.sparql.update.impl;

import org.apache.clerezza.IRI;
import org.apache.clerezza.sparql.GraphStore;
import org.apache.clerezza.sparql.update.UpdateOperation;

import java.util.HashSet;
import java.util.Set;

/**
 *
 * @author hasan
 */
public abstract class BaseUpdateOperation implements UpdateOperation {

    protected Set<IRI> inputGraphs = new HashSet<IRI>();
    protected Set<IRI> destinationGraphs = new HashSet<IRI>();
    protected GraphSpec inputGraphSpec = GraphSpec.GRAPH;
    protected GraphSpec destinationGraphSpec = GraphSpec.GRAPH;

    public void setInputGraphSpec(GraphSpec inputGraphSpec) {
        this.inputGraphSpec = inputGraphSpec;
    }

    public GraphSpec getInputGraphSpec() {
        return inputGraphSpec;
    }

    public void setDestinationGraphSpec(GraphSpec destinationGraphSpec) {
        this.destinationGraphSpec = destinationGraphSpec;
    }

    public GraphSpec getDestinationGraphSpec() {
        return destinationGraphSpec;
    }

    @Override
    public Set<IRI> getInputGraphs(IRI defaultGraph, GraphStore graphStore) {
        return getGraphs(defaultGraph, graphStore, inputGraphSpec, inputGraphs);
    }

    private Set<IRI> getGraphs(IRI defaultGraph, GraphStore graphStore, GraphSpec graphSpec, Set<IRI> graphs) {
        switch (graphSpec) {
            case DEFAULT:
                Set<IRI> result = new HashSet<IRI>();
                result.add(defaultGraph);
                return result;
            case NAMED:
            case ALL:
                return graphStore.listGraphs();
            default:
                return graphs;
        }
    }

    @Override
    public Set<IRI> getDestinationGraphs(IRI defaultGraph, GraphStore graphStore) {
        return getGraphs(defaultGraph, graphStore, destinationGraphSpec, destinationGraphs);
    }

    public void addInputGraph(IRI ImmutableGraph) {
        inputGraphs.add(ImmutableGraph);
    }

    public void addDestinationGraph(IRI ImmutableGraph) {
        destinationGraphs.add(ImmutableGraph);
    }
}


<|start_filename|>jaxrs.rdf.providers/src/main/java/org/apache/clerezza/jaxrs/sparql/providers/ResultSetXmlMessageBodyWriter.java<|end_filename|>
/*
 * 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.clerezza.jaxrs.sparql.providers;

import org.apache.clerezza.IRI;
import org.apache.clerezza.Language;
import org.apache.clerezza.Literal;
import org.apache.clerezza.RDFTerm;
import org.apache.clerezza.sparql.ResultSet;
import org.apache.clerezza.sparql.SolutionMapping;
import org.apache.clerezza.sparql.query.Variable;
import org.osgi.service.component.annotations.Component;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.w3c.dom.Document;
import org.w3c.dom.Element;

import javax.ws.rs.Produces;
import javax.ws.rs.WebApplicationException;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.MultivaluedMap;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.Response.Status;
import javax.ws.rs.ext.MessageBodyWriter;
import javax.ws.rs.ext.Provider;
import javax.ws.rs.ext.Providers;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.Source;
import javax.xml.transform.dom.DOMSource;
import java.io.IOException;
import java.io.OutputStream;
import java.lang.annotation.Annotation;
import java.lang.reflect.Type;
import java.util.List;
import java.util.Set;

/**
 * MessageBodyWirter for <code>ResultSet</code>.
 * Resulting output conforms to:
 * http://www.w3.org/TR/2008/REC-rdf-sparql-XMLres-20080115/
 *
 * @author mir, reto
 */
@Component(service = Object.class, property = {"javax.ws.rs=true"})
@Produces({"application/xml", "text/xml", "application/sparql-results+xml"})
@Provider
public class ResultSetXmlMessageBodyWriter implements MessageBodyWriter<ResultSet> {

    private Providers providers;

    final Logger logger = LoggerFactory.getLogger(ResultSetXmlMessageBodyWriter.class);

    @Override
    public boolean isWriteable(Class<?> type, Type genericType, Annotation[] annotations,
                               MediaType mediaType) {
        return ResultSet.class.isAssignableFrom(type);
    }

    @Override
    public long getSize(ResultSet t, Class<?> type, Type genericType,
                        Annotation[] annotations, MediaType mediaType) {
        return -1;
    }

    @Override
    public void writeTo(ResultSet resultSet, Class<?> type, Type genericType,
                        Annotation[] annotations, MediaType mediaType, MultivaluedMap<String,
            Object> httpHeaders, OutputStream entityStream) throws IOException, WebApplicationException {

        Source source = toXmlSource(resultSet);
        MessageBodyWriter<Source> sourceMessageBodyWriter =
                providers.getMessageBodyWriter(Source.class, null, null, mediaType);
        sourceMessageBodyWriter.writeTo(source, Source.class, null, null, mediaType,
                httpHeaders, entityStream);
    }

    @Context
    public void setProviders(Providers providers) {
        this.providers = providers;
    }

    /**
     * Helper: transforms a {@link ResultSet} or a {@link Boolean} to a
     * {@link DOMSource}
     *
     * @param queryResult
     * @param query
     * @param applyStyle
     */
    private Source toXmlSource(ResultSet queryResult) {
        DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
        try {
            Document doc = dbf.newDocumentBuilder().newDocument();
            // adding root element
            Element root = doc.createElement("sparql");
            root.setAttribute("xmlns", "http://www.w3.org/2005/sparql-results#");
            doc.appendChild(root);
            Element head = doc.createElement("head");
            createVariables(queryResult.getResultVars(), head, doc);
            root.appendChild(head);

            Element results = doc.createElement("results");
            while (queryResult.hasNext()) {
                createResultElement(queryResult.next(), results, doc);
            }
            root.appendChild(results);

            DOMSource source = new DOMSource(doc);
            return source;

        } catch (ParserConfigurationException e) {
            throw createWebApplicationException(e);
        }
    }

    /**
     * Creates a WebApplicationexception and prints a logger entry
     */
    private WebApplicationException createWebApplicationException(Exception e) {
        return new WebApplicationException(Response.status(Status.BAD_REQUEST)
                .entity(e.getMessage().replace("<", "&lt;").replace("\n",
                        "<br/>")).build());
    }


    /**
     * Helper: creates value element from {@link RDFTerm} depending on its
     * class
     */
    private Element createValueElement(RDFTerm resource, Document doc) {
        Element value = null;
        if (resource instanceof IRI) {
            value = doc.createElement("uri");
            value.appendChild(doc.createTextNode(((IRI) resource)
                    .getUnicodeString()));
        } else if (resource instanceof Literal) {
            value = doc.createElement("literal");
            value.appendChild(doc.createTextNode(((Literal) resource)
                    .getLexicalForm()));
            value.setAttribute("datatype", (((Literal) resource)
                    .getDataType().getUnicodeString()));
            Language lang = ((Literal) resource).getLanguage();
            if (lang != null) {
                value.setAttribute("xml:lang", (lang.toString()));
            }
        } else {
            value = doc.createElement("bnode");
            value.appendChild(doc.createTextNode("/"));
        }
        return value;
    }

    /**
     * Helper: creates results element from ResultSet
     */
    private void createResultElement(SolutionMapping solutionMap, Element results, Document doc) {
        Set<Variable> keys = solutionMap.keySet();
        Element result = doc.createElement("result");
        results.appendChild(result);
        for (Variable key : keys) {
            Element bindingElement = doc.createElement("binding");
            bindingElement.setAttribute("name", key.getName());
            bindingElement.appendChild(createValueElement((RDFTerm) solutionMap.get(key), doc));
            result.appendChild(bindingElement);
        }
    }

    private void createVariables(List<String> variables, Element head, Document doc) {
        for (String variable : variables) {
            Element varElement = doc.createElement("variable");
            varElement.setAttribute("name", variable);
            head.appendChild(varElement);
        }
    }
}


<|start_filename|>sparql/src/main/java/org/apache/clerezza/sparql/query/impl/SimpleGroupGraphPattern.java<|end_filename|>
/*
 * 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.clerezza.sparql.query.impl;

import org.apache.clerezza.IRI;
import org.apache.clerezza.sparql.query.*;

import java.util.*;

/**
 * This class implements {@link GroupGraphPattern}.
 *
 * @author hasan
 */
public class SimpleGroupGraphPattern implements GroupGraphPattern {

	private List<Expression> constraints = new ArrayList<Expression>();
	private List<GraphPattern> graphPatterns = new ArrayList<GraphPattern>();
    private SelectQuery subSelect = null;
    private boolean lastBasicGraphPatternIsComplete = true;

    @Override
    public boolean isSubSelect() {
        return subSelect != null;
    }

    @Override
    public SelectQuery getSubSelect() {
        return subSelect;
    }

    @Override
	public Set<GraphPattern> getGraphPatterns() {
		return subSelect == null ? new LinkedHashSet(graphPatterns) : null;
	}

	@Override
	public List<Expression> getFilter() {
		return subSelect == null ? constraints : null;
	}

    public void setSubSelect(SelectQuery subSelect) {
        this.subSelect = subSelect;
    }

    /**
	 * Adds a {@link GraphPattern} to the group.
	 *
	 * @param graphPattern
	 *		the GraphPattern to be added.
	 */
	public void addGraphPattern(GraphPattern graphPattern) {
        subSelect = null;
        graphPatterns.add(graphPattern);
        lastBasicGraphPatternIsComplete =
                !(graphPattern instanceof BasicGraphPattern || graphPattern instanceof PathSupportedBasicGraphPattern);
	}

	/**
	 * Adds a constraint to the {@link GroupGraphPattern}.
	 *
	 * @param constraint
	 *		an {@link Expression} as the constraint to be added.
	 */
	public void addConstraint(Expression constraint) {
        subSelect = null;
		constraints.add(constraint);
	}

    public void endLastBasicGraphPattern() {
        lastBasicGraphPatternIsComplete = true;
    }

    /**
	 * If the last {@link GraphPattern} added to the group is not a 
	 * {@link SimplePathSupportedBasicGraphPattern}, then creates one containing the 
	 * specified {@link PropertyPathPattern}s and adds it to the group.
	 * Otherwise, adds the specified {@link PropertyPathPattern}s to the last
	 * added {@link SimplePathSupportedBasicGraphPattern} in the group.
	 * 
	 * @param propertyPathPatterns
	 *		a set of {@link PropertyPathPattern}s to be added into a 
	 *		{@link SimplePathSupportedBasicGraphPattern} of the group.
	 */
	public void addPropertyPathPatterns(Set<PropertyPathPattern> propertyPathPatterns) {
        subSelect = null;
        if (lastBasicGraphPatternIsComplete) {
            graphPatterns.add(new SimplePathSupportedBasicGraphPattern(propertyPathPatterns));
            lastBasicGraphPatternIsComplete = false;
        } else {
            GraphPattern prevGraphPattern;
        	int size = graphPatterns.size();
			prevGraphPattern = graphPatterns.get(size-1);
            if (prevGraphPattern instanceof SimplePathSupportedBasicGraphPattern) {
                ((SimplePathSupportedBasicGraphPattern) prevGraphPattern).addPropertyPathPatterns(propertyPathPatterns);
            }
        }
	}

	/**
	 * If the last {@link GraphPattern} added to the group is not a 
	 * {@link SimpleBasicGraphPattern}, then creates one containing the 
	 * specified {@link TriplePattern}s and adds it to the group.
	 * Otherwise, adds the specified {@link TriplePattern}s to the last
	 * added {@link SimpleBasicGraphPattern} in the group.
	 * 
	 * @param triplePatterns
	 *		a set of {@link TriplePattern}s to be added into a 
	 *		{@link SimpleBasicGraphPattern} of the group.
	 */
	public void addTriplePatterns(Set<TriplePattern> triplePatterns) {
        subSelect = null;
        GraphPattern prevGraphPattern;
		int size = graphPatterns.size();
		if (!lastBasicGraphPatternIsComplete && (size > 0)) {
			prevGraphPattern = graphPatterns.get(size-1);
			if (prevGraphPattern instanceof SimpleBasicGraphPattern) {
				((SimpleBasicGraphPattern) prevGraphPattern)
						.addTriplePatterns(triplePatterns);
				return;
			}
		}
		graphPatterns.add(new SimpleBasicGraphPattern(triplePatterns));
        lastBasicGraphPatternIsComplete = false;
	}

	/**
	 * Adds an {@link OptionalGraphPattern} to the group consisting of
	 * a main ImmutableGraph pattern and the specified {@link GroupGraphPattern} as
	 * the optional pattern.
	 * The main ImmutableGraph pattern is taken from the last added {@link GraphPattern}
	 * in the group, if it exists. Otherwise, the main ImmutableGraph pattern is null.
	 *
	 * @param optional
	 *		a {@link GroupGraphPattern} as the optional pattern of
	 *		an {@link OptionalGraphPattern}.
	 */
	public void addOptionalGraphPattern(GroupGraphPattern optional) {
        subSelect = null;
		GraphPattern prevGraphPattern = null;
		int size = graphPatterns.size();
		if (size > 0) {
			prevGraphPattern = graphPatterns.remove(size-1);
		}
		graphPatterns.add(new SimpleOptionalGraphPattern(prevGraphPattern, optional));
        lastBasicGraphPatternIsComplete = true;
	}

    public void addMinusGraphPattern(GroupGraphPattern subtrahend) {
        subSelect = null;
		GraphPattern prevGraphPattern = null;
		int size = graphPatterns.size();
		if (size > 0) {
			prevGraphPattern = graphPatterns.remove(size-1);
		}
		graphPatterns.add(new SimpleMinusGraphPattern(prevGraphPattern, subtrahend));
        lastBasicGraphPatternIsComplete = true;
	}

    @Override
    public Set<IRI> getReferredGraphs() {
        Set<IRI> referredGraphs = new HashSet<IRI>();
        if (subSelect != null) {
            GroupGraphPattern queryPattern = subSelect.getQueryPattern();
            referredGraphs.addAll(queryPattern.getReferredGraphs());
        } else {
            for (GraphPattern graphPattern : graphPatterns) {
                referredGraphs.addAll(getReferredGraphs(graphPattern));
            }
        }
        return referredGraphs;
    }

    private Set<IRI> getReferredGraphs(GraphPattern graphPattern) {
        Set<IRI> referredGraphs = new HashSet<IRI>();
        if (graphPattern instanceof GraphGraphPattern) {
            GraphGraphPattern graphGraphPattern = (GraphGraphPattern) graphPattern;
            UriRefOrVariable ImmutableGraph = graphGraphPattern.getGraph();
            if (!ImmutableGraph.isVariable()) {
                referredGraphs.add(ImmutableGraph.getResource());
            }
            referredGraphs.addAll(graphGraphPattern.getGroupGraphPattern().getReferredGraphs());
        } else if (graphPattern instanceof AlternativeGraphPattern) {
            List<GroupGraphPattern> alternativeGraphPatterns =
                    ((AlternativeGraphPattern) graphPattern).getAlternativeGraphPatterns();
            for (GroupGraphPattern groupGraphPattern : alternativeGraphPatterns) {
                referredGraphs.addAll(groupGraphPattern.getReferredGraphs());
            }
        } else if (graphPattern instanceof OptionalGraphPattern) {
            GraphPattern mainGraphPattern = ((OptionalGraphPattern) graphPattern).getMainGraphPattern();
            referredGraphs.addAll(getReferredGraphs(mainGraphPattern));
            GroupGraphPattern optionalGraphPattern = ((OptionalGraphPattern) graphPattern).getOptionalGraphPattern();
            referredGraphs.addAll(optionalGraphPattern.getReferredGraphs());
        } else if (graphPattern instanceof MinusGraphPattern) {
            GraphPattern minuendGraphPattern = ((MinusGraphPattern) graphPattern).getMinuendGraphPattern();
            referredGraphs.addAll(getReferredGraphs(minuendGraphPattern));
            GroupGraphPattern subtrahendGraphPattern = ((MinusGraphPattern) graphPattern).getSubtrahendGraphPattern();
            referredGraphs.addAll(subtrahendGraphPattern.getReferredGraphs());
        } else if (graphPattern instanceof GroupGraphPattern) {
            GroupGraphPattern groupGraphPattern = (GroupGraphPattern) graphPattern;
            referredGraphs.addAll(groupGraphPattern.getReferredGraphs());
        }
        return referredGraphs;
    }
}


<|start_filename|>sparql/src/main/java/org/apache/clerezza/sparql/query/Variable.java<|end_filename|>
/*
 * 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.clerezza.sparql.query;

import java.util.UUID;

/**
 * Defines a Variable. A Variable can occur in an {@link Expression} and is
 * itself an {@link Expression}.
 * 
 * @author hasan
 */
public class Variable implements Expression {

	private String name;
	private Expression boundExpression;

	public Variable() {
		this.name = UUID.randomUUID().toString();
	}

	/**
	 * Creates a variable with the specified name
	 *
	 * @param name
	 */
	public Variable(String name) {
		if (name == null) {
			throw new IllegalArgumentException("name may not be null");
		}
		this.name = name;
	}

	public Variable(String name, Expression boundExpression) {
		this.name = name;
		this.boundExpression = boundExpression;
	}

	/**
	 * @return the name
	 */
	public String getName() {
		return name;
	}

	public Expression getBoundExpression() {
		return boundExpression;
	}

	public void setBoundExpression(Expression boundExpression) {
		this.boundExpression = boundExpression;
	}

	@Override
	public boolean equals(Object obj) {
		if (obj == null) {
			return false;
		}
		if (getClass() != obj.getClass()) {
			return false;
		}
		final Variable other = (Variable) obj;
		return name.equals(other.name);
	}

	@Override
	public int hashCode() {
		return name.hashCode();
	}
}


<|start_filename|>api/src/main/java/org/apache/clerezza/ImmutableGraph.java<|end_filename|>
/*
 * 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.clerezza;

/**
 * A graph, modeled as a set of triples.
 * This interface does not extend java.util.Set because of the different
 * identity constraints, i.e. two <code>Graph</code>s may be equal (isomorphic)
 * even if the set of triples are not.
 * <p>
 * Implementations MUST be immutable and throw respective exceptions, when
 * add/remove-methods are called.
 *
 * @author reto
 * @see org.apache.clerezza.rdf.core.impl.AbstractGraph
 */
public interface ImmutableGraph extends Graph {

    /**
     * Returns true if two graphs are isomorphic
     *
     * @return true if two graphs are isomorphic
     */
    @Override
    public boolean equals(Object obj);

    /**
     * Return the sum of the blank-nodes independent hashes of the triples.
     * More precisely the hash of the triple is calculated as follows:
     * (hash(subject) >> 1) ^  hash(hashCode) ^ (hash(hashCode) << 1)
     * Where the hash-fucntion return the hashCode of the argument
     * for grounded arguments and 0 otherwise.
     *
     * @return hash code
     */
    @Override
    public int hashCode();
}

<|start_filename|>impl.sparql/src/test/java/org/apache/clerezza/commons/rdf/impl/sparql/SparqlGraphTest.java<|end_filename|>
/*
 * 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.clerezza.commons.rdf.impl.sparql;

import com.hp.hpl.jena.query.DatasetAccessor;
import com.hp.hpl.jena.query.DatasetAccessorFactory;
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.clerezza.commons.rdf.Graph;
import org.apache.clerezza.commons.rdf.IRI;
import org.apache.clerezza.commons.rdf.Language;
import org.apache.clerezza.commons.rdf.Literal;
import org.apache.clerezza.commons.rdf.RDFTerm;
import org.apache.clerezza.commons.rdf.Triple;
import org.apache.clerezza.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 DatasetAccessor accessor = DatasetAccessorFactory.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");
        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")));
            Assert.assertTrue(names.contains(new PlainLiteralImpl("Человек-паук", new Language("ru"))));
        }
    }

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

}


<|start_filename|>impl.sparql/src/main/java/org/apache/clerezza/commons/rdf/impl/sparql/SparqlBNode.java<|end_filename|>
/*
 * 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.clerezza.commons.rdf.impl.sparql;

import java.util.Collection;
import java.util.Objects;
import org.apache.clerezza.commons.rdf.BlankNode;
import org.apache.clerezza.commons.rdf.BlankNodeOrIRI;
import org.apache.clerezza.commons.rdf.ImmutableGraph;
import org.apache.clerezza.commons.rdf.IRI;
import org.apache.clerezza.commons.rdf.RDFTerm;
import org.apache.clerezza.commons.rdf.Triple;
import org.apache.clerezza.commons.rdf.impl.utils.TripleImpl;
import org.apache.clerezza.commons.rdf.impl.utils.simple.SimpleGraph;

/**
 *
 * @author developer
 */
class SparqlBNode extends BlankNode {
    
    final static IRI internalBNodeId = new IRI("urn:x-internalid:fdmpoihdfw");
    
    final ImmutableGraph context;
    private final int isoDistinguisher;

    SparqlBNode(BlankNode node, Collection<Triple> context, int isoDistinguisher) {
        this.isoDistinguisher = isoDistinguisher;
        final SimpleGraph contextBuider = new SimpleGraph();
        for (Triple triple : context) {
            BlankNodeOrIRI subject = triple.getSubject();
            RDFTerm object = triple.getObject();
            contextBuider.add(new TripleImpl(subject.equals(node) ? internalBNodeId : subject, 
                    triple.getPredicate(), 
                    object.equals(node) ? internalBNodeId : object));
        }
        this.context = contextBuider.getImmutableGraph();
    }

    @Override
    public int hashCode() {
        int hash = 7+isoDistinguisher;
        hash = 61 * hash + Objects.hashCode(this.context);
        return hash;
    }

    @Override
    public boolean equals(Object obj) {
        if (obj == null) {
            return false;
        }
        if (getClass() != obj.getClass()) {
            return false;
        }
        final SparqlBNode other = (SparqlBNode) obj;
        if (isoDistinguisher != other.isoDistinguisher) {
            return false;
        }
        return Objects.equals(this.context, other.context);
    }
}


<|start_filename|>api-implementation/src/main/java/org/apache/clerezza/implementation/literal/PlainLiteralImpl.java<|end_filename|>
/*
 * 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.clerezza.implementation.literal;

import org.apache.clerezza.IRI;
import org.apache.clerezza.Language;
import org.apache.clerezza.Literal;

import java.io.Serializable;

/**
 * @author reto
 */
public class PlainLiteralImpl extends AbstractLiteral implements Literal, Serializable {

    private final String lexicalForm;
    private final Language language;

    public PlainLiteralImpl(String value) {
        this(value, null);
    }

    public PlainLiteralImpl(String value, Language language) {
        if (value == null) {
            throw new IllegalArgumentException("The literal string cannot be null");
        }
        this.lexicalForm = value;
        this.language = language;
        if (language == null) {
            dataType = XSD_STRING;
        } else {
            dataType = RDF_LANG_STRING;
        }
    }

    @Override
    public String getLexicalForm() {
        return lexicalForm;
    }

    @Override
    public Language getLanguage() {
        return language;
    }

    @Override
    public String toString() {
        final StringBuilder result = new StringBuilder();
        result.append('\"').append(lexicalForm).append('\"');
        if (language != null) {
            result.append("@").append(language.toString());
        }
        return result.toString();
    }

    @Override
    public IRI getDataType() {
        return dataType;
    }

    private final IRI dataType;
    private static final IRI XSD_STRING = new IRI("http://www.w3.org/2001/XMLSchema#string");
    private static final IRI RDF_LANG_STRING = new IRI("http://www.w3.org/1999/02/22-rdf-syntax-ns#langString");
}


<|start_filename|>sparql/src/main/java/org/apache/clerezza/sparql/query/impl/SimpleQuery.java<|end_filename|>
/*
 * 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.clerezza.sparql.query.impl;

import org.apache.clerezza.IRI;
import org.apache.clerezza.sparql.query.DataSet;
import org.apache.clerezza.sparql.query.GroupGraphPattern;
import org.apache.clerezza.sparql.query.InlineData;
import org.apache.clerezza.sparql.query.Query;

/**
 *
 * @author hasan
 */
public abstract class SimpleQuery implements Query {

    private SimpleDataSet dataSet = null;
    private GroupGraphPattern queryPattern = null;
    private InlineData inlineData = null;

    @Override
    public DataSet getDataSet() {
        return dataSet;
    }

    @Override
    public GroupGraphPattern getQueryPattern() {
        return queryPattern;
    }

    @Override
    public InlineData getInlineData() {
        return inlineData;
    }

    public void addDefaultGraph(IRI defaultGraph) {
        if (dataSet == null) {
            dataSet = new SimpleDataSet();
        }
        dataSet.addDefaultGraph(defaultGraph);
    }

    public void addNamedGraph(IRI namedGraph) {
        if (dataSet == null) {
            dataSet = new SimpleDataSet();
        }
        dataSet.addNamedGraph(namedGraph);
    }

    public void setQueryPattern(GroupGraphPattern queryPattern) {
        this.queryPattern = queryPattern;
    }

    public void setInlineData(InlineData inlineData) {
        this.inlineData = inlineData;
    }

    @Override
    public abstract String toString();
}


<|start_filename|>impl.sparql/src/test/java/org/apache/clerezza/commons/rdf/impl/sparql/SparqlClientTest.java<|end_filename|>
/*
 * 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.clerezza.commons.rdf.impl.sparql;

import com.hp.hpl.jena.query.DatasetAccessor;
import com.hp.hpl.jena.query.DatasetAccessorFactory;
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.List;
import java.util.Map;
import org.apache.clerezza.commons.rdf.Graph;
import org.apache.clerezza.commons.rdf.RDFTerm;
import org.junit.AfterClass;
import org.junit.Assert;
import org.junit.BeforeClass;
import org.junit.Test;

/**
 *
 * @author reto
 */
public class SparqlClientTest {

    final static int serverPort = findFreePort();
    static EmbeddedFusekiServer server;

    @BeforeClass
    public static void prepare() throws IOException {
        final String serviceURI = "http://localhost:" + serverPort + "/ds/data";
        final DatasetAccessor accessor = DatasetAccessorFactory.createHTTP(serviceURI);
        final InputStream in = SparqlClientTest.class.getResourceAsStream("grounded.ttl");
        final Model m = ModelFactory.createDefaultModel();
        String base = "http://example.org/";
        m.read(in, base, "TURTLE");
        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 select() throws IOException {
        final SparqlClient sparqlClient = new SparqlClient(
                "http://localhost:" + serverPort + "/ds/query");
        List<Map<String, RDFTerm>> result = sparqlClient.queryResultSet(
                "SELECT ?name WHERE { "
                        + "<http://example.org/#spiderman> "
                        + "<http://xmlns.com/foaf/0.1/name> ?name}");
        Assert.assertEquals("There should be two names", 2, result.size());
    }
    
    @Test
    public void ask() throws IOException {
        final SparqlClient sparqlClient = new SparqlClient(
                "http://localhost:" + serverPort + "/ds/query");
        Object result = sparqlClient.queryResult(
                "ASK { "
                        + "<http://example.org/#spiderman> "
                        + "<http://xmlns.com/foaf/0.1/name> ?name}");
        Assert.assertEquals("ASK should result to true", Boolean.TRUE, result);
    }

    @Test
    public void desribe() throws IOException {
        final SparqlClient sparqlClient = new SparqlClient(
                "http://localhost:" + serverPort + "/ds/query");
        Object result = sparqlClient.queryResult(
                "DESCRIBE <http://example.org/#spiderman>");
        Assert.assertTrue("DESCRIBE should return a graph", result instanceof Graph);
    }

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

}


<|start_filename|>sparql/src/main/java/org/apache/clerezza/sparql/query/impl/SimpleDescribeQuery.java<|end_filename|>
/*
 * 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.clerezza.sparql.query.impl;

import org.apache.clerezza.sparql.query.DescribeQuery;
import org.apache.clerezza.sparql.query.ResourceOrVariable;

import java.util.ArrayList;
import java.util.List;

/**
 *
 * @author hasan
 */
public class SimpleDescribeQuery extends SimpleQueryWithSolutionModifier
        implements DescribeQuery {

    private boolean describeAll;
    private List<ResourceOrVariable> resourcesToDescribe =
            new ArrayList<ResourceOrVariable>();

    @Override
    public boolean isDescribeAll() {
        return describeAll;
    }

    @Override
    public List<ResourceOrVariable> getResourcesToDescribe() {
        return resourcesToDescribe;
    }

    public void setDescribeAll() {
        assert resourcesToDescribe.isEmpty();
        describeAll = true;
    }

    public void addResourceToDescribe(ResourceOrVariable node) {
        resourcesToDescribe.add(node);
    }

    @Override
    public String toString() {
        return (new SimpleStringQuerySerializer()).serialize(this);
    }
}


<|start_filename|>api-implementation/src/main/java/org/apache/clerezza/implementation/graphmatching/MappingIterator.java<|end_filename|>
/*
 * 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.clerezza.implementation.graphmatching;

import java.util.*;

/**
 * An iterator over all possible mapping beetween the elemnets of two sets of
 * the same size, each mapping maps each element from set1 to a disctinct one of
 * set2.
 *
 * @author reto
 */
class MappingIterator<T, U> implements Iterator<Map<T, U>> {

    private List<T> list1;
    private Iterator<List<U>> permutationList2Iterator;


    public MappingIterator(Set<T> set1, Set<U> set2) {
        if (set1.size() != set2.size()) {
            throw new IllegalArgumentException();
        }
        this.list1 = new ArrayList<T>(set1);
        permutationList2Iterator = new PermutationIterator<U>(
                new ArrayList<U>(set2));
    }

    @Override
    public boolean hasNext() {
        return permutationList2Iterator.hasNext();
    }

    @Override
    public Map<T, U> next() {
        List<U> list2 = permutationList2Iterator.next();
        Map<T, U> result = new HashMap<T, U>(list1.size());
        for (int i = 0; i < list1.size(); i++) {
            result.put(list1.get(i), list2.get(i));
        }
        return result;
    }

    @Override
    public void remove() {
        throw new UnsupportedOperationException("Not supported.");
    }


}
