/******************************************************************************* * Copyright (c) 2008 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$ * Created by: Matthew Roy ( <a href="mailto:mroy@cambridgesemantics.com">mroy@cambridgesemantics.com </a>) * Created on: Jul 18, 2008 * Revision: $Id$ * * Contributors: * Cambridge Semantics Incorporated - initial API and implementation *******************************************************************************/ package org.openanzo.osgi.registry; import java.util.Collection; import java.util.HashSet; import java.util.Set; import java.util.concurrent.locks.ReentrantLock; import org.openanzo.client.AnzoClient; import org.openanzo.client.pool.AnzoClientPool; import org.openanzo.client.pool.RestrictedAnzoClient; import org.openanzo.datasource.IDatasourceListener; import org.openanzo.exceptions.AnzoException; import org.openanzo.glitter.query.QueryResults; import org.openanzo.osgi.registry.internal.RegistryProvider; import org.openanzo.rdf.IDataset; import org.openanzo.rdf.INamedGraph; import org.openanzo.rdf.IStatementListener; import org.openanzo.rdf.Resource; import org.openanzo.rdf.Statement; import org.openanzo.rdf.URI; import org.openanzo.rdf.Value; /** * Registry Dataset is a special dataset that is backed by a namedgraph in the registry datasource * * @author Ben Szekely ( <a href="mailto:ben@cambridgesemantics.com">ben@cambridgesemantics.com </a>) * */ public class RegistryDataset implements IDataset { //private static final Logger log = LoggerFactory.getLogger(RegistryDataset.class); private IDataset parent = null; private final RestrictedAnzoClient anzoClient; private final AnzoClientPool anzoClientPool; private final RegistryProvider registryProvider; private final Set<IDatasourceListener> datasourceListeners = new HashSet<IDatasourceListener>(); private final ReentrantLock resetLock = new ReentrantLock(); private URI registryURI = null; /** * Create a RegistryDataset for the given uri * * @param registryProvider * registry provider * @param registryUri * URI for the registry * @param userDescription * description of user/service opening registry * @param anzoClientPool * anzo client pool used to open registry graph * @throws AnzoException */ public RegistryDataset(RegistryProvider registryProvider, URI registryUri, String userDescription, AnzoClientPool anzoClientPool) throws AnzoException { this.registryURI = registryUri; this.registryProvider = registryProvider; this.anzoClient = anzoClientPool.getAnzoClient(false, userDescription); this.anzoClient.begin(); parent = anzoClient.createReplicaDataset(true, registryUri, null, null, AnzoClient.REVISIONED_NAMED_GRAPH); this.anzoClient.commit(); this.anzoClient.updateRepository(); this.anzoClientPool = anzoClientPool; } /** * * @return true if the AnzoClient under the registry is closed */ public boolean isClosed() { return !anzoClient.isConnected(); } /** * Start a transaction to update registry data */ public void beginUpdatingRegistry() { if (anzoClient.inTransaction()) { System.err.println("Already in transaction"); } anzoClient.begin(); } /** * Commit the current transaction * * @throws AnzoException */ public void commitRegistry() throws AnzoException { anzoClient.commit(); anzoClient.updateRepository(); } /** * Abort the current transaction * * @throws AnzoException */ public void abortRegistry() { anzoClient.abort(); } /** * * @return true if in transaction */ public boolean inTransaction() { return anzoClient.inTransaction(); } /** * Close the registry */ public void close() throws AnzoException { resetLock.lock(); try { parent.close(); anzoClientPool.returnAnzoClient(anzoClient); registryProvider.getRegistries().remove(this); } finally { resetLock.unlock(); } } /** * Server reset is starting, let all listeners know * * @throws AnzoException */ public void resetStarting() throws AnzoException { for (IDatasourceListener listener : datasourceListeners) { if (listener != null) listener.resetStarting(); } resetLock.lock(); } /** * Server reset in process, clean up and notify listeners to reset * * @throws AnzoException */ public void reset() throws AnzoException { parent.close(); anzoClient.clear(); for (IDatasourceListener listener : datasourceListeners) { if (listener != null) listener.reset(); } } /** * Server reset is completed, reopen registry with new data * * @throws AnzoException */ public void postReset() throws AnzoException { anzoClient.begin(); parent = anzoClient.createReplicaDataset(true, this.registryURI, null, null, AnzoClient.REVISIONED_NAMED_GRAPH); anzoClient.commit(); anzoClient.updateRepository(); for (IDatasourceListener listener : datasourceListeners) { if (listener != null) listener.postReset(); } } /** * Server reset is completed, reopen registry with new data * * @throws AnzoException */ public void resetFinished() throws AnzoException { try { for (IDatasourceListener listener : datasourceListeners) { if (listener != null) listener.resetFinished(); } } finally { resetLock.unlock(); } } /** * Register a datasource listener * * @param listener * listener to register */ public void registerDatasourceListener(IDatasourceListener listener) { datasourceListeners.add(listener); } /** * Unregister a datasource listener * * @param listener * listener to unregister */ public void unregisterDatasourceListener(IDatasourceListener listener) { datasourceListeners.remove(listener); } // all the other methods are just straight passthroughs. public INamedGraph addDefaultGraph(URI uri) { return parent.addDefaultGraph(uri); } public INamedGraph addNamedGraph(URI uri) { return parent.addNamedGraph(uri); } public void clear() { parent.clear(); } public boolean containsDefaultGraph(URI uri) { return parent.containsDefaultGraph(uri); } public boolean containsNamedGraph(URI uri) { return parent.containsNamedGraph(uri); } public QueryResults executeQuery(String query) throws AnzoException { return parent.executeQuery(query); } public Collection<Statement> find(boolean includeEntireDataset, Resource subj, URI prop, Value obj, URI... namedGraphUris) { return parent.find(includeEntireDataset, subj, prop, obj, namedGraphUris); } public INamedGraph getDatasetGraph() { return parent.getDatasetGraph(); } public INamedGraph getDefaultGraph(URI uri) { return parent.getDefaultGraph(uri); } public Set<URI> getDefaultGraphUris() { return parent.getDefaultGraphUris(); } public INamedGraph getNamedGraph(URI uri) { return parent.getNamedGraph(uri); } public Set<URI> getNamedGraphUris() { return parent.getNamedGraphUris(); } public URI getURI() { return parent.getURI(); } public void removeDefaultGraph(URI uri) { parent.removeDefaultGraph(uri); } public void removeNamedGraph(URI uri) { parent.removeNamedGraph(uri); } public void setDefaultGraphs(Set<URI> defaultGraphUris) { parent.setDefaultGraphs(defaultGraphUris); } public void setNamedGraphs(Set<URI> namedGraphUris) { parent.setNamedGraphs(namedGraphUris); } public void add(Collection<Statement> statements) { parent.add(statements); } public void add(Resource subj, URI pred, Value obj, URI namedGraphUri) { parent.add(subj, pred, obj, namedGraphUri); } public void add(Statement... statements) { parent.add(statements); } public boolean contains(Resource subj, URI prop, Value obj, URI... namedGraphUri) { return parent.contains(subj, prop, obj, namedGraphUri); } public boolean contains(Statement statement) { return parent.contains(statement); } public QueryResults executeQuery(Set<URI> defaultGraph, Set<URI> namedGraphs, Set<URI> namedDatasets, String query, URI baseUri) throws AnzoException { return parent.executeQuery(defaultGraph, namedGraphs, namedDatasets, query, baseUri); } public Collection<Statement> find(Resource subj, URI prop, Value obj, URI... namedGraphUri) { return parent.find(subj, prop, obj, namedGraphUri); } public Collection<Statement> getStatements() { return parent.getStatements(); } public boolean isEmpty() { return parent.isEmpty(); } public void remove(Collection<Statement> statements) { parent.remove(statements); } public void remove(Resource subj, URI prop, Value obj, URI... namedGraphUri) { parent.remove(subj, prop, obj, namedGraphUri); } public void remove(Statement... statements) { parent.remove(statements); } public int size() { return parent.size(); } public int size(URI... namedGraphUris) { return parent.size(namedGraphUris); } public void notifyAddStatements(Statement... statements) { parent.notifyAddStatements(statements); } public void notifyRemoveStatements(Statement... statements) { parent.notifyRemoveStatements(statements); } public void registerListener(IStatementListener<IDataset> listener) { parent.registerListener(listener); } public void unregisterListener(IStatementListener<IDataset> listener) { parent.unregisterListener(listener); } /** * @return the resetLock */ public ReentrantLock getResetLock() { return resetLock; } }