Author: rhauch
Date: 2008-06-30 17:45:21 -0400 (Mon, 30 Jun 2008)
New Revision: 321
Added:
trunk/dna-repository/src/main/java/org/jboss/dna/repository/federation/FederatedNode.java
trunk/dna-repository/src/main/java/org/jboss/dna/repository/federation/FederatedRegion.java
trunk/dna-repository/src/main/java/org/jboss/dna/repository/federation/RepositoryConnectionFactories.java
trunk/dna-repository/src/main/java/org/jboss/dna/repository/federation/RepositorySourceManager.java
trunk/dna-repository/src/test/java/org/jboss/dna/repository/federation/FederationServiceTest.java
trunk/dna-spi/src/main/java/org/jboss/dna/spi/graph/commands/impl/BasicCompositeCommand.java
trunk/dna-spi/src/main/java/org/jboss/dna/spi/graph/connection/BasicExecutionEnvironment.java
trunk/dna-spi/src/main/java/org/jboss/dna/spi/graph/connection/ExecutionEnvironments.java
trunk/dna-spi/src/main/java/org/jboss/dna/spi/graph/connection/RepositoryConnectionPool.java
trunk/dna-spi/src/main/java/org/jboss/dna/spi/graph/impl/AbstractValueFactories.java
trunk/dna-spi/src/main/java/org/jboss/dna/spi/graph/impl/DelegatingValueFactories.java
Log:
DNA-115: Create federation service - Completed another round of refactoring to simplify
configuration that also allows distribution/clustering
Added:
trunk/dna-repository/src/main/java/org/jboss/dna/repository/federation/FederatedNode.java
===================================================================
---
trunk/dna-repository/src/main/java/org/jboss/dna/repository/federation/FederatedNode.java
(rev 0)
+++
trunk/dna-repository/src/main/java/org/jboss/dna/repository/federation/FederatedNode.java 2008-06-30
21:45:21 UTC (rev 321)
@@ -0,0 +1,140 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2008, Red Hat Middleware LLC, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site:
http://www.fsf.org.
+ */
+package org.jboss.dna.repository.federation;
+
+import java.util.Iterator;
+import java.util.Set;
+import java.util.UUID;
+import net.jcip.annotations.ThreadSafe;
+import org.jboss.dna.spi.graph.Name;
+import org.jboss.dna.spi.graph.Property;
+
+/**
+ * @author Randall Hauch
+ */
+@ThreadSafe
+public interface FederatedNode {
+ /**
+ * Get the unique identifier for this federated node.
+ *
+ * @return the UUID; never null
+ */
+ UUID getUuid();
+
+ /**
+ * Get the name of this node.
+ *
+ * @return the node name; never null
+ */
+ Name getName();
+
+ /**
+ * Get the property with the given name.
+ *
+ * @param propertyName the property name
+ * @return the property, or null if the property does not exist
+ * @throws IllegalArgumentException if the name is null
+ */
+ Property getProperty( Name propertyName );
+
+ /**
+ * Get the number of properties on this node. This value is technically an estimate,
as it may not exactly match the number of
+ * properties returned by {@link #getProperties()} or {@link #getPropertyNames()}.
+ *
+ * @return the approximate number of properties.
+ */
+ int getPropertyCount();
+
+ /**
+ * Get the properties. This method returns a consistent set of properties at the
moment this method is called, and is not
+ * affected by additions or change to the properties. In other words, it is safe for
concurrent operations and is not a
+ * fail-fast iterator.
+ *
+ * @return the properties on this node via an immutable iterator
+ */
+ Iterator<Property> getProperties();
+
+ /**
+ * Get the names of the properties for this node. This method returns a consistent
set of names at the moment this method is
+ * called, and is not affected by additions or change to the properties. In other
words, it is safe for concurrent operations
+ * and is not a fail-fast iterator.
+ *
+ * @return the property names via an immutable iterator
+ */
+ Iterator<Name> getPropertyNames();
+
+ /**
+ * Set the property if it is not already set.
+ *
+ * @param property the property
+ * @return the existing property, or null if there was no property and the supplied
property was set
+ * @throws IllegalArgumentException if the property is null
+ */
+ Property setPropertyIfAbsent( Property property );
+
+ /**
+ * Set the supplied properties. This method will overwrite any existing properties
with the new properties if they have the
+ * same {@link Property#getName() property name}. This method ignores any null
property references, and does nothing if there
+ * are no properties supplied.
+ *
+ * @param properties the properties that should be set
+ */
+ void setProperties( Property... properties );
+
+ /**
+ * Set the supplied properties. This method will overwrite any existing properties
with the new properties if they have the
+ * same {@link Property#getName() property name}. This method ignores any null
property references, and does nothing if there
+ * are no properties supplied.
+ *
+ * @param properties the properties that should be set
+ */
+ void setProperties( Iterable<Property> properties );
+
+ /**
+ * Replace all existing properties with the supplied properties. This method ignores
any null property references, and does
+ * nothing if there are no properties supplied.
+ *
+ * @param properties the properties that should be set
+ */
+ void setAllProperties( Property... properties );
+
+ /**
+ * Replace all existing properties with the supplied properties. This method ignores
any null property references, and does
+ * nothing if there are no properties supplied.
+ *
+ * @param properties the properties that should replace the existing properties
+ */
+ void setAllProperties( Iterable<Property> properties );
+
+ /**
+ * Remove all properties, except for the {@link #getName() name} and {@link
#getUuid() identifier}.
+ */
+ void removeAllProperties();
+
+ /**
+ * Get the sources that have contributed information to this node.
+ *
+ * @return the names of the sources that have contributed content to this node.
+ */
+ Set<String> getContributingSources();
+
+}
Added:
trunk/dna-repository/src/main/java/org/jboss/dna/repository/federation/FederatedRegion.java
===================================================================
---
trunk/dna-repository/src/main/java/org/jboss/dna/repository/federation/FederatedRegion.java
(rev 0)
+++
trunk/dna-repository/src/main/java/org/jboss/dna/repository/federation/FederatedRegion.java 2008-06-30
21:45:21 UTC (rev 321)
@@ -0,0 +1,188 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2008, Red Hat Middleware LLC, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site:
http://www.fsf.org.
+ */
+package org.jboss.dna.repository.federation;
+
+import net.jcip.annotations.Immutable;
+import org.jboss.dna.common.util.ArgCheck;
+import org.jboss.dna.repository.RepositoryI18n;
+import org.jboss.dna.spi.graph.Path;
+import org.jboss.dna.spi.graph.PathFactory;
+
+/**
+ * A binding of content from a source into a particular location within a repository. The
content in the source is defined by the
+ * name of the source and the {@link #getPathInSource() path within the source}. The
{@link #getPathInRepository() path in the
+ * repository} defines the location at which the content appears.
+ * <p>
+ * Note that it is possible for a federated repository to have a single source may be
bound to multiple locations, and multiple
+ * sources bound to the same location.
+ * </p>
+ *
+ * @author Randall Hauch
+ */
+@Immutable
+public class FederatedRegion implements Comparable<FederatedRegion> {
+
+ private final Path pathInRepository;
+ private final Path pathInSource;
+ private final String sourceName;
+
+ /**
+ * Create a binding given a location in the repository below which the content from
the named source appears.
+ *
+ * @param pathInRepository the absolute path in the repository at which the content
appears
+ * @param pathInSource the path in the source defining the content
+ * @param sourceName the name of the source
+ * @throws IllegalArgumentException if any of the parameters is null, or if the
source name is empty/blank, or if the
+ * <code>pathInRepository</code> is not {@link Path#isAbsolute()
absolute}.
+ */
+ public FederatedRegion( Path pathInRepository,
+ Path pathInSource,
+ String sourceName ) {
+ ArgCheck.isNotNull(pathInRepository, "pathInRepository");
+ ArgCheck.isNotNull(pathInSource, "pathInSource");
+ ArgCheck.isNotEmpty(sourceName, "sourceName");
+ if (!pathInRepository.isAbsolute()) {
+ String msg =
RepositoryI18n.repositoryPathInFederationBindingIsNotAbsolute.text(pathInRepository.getString());
+ throw new IllegalArgumentException(msg);
+ }
+ this.pathInRepository = pathInRepository;
+ this.pathInSource = pathInSource;
+ this.sourceName = sourceName;
+ }
+
+ /**
+ * Get the location in the repository at which the source's content appears.
+ *
+ * @return the repository-based path for the top of the source's content
+ */
+ public Path getPathInRepository() {
+ return pathInRepository;
+ }
+
+ /**
+ * Get the path to the source content that is bound to the {@link
#getPathInRepository() repository location}. This path is
+ * source-specific, and may be either absolute or relative.
+ *
+ * @return pathInSource
+ */
+ public Path getPathInSource() {
+ return pathInSource;
+ }
+
+ /**
+ * @return sourceName
+ */
+ public String getSourceName() {
+ return sourceName;
+ }
+
+ /**
+ * Convert a path defined in the source system into an equivalent path in the
repository system.
+ *
+ * @param pathInSource the path in the source system, which may include the {@link
#getPathInSource()}
+ * @param factory the path factory; may not be null
+ * @return the path in the repository system, which will be normalized and absolute
(including the
+ * {@link #getPathInRepository()})
+ */
+ public Path convertPathInSourceToPathInRepository( Path pathInSource,
+ PathFactory factory ) {
+ Path relativeSourcePath = pathInSource;
+ if (this.pathInSource.isAncestorOf(pathInSource)) {
+ // Remove the leading source path ...
+ relativeSourcePath = pathInSource.relativeTo(this.pathInSource);
+ }
+ // Prepend the region's root path ...
+ Path result = factory.create(this.pathInRepository, relativeSourcePath);
+ return result.getNormalizedPath();
+ }
+
+ /**
+ * Convert a path defined in the repository system into an equivalent path in the
source system.
+ *
+ * @param pathInRepository the path in the repository system, which may include the
{@link #getPathInRepository()}
+ * @param factory the path factory; may not be null
+ * @return the path in the source system, which will be normalized and absolute
(including the {@link #getPathInSource()})
+ */
+ public Path convertPathInRepositoryToPathInSource( Path pathInRepository,
+ PathFactory factory ) {
+ Path pathInRegion = pathInRepository;
+ if (this.pathInRepository.isAncestorOf(pathInRepository)) {
+ // Find the relative path from the root of this region ...
+ pathInRegion = pathInRepository.relativeTo(this.pathInRepository);
+ }
+ // Prepend the path in source ...
+ Path result = factory.create(this.pathInSource, pathInRegion);
+ return result.getNormalizedPath();
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see java.lang.Object#hashCode()
+ */
+ @Override
+ public int hashCode() {
+ return pathInRepository.hashCode();
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see java.lang.Object#equals(java.lang.Object)
+ */
+ @Override
+ public boolean equals( Object obj ) {
+ if (obj == this) return true;
+ if (obj instanceof FederatedRegion) {
+ FederatedRegion that = (FederatedRegion)obj;
+ if (!this.getPathInRepository().equals(that.getPathInRepository())) return
false;
+ if (!this.getPathInSource().equals(that.getPathInSource())) return false;
+ if (!this.getSourceName().equals(that.getSourceName())) return false;
+ return true;
+ }
+ return false;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see java.lang.Comparable#compareTo(java.lang.Object)
+ */
+ public int compareTo( FederatedRegion that ) {
+ if (this == that) return 0;
+ int diff = this.getPathInRepository().compareTo(that.getPathInRepository());
+ if (diff != 0) return diff;
+ diff = this.getPathInSource().compareTo(that.getPathInSource());
+ if (diff != 0) return diff;
+ return this.getSourceName().compareTo(that.getSourceName());
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see java.lang.Object#toString()
+ */
+ @Override
+ public String toString() {
+ return this.getPathInRepository().toString() + " -> \"" +
this.getSourceName() + "\":" + this.getPathInSource();
+ }
+}
Added:
trunk/dna-repository/src/main/java/org/jboss/dna/repository/federation/RepositoryConnectionFactories.java
===================================================================
---
trunk/dna-repository/src/main/java/org/jboss/dna/repository/federation/RepositoryConnectionFactories.java
(rev 0)
+++
trunk/dna-repository/src/main/java/org/jboss/dna/repository/federation/RepositoryConnectionFactories.java 2008-06-30
21:45:21 UTC (rev 321)
@@ -0,0 +1,33 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2008, Red Hat Middleware LLC, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site:
http://www.fsf.org.
+ */
+package org.jboss.dna.repository.federation;
+
+import org.jboss.dna.spi.graph.connection.RepositoryConnectionFactory;
+
+/**
+ * @author Randall Hauch
+ */
+public interface RepositoryConnectionFactories {
+
+ RepositoryConnectionFactory getConnectionFactory( String sourceName );
+
+}
Added:
trunk/dna-repository/src/main/java/org/jboss/dna/repository/federation/RepositorySourceManager.java
===================================================================
---
trunk/dna-repository/src/main/java/org/jboss/dna/repository/federation/RepositorySourceManager.java
(rev 0)
+++
trunk/dna-repository/src/main/java/org/jboss/dna/repository/federation/RepositorySourceManager.java 2008-06-30
21:45:21 UTC (rev 321)
@@ -0,0 +1,341 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2008, Red Hat Middleware LLC, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site:
http://www.fsf.org.
+ */
+package org.jboss.dna.repository.federation;
+
+import java.util.Collection;
+import java.util.Collections;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentMap;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.locks.Lock;
+import java.util.concurrent.locks.ReentrantLock;
+import org.jboss.dna.repository.RepositoryI18n;
+import org.jboss.dna.repository.services.AbstractServiceAdministrator;
+import org.jboss.dna.repository.services.ServiceAdministrator;
+import org.jboss.dna.spi.graph.connection.RepositoryConnection;
+import org.jboss.dna.spi.graph.connection.RepositoryConnectionFactory;
+import org.jboss.dna.spi.graph.connection.RepositoryConnectionPool;
+import org.jboss.dna.spi.graph.connection.RepositorySource;
+
+/**
+ * @author Randall Hauch
+ */
+public class RepositorySourceManager implements RepositoryConnectionFactories {
+
+ /**
+ * The administrative component for this service.
+ *
+ * @author Randall Hauch
+ */
+ protected class Administrator extends AbstractServiceAdministrator {
+
+ protected Administrator() {
+ super(RepositoryI18n.federationServiceName, State.STARTED);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ protected void doStart( State fromState ) {
+ super.doStart(fromState);
+ RepositorySourceManager.this.start();
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ protected void doShutdown( State fromState ) {
+ super.doShutdown(fromState);
+ RepositorySourceManager.this.shutdown();
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public boolean awaitTermination( long timeout,
+ TimeUnit unit ) throws InterruptedException {
+ return RepositorySourceManager.this.awaitTermination(timeout, unit);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ protected boolean doCheckIsTerminated() {
+ return RepositorySourceManager.this.isTerminated();
+ }
+
+ }
+
+ private final ServiceAdministrator administrator = new Administrator();
+ private final Lock sourcesWriteLock = new ReentrantLock();
+ private final ConcurrentMap<String, RepositorySource> sources = new
ConcurrentHashMap<String, RepositorySource>();
+ private RepositoryConnectionFactories delegate;
+
+ /**
+ * Create a new manager instance.
+ *
+ * @param delegate the factories object that this instance should delegate to in the
event that a source is not found in this
+ * manager; may be null if there is no delegate
+ */
+ public RepositorySourceManager( RepositoryConnectionFactories delegate ) {
+ this.delegate = delegate;
+ }
+
+ /**
+ * @return delegate
+ */
+ public RepositoryConnectionFactories getDelegate() {
+ return delegate;
+ }
+
+ /**
+ * @param delegate Sets delegate to the specified value.
+ */
+ public void setDelegate( RepositoryConnectionFactories delegate ) {
+ this.delegate = delegate;
+ }
+
+ /**
+ * @return administrator
+ */
+ public ServiceAdministrator getAdministrator() {
+ return this.administrator;
+ }
+
+ /**
+ * Utility method called by the administrator.
+ */
+ protected void start() {
+ // Do not establish connections to the sources; these will be established as
needed
+
+ }
+
+ /**
+ * Utility method called by the administrator.
+ */
+ protected void shutdown() {
+ // Close all connections to the sources. This is done inside the sources write
lock.
+ try {
+ this.sourcesWriteLock.lock();
+ for (RepositorySource source : this.sources.values()) {
+ if (source instanceof RepositoryConnectionPool) {
+ RepositoryConnectionPool pool = (RepositoryConnectionPool)source;
+ pool.shutdown();
+ }
+ }
+ } finally {
+ this.sourcesWriteLock.unlock();
+ }
+ }
+
+ /**
+ * Utility method called by the administrator.
+ *
+ * @param timeout
+ * @param unit
+ * @return true if all pools were terminated in the supplied time (or were already
terminated), or false if the timeout
+ * occurred before all the connections were closed
+ * @throws InterruptedException
+ */
+ protected boolean awaitTermination( long timeout,
+ TimeUnit unit ) throws InterruptedException {
+ // Check whether all source pools are shut down. This is done inside the sources
write lock.
+ try {
+ this.sourcesWriteLock.lock();
+ for (RepositorySource source : this.sources.values()) {
+ if (source instanceof RepositoryConnectionPool) {
+ RepositoryConnectionPool pool = (RepositoryConnectionPool)source;
+ if (!pool.awaitTermination(timeout, unit)) {
+ return false;
+ }
+ }
+ }
+ return true;
+ } finally {
+ this.sourcesWriteLock.unlock();
+ }
+ }
+
+ /**
+ * Returns true if this federated repository is in the process of terminating after
{@link ServiceAdministrator#shutdown()}
+ * has been called on the {@link #getAdministrator() administrator}, but the
federated repository has connections that have
+ * not yet normally been {@link RepositoryConnection#close() closed}. This method may
be useful for debugging. A return of
+ * <tt>true</tt> reported a sufficient period after shutdown may indicate
that connection users have ignored or suppressed
+ * interruption, causing this repository not to properly terminate.
+ *
+ * @return true if terminating but not yet terminated, or false otherwise
+ * @see #isTerminated()
+ */
+ public boolean isTerminating() {
+ try {
+ this.sourcesWriteLock.lock();
+ for (RepositorySource source : this.sources.values()) {
+ if (source instanceof RepositoryConnectionPool) {
+ RepositoryConnectionPool pool = (RepositoryConnectionPool)source;
+ if (pool.isTerminating()) {
+ return true;
+ }
+ }
+ }
+ return false;
+ } finally {
+ this.sourcesWriteLock.unlock();
+ }
+ }
+
+ /**
+ * Return true if this federated repository has completed its termination and no
longer has any open connections.
+ *
+ * @return true if terminated, or false otherwise
+ * @see #isTerminating()
+ */
+ public boolean isTerminated() {
+ try {
+ this.sourcesWriteLock.lock();
+ for (RepositorySource source : this.sources.values()) {
+ if (source instanceof RepositoryConnectionPool) {
+ RepositoryConnectionPool pool = (RepositoryConnectionPool)source;
+ if (!pool.isTerminated()) {
+ return false;
+ }
+ }
+ }
+ return true;
+ } finally {
+ this.sourcesWriteLock.unlock();
+ }
+ }
+
+ /**
+ * Get an unmodifiable collection of {@link RepositorySource federated sources}.
+ * <p>
+ * This method can safely be called while the federation repository is in use.
+ * </p>
+ *
+ * @return the sources
+ */
+ public Collection<RepositorySource> getSources() {
+ return Collections.unmodifiableCollection(this.sources.values());
+ }
+
+ /**
+ * Add the supplied federated source. This method returns false if the source is
null.
+ * <p>
+ * This method can safely be called while the federation repository is in use.
+ * </p>
+ *
+ * @param source the source to add
+ * @return true if the source is added, or false if the reference is null or if there
is already an existing source with the
+ * supplied name.
+ */
+ public boolean addSource( RepositorySource source ) {
+ if (source == null) return false;
+ try {
+ this.sourcesWriteLock.lock();
+ for (RepositorySource existingSource : this.sources.values()) {
+ if (existingSource.getName().equals(source.getName())) return false;
+ }
+ this.sources.put(source.getName(), source);
+ } finally {
+ this.sourcesWriteLock.unlock();
+ }
+ return true;
+ }
+
+ /**
+ * Remove from this federated repository the supplied source (or a source with the
same name as that supplied). This call
+ * shuts down the connections in the source in an orderly fashion, allowing those
connection currently in use to be used and
+ * closed normally, but preventing further connections from being used.
+ * <p>
+ * This method can safely be called while the federation repository is in use.
+ * </p>
+ *
+ * @param source the source to be removed
+ * @param timeToAwait the amount of time to wait while all of the source's
connections are closed, or non-positive if the call
+ * should not wait at all
+ * @param unit the time unit to be used for <code>timeToAwait</code>
+ * @return true if the source was removed, or false if the source was not a source
for this repository.
+ * @throws InterruptedException if the thread is interrupted while awaiting closing
of the connections
+ */
+ public boolean removeSource( RepositorySource source,
+ long timeToAwait,
+ TimeUnit unit ) throws InterruptedException {
+ // Use the name; don't use the object equality ...
+ return removeSource(source.getName(), timeToAwait, unit) != null;
+ }
+
+ /**
+ * Remove from this federated repository the source with the supplied name. This call
shuts down the connections in the source
+ * in an orderly fashion, allowing those connection currently in use to be used and
closed normally, but preventing further
+ * connections from being used.
+ * <p>
+ * This method can safely be called while the federation repository is in use.
+ * </p>
+ *
+ * @param name the name of the source to be removed
+ * @param timeToAwait the amount of time to wait while all of the source's
connections are closed, or non-positive if the call
+ * should not wait at all
+ * @param unit the time unit to be used for <code>timeToAwait</code>
+ * @return the source with the supplied name that was removed, or null if no existing
source matching the supplied name could
+ * be found
+ * @throws InterruptedException if the thread is interrupted while awaiting closing
of the connections
+ */
+ public RepositorySource removeSource( String name,
+ long timeToAwait,
+ TimeUnit unit ) throws InterruptedException {
+ try {
+ this.sourcesWriteLock.lock();
+ RepositorySource existingSource = this.sources.remove(name);
+ if (existingSource != null) {
+ // Shut down the connection pool if it is one ...
+ if (existingSource instanceof RepositoryConnectionPool) {
+ RepositoryConnectionPool pool =
(RepositoryConnectionPool)existingSource;
+ pool.shutdown();
+ if (timeToAwait > 0l) pool.awaitTermination(timeToAwait, unit);
+ }
+ }
+ return existingSource;
+ } finally {
+ this.sourcesWriteLock.unlock();
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see
org.jboss.dna.repository.federation.RepositoryConnectionFactories#getConnectionFactory(java.lang.String)
+ */
+ public RepositoryConnectionFactory getConnectionFactory( String sourceName ) {
+ RepositoryConnectionFactory result = this.sources.get(sourceName);
+ if (result == null) {
+ RepositoryConnectionFactories delegate = this.delegate;
+ if (delegate != null) {
+ result = delegate.getConnectionFactory(sourceName);
+ }
+ }
+ return result;
+ }
+
+}
Added:
trunk/dna-repository/src/test/java/org/jboss/dna/repository/federation/FederationServiceTest.java
===================================================================
---
trunk/dna-repository/src/test/java/org/jboss/dna/repository/federation/FederationServiceTest.java
(rev 0)
+++
trunk/dna-repository/src/test/java/org/jboss/dna/repository/federation/FederationServiceTest.java 2008-06-30
21:45:21 UTC (rev 321)
@@ -0,0 +1,87 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2008, Red Hat Middleware LLC, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site:
http://www.fsf.org.
+ */
+package org.jboss.dna.repository.federation;
+
+import static org.hamcrest.core.Is.is;
+import static org.hamcrest.core.IsNull.notNullValue;
+import static org.hamcrest.core.IsSame.sameInstance;
+import static org.junit.Assert.assertThat;
+import static org.mockito.Mockito.stub;
+import org.jboss.dna.repository.util.ExecutionContext;
+import org.jboss.dna.spi.graph.Path;
+import org.jboss.dna.spi.graph.PathFactory;
+import org.jboss.dna.spi.graph.impl.BasicNamespaceRegistry;
+import org.jboss.dna.spi.graph.impl.StandardValueFactories;
+import org.junit.Before;
+import org.junit.Ignore;
+import org.junit.Test;
+import org.mockito.MockitoAnnotations;
+import org.mockito.MockitoAnnotations.Mock;
+
+/**
+ * @author Randall Hauch
+ */
+public class FederationServiceTest {
+
+ private FederationService service;
+ private FederatedRegion configRegion;
+ private StandardValueFactories valueFactories;
+ private PathFactory pathFactory;
+ private String configSourceName;
+ @Mock
+ private ExecutionContext env;
+ @Mock
+ private RepositorySourceManager sources;
+
+ @Before
+ public void beforeEach() throws Exception {
+ MockitoAnnotations.initMocks(this);
+ configSourceName = "configSource";
+ valueFactories = new StandardValueFactories(new BasicNamespaceRegistry());
+ pathFactory = valueFactories.getPathFactory();
+ Path pathInRepository = pathFactory.create("/dna:system");
+ Path pathInSource = pathFactory.create("/some/root");
+ configRegion = new FederatedRegion(pathInRepository, pathInSource,
configSourceName);
+ stub(env.getValueFactories()).toReturn(valueFactories);
+ service = new FederationService(sources, configRegion, env, null);
+ }
+
+ @Ignore
+ @Test
+ public void shouldHaveServiceAdministratorAfterInstantiation() {
+ assertThat(service.getAdministrator(), is(notNullValue()));
+ }
+
+ @Ignore
+ @Test
+ public void shouldHaveConfigurationRegionAfterInstantiation() {
+ assertThat(service.getConfigurationRegion(), is(notNullValue()));
+ assertThat(service.getConfigurationRegion(), is(sameInstance(configRegion)));
+ }
+
+ @Ignore
+ @Test
+ public void
shouldHaveNonNullClassLoaderFactoryAfterInstantiatingWithNullClassLoaderFactoryReference()
{
+ assertThat(service.getClassLoaderFactory(), is(notNullValue()));
+ }
+
+}
Added:
trunk/dna-spi/src/main/java/org/jboss/dna/spi/graph/commands/impl/BasicCompositeCommand.java
===================================================================
---
trunk/dna-spi/src/main/java/org/jboss/dna/spi/graph/commands/impl/BasicCompositeCommand.java
(rev 0)
+++
trunk/dna-spi/src/main/java/org/jboss/dna/spi/graph/commands/impl/BasicCompositeCommand.java 2008-06-30
21:45:21 UTC (rev 321)
@@ -0,0 +1,71 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2008, Red Hat Middleware LLC, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site:
http://www.fsf.org.
+ */
+package org.jboss.dna.spi.graph.commands.impl;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+import org.jboss.dna.spi.graph.commands.CompositeCommand;
+import org.jboss.dna.spi.graph.commands.GraphCommand;
+
+/**
+ * @author Randall Hauch
+ */
+public class BasicCompositeCommand extends BasicGraphCommand implements CompositeCommand
{
+
+ private final List<GraphCommand> commands = new
ArrayList<GraphCommand>();
+
+ public BasicCompositeCommand() {
+ super();
+ }
+
+ public boolean isEmpty() {
+ return commands.isEmpty();
+ }
+
+ public int size() {
+ return commands.size();
+ }
+
+ public void add( GraphCommand command ) {
+ if (command != null) commands.add(command);
+ }
+
+ public GraphCommand getCommand( int index ) {
+ return commands.get(index);
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see java.lang.Iterable#iterator()
+ */
+ public Iterator<GraphCommand> iterator() {
+ return commands.iterator();
+ }
+
+ public BasicCompositeCommand clearCommands() {
+ this.commands.clear();
+ return this;
+ }
+
+}
Added:
trunk/dna-spi/src/main/java/org/jboss/dna/spi/graph/connection/BasicExecutionEnvironment.java
===================================================================
---
trunk/dna-spi/src/main/java/org/jboss/dna/spi/graph/connection/BasicExecutionEnvironment.java
(rev 0)
+++
trunk/dna-spi/src/main/java/org/jboss/dna/spi/graph/connection/BasicExecutionEnvironment.java 2008-06-30
21:45:21 UTC (rev 321)
@@ -0,0 +1,78 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2008, Red Hat Middleware LLC, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site:
http://www.fsf.org.
+ */
+package org.jboss.dna.spi.graph.connection;
+
+import org.jboss.dna.common.util.ArgCheck;
+import org.jboss.dna.spi.graph.NamespaceRegistry;
+import org.jboss.dna.spi.graph.PropertyFactory;
+import org.jboss.dna.spi.graph.ValueFactories;
+import org.jboss.dna.spi.graph.impl.BasicNamespaceRegistry;
+import org.jboss.dna.spi.graph.impl.BasicPropertyFactory;
+import org.jboss.dna.spi.graph.impl.StandardValueFactories;
+
+/**
+ * @author Randall Hauch
+ */
+public class BasicExecutionEnvironment implements ExecutionEnvironment {
+
+ private final PropertyFactory propertyFactory;
+ private final ValueFactories valueFactories;
+ private final NamespaceRegistry namespaceRegistry;
+
+ public BasicExecutionEnvironment() {
+ this(new BasicNamespaceRegistry());
+ }
+
+ public BasicExecutionEnvironment( NamespaceRegistry namespaceRegistry ) {
+ this(namespaceRegistry, null, null);
+ }
+
+ public BasicExecutionEnvironment( NamespaceRegistry namespaceRegistry,
+ ValueFactories valueFactories,
+ PropertyFactory propertyFactory ) {
+ ArgCheck.isNotNull(namespaceRegistry, "namespace registry");
+ this.namespaceRegistry = namespaceRegistry;
+ this.valueFactories = valueFactories != null ? valueFactories : new
StandardValueFactories(this.namespaceRegistry);
+ this.propertyFactory = propertyFactory != null ? propertyFactory : new
BasicPropertyFactory(this.valueFactories);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public NamespaceRegistry getNamespaceRegistry() {
+ return this.namespaceRegistry;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public ValueFactories getValueFactories() {
+ return this.valueFactories;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public PropertyFactory getPropertyFactory() {
+ return this.propertyFactory;
+ }
+}
Added:
trunk/dna-spi/src/main/java/org/jboss/dna/spi/graph/connection/ExecutionEnvironments.java
===================================================================
---
trunk/dna-spi/src/main/java/org/jboss/dna/spi/graph/connection/ExecutionEnvironments.java
(rev 0)
+++
trunk/dna-spi/src/main/java/org/jboss/dna/spi/graph/connection/ExecutionEnvironments.java 2008-06-30
21:45:21 UTC (rev 321)
@@ -0,0 +1,184 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2008, Red Hat Middleware LLC, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site:
http://www.fsf.org.
+ */
+package org.jboss.dna.spi.graph.connection;
+
+import org.jboss.dna.common.util.ArgCheck;
+import org.jboss.dna.spi.graph.NameFactory;
+import org.jboss.dna.spi.graph.NamespaceRegistry;
+import org.jboss.dna.spi.graph.PathFactory;
+import org.jboss.dna.spi.graph.PropertyFactory;
+import org.jboss.dna.spi.graph.ValueFactories;
+import org.jboss.dna.spi.graph.impl.DelegatingValueFactories;
+
+/**
+ * Utility methods for creating various execution environments with replacement factories
or components.
+ *
+ * @author Randall Hauch
+ */
+public class ExecutionEnvironments {
+
+ /**
+ * Create an environment that can be used to replace the supplied environment but
that uses the supplied path factory.
+ *
+ * @param env the base environment
+ * @param pathFactory the new path factory
+ * @return the new execution environment
+ * @throws IllegalArgumentException if the environment or factory references are
null
+ */
+ public static ExecutionEnvironment replace( ExecutionEnvironment env,
+ PathFactory pathFactory ) {
+ ArgCheck.isNotNull(env, "env");
+ ArgCheck.isNotNull(pathFactory, "pathFactory");
+ return new DelegatingExecutionEnvironment(env, null, null, null, pathFactory);
+ }
+
+ /**
+ * Create an environment that can be used to replace the supplied environment but
that uses the supplied name factory.
+ *
+ * @param env the base environment
+ * @param nameFactory the new name factory
+ * @return the new execution environment
+ * @throws IllegalArgumentException if the environment or factory references are
null
+ */
+ public static ExecutionEnvironment replace( ExecutionEnvironment env,
+ NameFactory nameFactory ) {
+ ArgCheck.isNotNull(env, "env");
+ ArgCheck.isNotNull(nameFactory, "nameFactory");
+ return new DelegatingExecutionEnvironment(env, null, null, nameFactory, null);
+ }
+
+ /**
+ * Create an environment that can be used to replace the supplied environment but
that uses the supplied name and path
+ * factories.
+ *
+ * @param env the base environment
+ * @param nameFactory the new name factory
+ * @param pathFactory the new path factory
+ * @return the new execution environment
+ * @throws IllegalArgumentException if the environment or factory references are
null
+ */
+ public static ExecutionEnvironment replace( ExecutionEnvironment env,
+ NameFactory nameFactory,
+ PathFactory pathFactory ) {
+ ArgCheck.isNotNull(env, "env");
+ ArgCheck.isNotNull(nameFactory, "nameFactory");
+ ArgCheck.isNotNull(pathFactory, "pathFactory");
+ return new DelegatingExecutionEnvironment(env, null, null, nameFactory,
pathFactory);
+ }
+
+ /**
+ * Create an environment that can be used to replace the supplied environment but
that uses the supplied namespace registry.
+ *
+ * @param env the base environment
+ * @param namespaceRegistry the new namespace registry
+ * @return the new execution environment
+ * @throws IllegalArgumentException if the environment or registry references are
null
+ */
+ public static ExecutionEnvironment replace( ExecutionEnvironment env,
+ NamespaceRegistry namespaceRegistry ) {
+ ArgCheck.isNotNull(env, "env");
+ ArgCheck.isNotNull(namespaceRegistry, "namespaceRegistry");
+ return new DelegatingExecutionEnvironment(env, namespaceRegistry, null, null,
null);
+ }
+
+ protected static class DelegatingExecutionEnvironment implements ExecutionEnvironment
{
+
+ private final ExecutionEnvironment delegate;
+ private final NamespaceRegistry newNamespaceRegistry;
+ private final PropertyFactory newPropertyFactory;
+ private final ValueFactories newValueFactories;
+
+ public DelegatingExecutionEnvironment( ExecutionEnvironment delegate,
+ NamespaceRegistry newRegistry,
+ PropertyFactory newPropertyFactory,
+ ValueFactories newValueFactories ) {
+ assert delegate != null;
+ this.delegate = delegate;
+ this.newNamespaceRegistry = newRegistry;
+ this.newPropertyFactory = newPropertyFactory;
+ this.newValueFactories = newValueFactories;
+ }
+
+ public DelegatingExecutionEnvironment( ExecutionEnvironment delegate,
+ NamespaceRegistry newRegistry,
+ PropertyFactory newPropertyFactory,
+ final NameFactory newNameFactory,
+ final PathFactory newPathFactory ) {
+ assert delegate != null;
+ this.delegate = delegate;
+ this.newNamespaceRegistry = newRegistry;
+ this.newPropertyFactory = newPropertyFactory;
+ final PathFactory pathFactory = newPathFactory != null ? newPathFactory :
delegate.getValueFactories().getPathFactory();
+ final NameFactory nameFactory = newNameFactory != null ? newNameFactory :
delegate.getValueFactories().getNameFactory();
+ this.newValueFactories = newPathFactory == null ? null : new
DelegatingValueFactories(delegate.getValueFactories()) {
+
+ @Override
+ public PathFactory getPathFactory() {
+ return pathFactory;
+ }
+
+ @Override
+ public NameFactory getNameFactory() {
+ return nameFactory;
+ }
+ };
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see
org.jboss.dna.spi.graph.connection.ExecutionEnvironment#getNamespaceRegistry()
+ */
+ public NamespaceRegistry getNamespaceRegistry() {
+ if (newNamespaceRegistry != null) return newNamespaceRegistry;
+ return delegate.getNamespaceRegistry();
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see
org.jboss.dna.spi.graph.connection.ExecutionEnvironment#getPropertyFactory()
+ */
+ public PropertyFactory getPropertyFactory() {
+ if (newPropertyFactory != null) return newPropertyFactory;
+ return delegate.getPropertyFactory();
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see
org.jboss.dna.spi.graph.connection.ExecutionEnvironment#getValueFactories()
+ */
+ public ValueFactories getValueFactories() {
+ if (newValueFactories != null) return newValueFactories;
+ return delegate.getValueFactories();
+ }
+
+ /**
+ * @return delegate
+ */
+ protected ExecutionEnvironment getDelegate() {
+ return delegate;
+ }
+
+ }
+}
Added:
trunk/dna-spi/src/main/java/org/jboss/dna/spi/graph/connection/RepositoryConnectionPool.java
===================================================================
---
trunk/dna-spi/src/main/java/org/jboss/dna/spi/graph/connection/RepositoryConnectionPool.java
(rev 0)
+++
trunk/dna-spi/src/main/java/org/jboss/dna/spi/graph/connection/RepositoryConnectionPool.java 2008-06-30
21:45:21 UTC (rev 321)
@@ -0,0 +1,111 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2008, Red Hat Middleware LLC, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site:
http://www.fsf.org.
+ */
+package org.jboss.dna.spi.graph.connection;
+
+import java.util.concurrent.TimeUnit;
+
+/**
+ * @author Randall Hauch
+ */
+public interface RepositoryConnectionPool extends RepositoryConnectionFactory {
+
+ /**
+ * Initiates an orderly shutdown in which connections that are currently in use are
allowed to be used and closed as normal,
+ * but no new connections will be created. Invocation has no additional effect if
already shut down.
+ * <p>
+ * Once the pool has been shutdown, it may not be used to {@link #getConnection() get
connections}.
+ * </p>
+ *
+ * @throws SecurityException if a security manager exists and shutting down this pool
may manipulate threads that the caller
+ * is not permitted to modify because it does not hold {@link
java.lang.RuntimePermission}<tt>("modifyThread")</tt>,
+ * or the security manager's <tt>checkAccess</tt> method
denies access.
+ * @see #shutdownNow()
+ */
+ void shutdown();
+
+ /**
+ * Attempts to close all connections, including those connections currently in use,
and prevent the use of other connections.
+ *
+ * @throws SecurityException if a security manager exists and shutting down this pool
may manipulate threads that the caller
+ * is not permitted to modify because it does not hold {@link
java.lang.RuntimePermission}<tt>("modifyThread")</tt>,
+ * or the security manager's <tt>checkAccess</tt> method
denies access.
+ * @see #shutdown()
+ */
+ void shutdownNow();
+
+ /**
+ * Return whether this connection pool is running and is able to {@link
#getConnection() provide connections}. Note that this
+ * method is effectively <code>!isShutdown()</code>.
+ *
+ * @return true if this pool is running, or false otherwise
+ * @see #isShutdown()
+ * @see #isTerminated()
+ * @see #isTerminating()
+ */
+ boolean isRunning();
+
+ /**
+ * Return whether this connection pool is in the process of shutting down or has
already been shut down. A result of
+ * <code>true</code> signals that the pool may no longer be used. Note
that this method is effectively
+ * <code>!isRunning()</code>.
+ *
+ * @return true if this pool has been shut down, or false otherwise
+ * @see #isShutdown()
+ * @see #isTerminated()
+ * @see #isTerminating()
+ */
+ boolean isShutdown();
+
+ /**
+ * Returns true if this pool is in the process of terminating after {@link
#shutdown()} or {@link #shutdownNow()} has been
+ * called but has not completely terminated. This method may be useful for debugging.
A return of <tt>true</tt> reported a
+ * sufficient period after shutdown may indicate that submitted tasks have ignored or
suppressed interruption, causing this
+ * executor not to properly terminate.
+ *
+ * @return true if terminating but not yet terminated, or false otherwise
+ * @see #isTerminated()
+ */
+ boolean isTerminating();
+
+ /**
+ * Return true if this pool has completed its termination and no longer has any open
connections.
+ *
+ * @return true if terminated, or false otherwise
+ * @see #isTerminating()
+ */
+ boolean isTerminated();
+
+ /**
+ * Method that can be called after {@link #shutdown()} or {@link #shutdownNow()} to
wait until all connections in use at the
+ * time those methods were called have been closed normally. This method accepts a
maximum time duration, after which it will
+ * return even if all connections have not been closed.
+ *
+ * @param timeout the maximum time to wait for all connections to be closed and
returned to the pool
+ * @param unit the time unit for <code>timeout</code>
+ * @return true if the pool was terminated in the supplied time (or was already
terminated), or false if the timeout occurred
+ * before all the connections were closed
+ * @throws InterruptedException if the thread was interrupted
+ */
+ boolean awaitTermination( long timeout,
+ TimeUnit unit ) throws InterruptedException;
+
+}
Added:
trunk/dna-spi/src/main/java/org/jboss/dna/spi/graph/impl/AbstractValueFactories.java
===================================================================
--- trunk/dna-spi/src/main/java/org/jboss/dna/spi/graph/impl/AbstractValueFactories.java
(rev 0)
+++
trunk/dna-spi/src/main/java/org/jboss/dna/spi/graph/impl/AbstractValueFactories.java 2008-06-30
21:45:21 UTC (rev 321)
@@ -0,0 +1,130 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2008, Red Hat Middleware LLC, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site:
http://www.fsf.org.
+ */
+package org.jboss.dna.spi.graph.impl;
+
+import java.util.Iterator;
+import org.jboss.dna.common.util.ArgCheck;
+import org.jboss.dna.spi.graph.PropertyType;
+import org.jboss.dna.spi.graph.ValueFactories;
+import org.jboss.dna.spi.graph.ValueFactory;
+
+/**
+ * Abstract implementation of {@link ValueFactories} that implements all the methods
other than the <code>get*Factory()</code>
+ * methods. Subclasses can simply implement these methods and inherit the {@link
#iterator()}, {@link #getValueFactory(Object)}
+ * and {@link #getValueFactory(PropertyType)} method implementations.
+ *
+ * @author Randall Hauch
+ */
+public abstract class AbstractValueFactories implements ValueFactories {
+
+ /**
+ * <p>
+ * {@inheritDoc}
+ * </p>
+ * <p>
+ * This implementation always iterates over the instances return by the
<code>get*Factory()</code> methods.
+ * </p>
+ */
+ public Iterator<ValueFactory<?>> iterator() {
+ return new ValueFactoryIterator();
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public ValueFactory<?> getValueFactory( PropertyType type ) {
+ ArgCheck.isNotNull(type, "type");
+ switch (type) {
+ case BINARY:
+ return getBinaryFactory();
+ case BOOLEAN:
+ return getBooleanFactory();
+ case DATE:
+ return getDateFactory();
+ case DECIMAL:
+ return getDecimalFactory();
+ case DOUBLE:
+ return getDoubleFactory();
+ case LONG:
+ return getLongFactory();
+ case NAME:
+ return getNameFactory();
+ case OBJECT:
+ return getObjectFactory();
+ case PATH:
+ return getPathFactory();
+ case REFERENCE:
+ return getReferenceFactory();
+ case STRING:
+ return getStringFactory();
+ case URI:
+ return getUriFactory();
+ }
+ return getObjectFactory();
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public ValueFactory<?> getValueFactory( Object prototype ) {
+ ArgCheck.isNotNull(prototype, "prototype");
+ PropertyType inferredType = PropertyType.discoverType(prototype);
+ assert inferredType != null;
+ return getValueFactory(inferredType);
+ }
+
+ protected class ValueFactoryIterator implements Iterator<ValueFactory<?>>
{
+ private final Iterator<PropertyType> propertyTypeIter =
PropertyType.iterator();
+
+ protected ValueFactoryIterator() {
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see java.util.Iterator#hasNext()
+ */
+ public boolean hasNext() {
+ return propertyTypeIter.hasNext();
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see java.util.Iterator#next()
+ */
+ public ValueFactory<?> next() {
+ PropertyType nextType = propertyTypeIter.next();
+ return getValueFactory(nextType);
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see java.util.Iterator#remove()
+ */
+ public void remove() {
+ throw new UnsupportedOperationException();
+ }
+ }
+
+}
Added:
trunk/dna-spi/src/main/java/org/jboss/dna/spi/graph/impl/DelegatingValueFactories.java
===================================================================
---
trunk/dna-spi/src/main/java/org/jboss/dna/spi/graph/impl/DelegatingValueFactories.java
(rev 0)
+++
trunk/dna-spi/src/main/java/org/jboss/dna/spi/graph/impl/DelegatingValueFactories.java 2008-06-30
21:45:21 UTC (rev 321)
@@ -0,0 +1,94 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2008, Red Hat Middleware LLC, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site:
http://www.fsf.org.
+ */
+package org.jboss.dna.spi.graph.impl;
+
+import java.math.BigDecimal;
+import java.net.URI;
+import org.jboss.dna.spi.graph.Binary;
+import org.jboss.dna.spi.graph.DateTimeFactory;
+import org.jboss.dna.spi.graph.NameFactory;
+import org.jboss.dna.spi.graph.PathFactory;
+import org.jboss.dna.spi.graph.Reference;
+import org.jboss.dna.spi.graph.ValueFactories;
+import org.jboss.dna.spi.graph.ValueFactory;
+
+/**
+ * @author Randall Hauch
+ */
+public class DelegatingValueFactories extends AbstractValueFactories {
+
+ private final ValueFactories delegate;
+
+ protected DelegatingValueFactories( ValueFactories delegate ) {
+ assert delegate != null;
+ this.delegate = delegate;
+ }
+
+ public ValueFactory<Binary> getBinaryFactory() {
+ return delegate.getBinaryFactory();
+ }
+
+ public ValueFactory<Boolean> getBooleanFactory() {
+ return delegate.getBooleanFactory();
+ }
+
+ public DateTimeFactory getDateFactory() {
+ return delegate.getDateFactory();
+ }
+
+ public ValueFactory<BigDecimal> getDecimalFactory() {
+ return delegate.getDecimalFactory();
+ }
+
+ public ValueFactory<Double> getDoubleFactory() {
+ return delegate.getDoubleFactory();
+ }
+
+ public ValueFactory<Long> getLongFactory() {
+ return delegate.getLongFactory();
+ }
+
+ public NameFactory getNameFactory() {
+ return delegate.getNameFactory();
+ }
+
+ public ValueFactory<Object> getObjectFactory() {
+ return delegate.getObjectFactory();
+ }
+
+ public PathFactory getPathFactory() {
+ return delegate.getPathFactory();
+ }
+
+ public ValueFactory<Reference> getReferenceFactory() {
+ return delegate.getReferenceFactory();
+ }
+
+ public ValueFactory<String> getStringFactory() {
+ return delegate.getStringFactory();
+ }
+
+ public ValueFactory<URI> getUriFactory() {
+ return delegate.getUriFactory();
+ }
+
+}