/******************************************************************************* * Copyright (c) 2004, 2007 IBM Corporation and Cambridge Semantics Incorporated. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * File: $Source: /cvsroot/slrp/boca/com.ibm.adtech.boca.core/src/com/ibm/adtech/boca/model/Attic/ContainerNamedGraph.java,v $ * Created by: Matthew Roy ( <a href="mailto:mroy@us.ibm.com">mroy@us.ibm.com </a>) * Created on: 4/27/2005 * Revision: $Id: ContainerNamedGraph.java 168 2007-07-31 14:11:14Z mroy $ * * Contributors: * IBM Corporation - initial API and implementation * Cambridge Semantics Incorporated - Fork to Anzo *******************************************************************************/ package org.openanzo.rdf; import java.util.ArrayList; import java.util.Collection; import java.util.concurrent.CopyOnWriteArraySet; import org.openanzo.exceptions.LogUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** * NamedGraph class is a graph that provides an INamedGraph interface around statements within an IQuadStore * * @author Ben Szekely ( <a href="mailto:ben@cambridgesemantics.com">ben@cambridgesemantics.com </a>) * @author Matthew Roy ( <a href="mailto:mroy@cambridgesemantics.com">mroy@cambridgesemantics.com </a>) * */ public class NamedGraph implements INamedGraph { private static final long serialVersionUID = -8380133875482128495L; private final static Logger log = LoggerFactory.getLogger(NamedGraph.class); /** Parent IContainer containing statements */ final IQuadStore quadStore; /** URI of NamedGraph */ private final URI namedGraphUri; private boolean closed = false; protected boolean notifyAddRemove = true; /** Graph listeners */ private final CopyOnWriteArraySet<IStatementListener<INamedGraph>> listeners = new CopyOnWriteArraySet<IStatementListener<INamedGraph>>(); /** * Create new ContainerNamedGraph backed by given container * * @param quadStore * Parent quadStore holding statements * @param namedGraphUri * URI of NamedGraph */ public NamedGraph(URI namedGraphUri, IQuadStore quadStore) { this.quadStore = quadStore; if (this.quadStore == null) { throw new RuntimeException("Null QuadStore"); } this.namedGraphUri = namedGraphUri; } /** * New namededgraph with URI backed by a memquadstore * * @param namedGraphUri * uri for namedgraph */ public NamedGraph(URI namedGraphUri) { this.namedGraphUri = namedGraphUri; this.quadStore = new MemQuadStore(); } /** * Clear will remove the statements for this NamedGraph from the parent container */ public void clear() { remove(find(null, null, null)); } public URI getNamedGraphUri() { return namedGraphUri; } public void add(Resource subj, URI pred, Value obj) { checkClosed(); add(new Statement(subj, pred, obj, getNamedGraphUri())); } public void remove(Resource subj, URI pred, Value obj) { checkClosed(); if (subj == null || pred == null || obj == null) { remove(find(subj, pred, obj)); } else { remove(new Statement(subj, pred, obj, getNamedGraphUri())); } } public void add(Statement... stmts) { checkClosed(); boolean foundMismatchGraph = false; for (Statement stmt : stmts) { if (stmt.getNamedGraphUri() == null || !stmt.getNamedGraphUri().equals(getNamedGraphUri())) { foundMismatchGraph = true; break; } } Statement[] stmtsArray = stmts; if (foundMismatchGraph) { ArrayList<Statement> statements = new ArrayList<Statement>(stmts.length); for (Statement stmt : stmts) { if (stmt.getNamedGraphUri() == null || !stmt.getNamedGraphUri().equals(getNamedGraphUri())) { foundMismatchGraph = true; stmt = new Statement(stmt.getSubject(), stmt.getPredicate(), stmt.getObject(), getNamedGraphUri()); } statements.add(stmt); } stmtsArray = new Statement[statements.size()]; statements.toArray(stmtsArray); } quadStore.add(stmtsArray); if (notifyAddRemove) { notifyAddStatements(stmtsArray); } } public boolean contains(Resource subj, URI prop, Value obj) { checkClosed(); return quadStore.contains(subj, prop, obj, namedGraphUri); } public boolean contains(Statement statement) { checkClosed(); return quadStore.contains(statement.getSubject(), statement.getPredicate(), statement.getObject(), namedGraphUri); } public void remove(Statement... stmts) { checkClosed(); ArrayList<Statement> statements = new ArrayList<Statement>(); for (Statement stmt : stmts) { if (stmt.getNamedGraphUri() == null || !stmt.getNamedGraphUri().equals(getNamedGraphUri())) { stmt = new Statement(stmt.getSubject(), stmt.getPredicate(), stmt.getObject(), getNamedGraphUri()); } statements.add(stmt); } quadStore.remove(statements.toArray(new Statement[0])); if (notifyAddRemove) { notifyRemoveStatements(statements.toArray(new Statement[0])); } } public void add(Collection<Statement> statements) { checkClosed(); for (Statement statement : statements) { add(statement); } } public void remove(Collection<Statement> statements) { checkClosed(); for (Statement statement : statements) { remove(statement); } } public Collection<Statement> find(Resource subj, URI prop, Value obj) { checkClosed(); return quadStore.find(subj, prop, obj, namedGraphUri); } public Collection<Statement> getStatements() { checkClosed(); return quadStore.find(null, null, null, getNamedGraphUri()); } public int size() { checkClosed(); return quadStore.size(getNamedGraphUri()); } public boolean isEmpty() { checkClosed(); return size() == 0; } public boolean isClosed() { return closed; } public void close() { closed = true; } /** * Determine whether IStatementListeners registere with this graph are automatically notified on statement add and remove calls, or whether notify must be * explicitly called. By default, this automatic notification is enabled. * * @param notifyAddRemove */ public void setNotifyAddRemove(boolean notifyAddRemove) { this.notifyAddRemove = notifyAddRemove; } public void registerListener(IStatementListener<INamedGraph> listener) { checkClosed(); listeners.add(listener); } public void unregisterListener(IStatementListener<INamedGraph> listener) { checkClosed(); listeners.remove(listener); } public void notifyAddStatements(Statement... statements) { checkClosed(); for (IStatementListener<INamedGraph> listener : listeners) { try { listener.statementsAdded(this, statements); } catch (Throwable t) { if (log.isWarnEnabled()) { log.warn(LogUtils.GLITTER_MARKER, "Error notifying listeners", t); } } } } public void notifyRemoveStatements(Statement... statements) { checkClosed(); for (IStatementListener<INamedGraph> listener : listeners) { try { listener.statementsRemoved(this, statements); } catch (Throwable t) { if (log.isWarnEnabled()) { log.warn(LogUtils.GLITTER_MARKER, "Error notifying listeners", t); } } } } protected void checkClosed() { if (closed) { throw new RuntimeException("Graph is closed"); } } }