Java tutorial
/* * Licensed to Aduna under one or more contributor license agreements. * See the NOTICE.txt file distributed with this work for additional * information regarding copyright ownership. * * Aduna licenses this file to you under the terms of the Aduna BSD * License (the "License"); you may not use this file except in compliance * with the License. See the LICENSE.txt file distributed with this work * for the full License. * * 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.openrdf.sail.federation; import java.io.File; import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; import java.util.List; import java.util.concurrent.Executor; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import org.apache.http.client.HttpClient; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.openrdf.IsolationLevel; import org.openrdf.IsolationLevels; import org.openrdf.http.client.HttpClientDependent; import org.openrdf.http.client.SesameClient; import org.openrdf.http.client.SesameClientDependent; import org.openrdf.model.ValueFactory; import org.openrdf.model.impl.SimpleValueFactory; import org.openrdf.query.Dataset; import org.openrdf.query.algebra.evaluation.EvaluationStrategy; import org.openrdf.query.algebra.evaluation.TripleSource; import org.openrdf.query.algebra.evaluation.federation.FederatedServiceResolver; import org.openrdf.query.algebra.evaluation.federation.FederatedServiceResolverClient; import org.openrdf.query.algebra.evaluation.federation.FederatedServiceResolverImpl; import org.openrdf.query.algebra.evaluation.impl.SimpleEvaluationStrategy; import org.openrdf.repository.Repository; import org.openrdf.repository.RepositoryConnection; import org.openrdf.repository.RepositoryException; import org.openrdf.repository.sail.config.RepositoryResolver; import org.openrdf.repository.sail.config.RepositoryResolverClient; import org.openrdf.sail.Sail; import org.openrdf.sail.SailConnection; import org.openrdf.sail.SailException; import org.openrdf.sail.federation.evaluation.FederationStrategy; /** * Union multiple (possibly remote) Repositories into a single RDF store. * * @author James Leigh * @author Arjohn Kampman */ public class Federation implements Sail, Executor, FederatedServiceResolverClient, RepositoryResolverClient, HttpClientDependent, SesameClientDependent { private static final Logger LOGGER = LoggerFactory.getLogger(Federation.class); private final List<Repository> members = new ArrayList<Repository>(); private final ExecutorService executor = Executors.newCachedThreadPool(); private PrefixHashSet localPropertySpace; // NOPMD private boolean distinct; private boolean readOnly; private File dataDir; /** independent life cycle */ private FederatedServiceResolver serviceResolver; /** dependent life cycle */ private FederatedServiceResolverImpl dependentServiceResolver; public File getDataDir() { return dataDir; } public void setDataDir(File dataDir) { this.dataDir = dataDir; } public ValueFactory getValueFactory() { return SimpleValueFactory.getInstance(); } public boolean isWritable() throws SailException { return !isReadOnly(); } public void addMember(Repository member) { members.add(member); } /** * @return PrefixHashSet or null */ public PrefixHashSet getLocalPropertySpace() { return localPropertySpace; } public void setLocalPropertySpace(Collection<String> localPropertySpace) { // NOPMD if (localPropertySpace.isEmpty()) { this.localPropertySpace = null; // NOPMD } else { this.localPropertySpace = new PrefixHashSet(localPropertySpace); } } public boolean isDistinct() { return distinct; } public void setDistinct(boolean distinct) { this.distinct = distinct; } public boolean isReadOnly() { return readOnly; } public void setReadOnly(boolean readOnly) { this.readOnly = readOnly; } /** * @return Returns the SERVICE resolver. */ public synchronized FederatedServiceResolver getFederatedServiceResolver() { if (serviceResolver == null) { if (dependentServiceResolver == null) { dependentServiceResolver = new FederatedServiceResolverImpl(); } return serviceResolver = dependentServiceResolver; } return serviceResolver; } /** * Overrides the {@link FederatedServiceResolver} used by this instance, but * the given resolver is not shutDown when this instance is. * * @param reslover * The SERVICE resolver to set. */ public synchronized void setFederatedServiceResolver(FederatedServiceResolver resolver) { this.serviceResolver = resolver; for (Repository member : members) { if (member instanceof FederatedServiceResolverClient) { ((FederatedServiceResolverClient) member).setFederatedServiceResolver(resolver); } } } @Override public void setRepositoryResolver(RepositoryResolver resolver) { for (Repository member : members) { if (member instanceof RepositoryResolverClient) { ((RepositoryResolverClient) member).setRepositoryResolver(resolver); } } } @Override public SesameClient getSesameClient() { for (Repository member : members) { if (member instanceof SesameClientDependent) { SesameClient client = ((SesameClientDependent) member).getSesameClient(); if (client != null) { return client; } } } return null; } @Override public void setSesameClient(SesameClient client) { for (Repository member : members) { if (member instanceof SesameClientDependent) { ((SesameClientDependent) member).setSesameClient(client); } } } @Override public HttpClient getHttpClient() { for (Repository member : members) { if (member instanceof HttpClientDependent) { HttpClient client = ((HttpClientDependent) member).getHttpClient(); if (client != null) { return client; } } } return null; } @Override public void setHttpClient(HttpClient client) { for (Repository member : members) { if (member instanceof HttpClientDependent) { ((HttpClientDependent) member).setHttpClient(client); } } } @Override public void initialize() throws SailException { for (Repository member : members) { try { member.initialize(); } catch (RepositoryException e) { throw new SailException(e); } } } public void shutDown() throws SailException { for (Repository member : members) { try { member.shutDown(); } catch (RepositoryException e) { throw new SailException(e); } } executor.shutdown(); if (dependentServiceResolver != null) { dependentServiceResolver.shutDown(); } } /** * Required by {@link java.util.concurrent.Executor Executor} interface. */ public void execute(Runnable command) { executor.execute(command); } public SailConnection getConnection() throws SailException { List<RepositoryConnection> connections = new ArrayList<RepositoryConnection>(members.size()); try { for (Repository member : members) { connections.add(member.getConnection()); } return readOnly ? new ReadOnlyConnection(this, connections) : new WritableConnection(this, connections); } catch (RepositoryException e) { closeAll(connections); throw new SailException(e); } catch (RuntimeException e) { closeAll(connections); throw e; } } protected EvaluationStrategy createEvaluationStrategy(TripleSource tripleSource, Dataset dataset, FederatedServiceResolver resolver) { return new FederationStrategy(this, tripleSource, dataset, getFederatedServiceResolver()); } private void closeAll(Iterable<RepositoryConnection> connections) { for (RepositoryConnection con : connections) { try { con.close(); } catch (RepositoryException e) { LOGGER.error(e.getMessage(), e); } } } @Override public List<IsolationLevel> getSupportedIsolationLevels() { return Arrays.asList(new IsolationLevel[] { IsolationLevels.NONE }); } @Override public IsolationLevel getDefaultIsolationLevel() { return IsolationLevels.NONE; } }