Author: rhauch
Date: 2009-05-19 13:40:25 -0400 (Tue, 19 May 2009)
New Revision: 912
Added:
trunk/dna-graph/src/main/java/org/jboss/dna/graph/observe/
trunk/dna-graph/src/main/java/org/jboss/dna/graph/observe/ChangeFeed.java
trunk/dna-graph/src/main/java/org/jboss/dna/graph/observe/ChangeObserver.java
trunk/dna-graph/src/main/java/org/jboss/dna/graph/observe/ChangeObservers.java
trunk/dna-graph/src/main/java/org/jboss/dna/graph/observe/ChangeTimeline.java
trunk/dna-graph/src/main/java/org/jboss/dna/graph/observe/Changes.java
trunk/dna-graph/src/main/java/org/jboss/dna/graph/observe/Observable.java
trunk/dna-graph/src/main/java/org/jboss/dna/graph/observe/package-info.java
Modified:
trunk/dna-graph/src/main/java/org/jboss/dna/graph/GraphI18n.java
trunk/dna-graph/src/main/java/org/jboss/dna/graph/connector/federation/ForkRequestProcessor.java
trunk/dna-graph/src/main/java/org/jboss/dna/graph/request/CacheableRequest.java
trunk/dna-graph/src/main/java/org/jboss/dna/graph/request/ChangeRequest.java
trunk/dna-graph/src/main/java/org/jboss/dna/graph/request/CloneWorkspaceRequest.java
trunk/dna-graph/src/main/java/org/jboss/dna/graph/request/CompositeRequest.java
trunk/dna-graph/src/main/java/org/jboss/dna/graph/request/CopyBranchRequest.java
trunk/dna-graph/src/main/java/org/jboss/dna/graph/request/CreateNodeRequest.java
trunk/dna-graph/src/main/java/org/jboss/dna/graph/request/CreateWorkspaceRequest.java
trunk/dna-graph/src/main/java/org/jboss/dna/graph/request/DeleteBranchRequest.java
trunk/dna-graph/src/main/java/org/jboss/dna/graph/request/DeleteChildrenRequest.java
trunk/dna-graph/src/main/java/org/jboss/dna/graph/request/GetWorkspacesRequest.java
trunk/dna-graph/src/main/java/org/jboss/dna/graph/request/MoveBranchRequest.java
trunk/dna-graph/src/main/java/org/jboss/dna/graph/request/ReadAllChildrenRequest.java
trunk/dna-graph/src/main/java/org/jboss/dna/graph/request/ReadAllPropertiesRequest.java
trunk/dna-graph/src/main/java/org/jboss/dna/graph/request/ReadBlockOfChildrenRequest.java
trunk/dna-graph/src/main/java/org/jboss/dna/graph/request/ReadBranchRequest.java
trunk/dna-graph/src/main/java/org/jboss/dna/graph/request/ReadNextBlockOfChildrenRequest.java
trunk/dna-graph/src/main/java/org/jboss/dna/graph/request/ReadNodeRequest.java
trunk/dna-graph/src/main/java/org/jboss/dna/graph/request/ReadPropertyRequest.java
trunk/dna-graph/src/main/java/org/jboss/dna/graph/request/RemovePropertyRequest.java
trunk/dna-graph/src/main/java/org/jboss/dna/graph/request/RenameNodeRequest.java
trunk/dna-graph/src/main/java/org/jboss/dna/graph/request/Request.java
trunk/dna-graph/src/main/java/org/jboss/dna/graph/request/SetPropertyRequest.java
trunk/dna-graph/src/main/java/org/jboss/dna/graph/request/UpdatePropertiesRequest.java
trunk/dna-graph/src/main/java/org/jboss/dna/graph/request/VerifyNodeExistsRequest.java
trunk/dna-graph/src/main/java/org/jboss/dna/graph/request/VerifyWorkspaceRequest.java
trunk/dna-graph/src/main/java/org/jboss/dna/graph/request/processor/RequestProcessor.java
trunk/dna-graph/src/main/resources/org/jboss/dna/graph/GraphI18n.properties
trunk/extensions/dna-connector-federation/src/main/java/org/jboss/dna/connector/federation/FederatingRequestProcessor.java
Log:
DNA-252 Complete event support in the connector API
Added initial version/proposal for events/observation in the JBoss DNA graph API into the
'org.jboss.dna.graph.observe' package. The framework consists of a ChangeObserver
abstract class (this is the listener); an Observable interface with which observers can be
registered and unregistered; a ChangeObservers class that provides a default Observable
implementation ready for use in other Observable implementations; a ChangeFeed interface
used to poll for changes during a specified timeline; a Changes class containing the
individual changes in an atomic operation and that is passed to the observers.
This design reuses the Request classes as the events, allowing for more advanced
observation (leverage the additional information in change requests, such as in
UpdatePropertiesRequest) as well as replaying events.
This commit adds the framework (including several thread-safe implementation classes), but
does not make use of the framework in the connector API or graph API. Those changes will
be coming subsequently.
Modified: trunk/dna-graph/src/main/java/org/jboss/dna/graph/GraphI18n.java
===================================================================
--- trunk/dna-graph/src/main/java/org/jboss/dna/graph/GraphI18n.java 2009-05-18 15:36:58
UTC (rev 911)
+++ trunk/dna-graph/src/main/java/org/jboss/dna/graph/GraphI18n.java 2009-05-19 17:40:25
UTC (rev 912)
@@ -84,6 +84,7 @@
public static I18n actualOldLocationMustHavePath;
public static I18n actualNewLocationMustHaveSameParentAsOldLocation;
public static I18n actualNewLocationMustHaveSameNameAsRequest;
+ public static I18n requestIsFrozenAndMayNotBeChanged;
public static I18n errorImportingContent;
public static I18n unableToFindRepositorySourceWithName;
Modified:
trunk/dna-graph/src/main/java/org/jboss/dna/graph/connector/federation/ForkRequestProcessor.java
===================================================================
---
trunk/dna-graph/src/main/java/org/jboss/dna/graph/connector/federation/ForkRequestProcessor.java 2009-05-18
15:36:58 UTC (rev 911)
+++
trunk/dna-graph/src/main/java/org/jboss/dna/graph/connector/federation/ForkRequestProcessor.java 2009-05-19
17:40:25 UTC (rev 912)
@@ -669,6 +669,16 @@
/**
* {@inheritDoc}
*
+ * @see
org.jboss.dna.graph.request.processor.RequestProcessor#completeRequest(org.jboss.dna.graph.request.Request)
+ */
+ @Override
+ protected void completeRequest( Request request ) {
+ // Do nothing here, as this is the federated request
+ }
+
+ /**
+ * {@inheritDoc}
+ *
* @see
org.jboss.dna.graph.request.processor.RequestProcessor#process(org.jboss.dna.graph.request.VerifyNodeExistsRequest)
*/
@Override
Copied: trunk/dna-graph/src/main/java/org/jboss/dna/graph/observe/ChangeFeed.java (from
rev 911, trunk/dna-graph/src/main/java/org/jboss/dna/graph/request/CacheableRequest.java)
===================================================================
--- trunk/dna-graph/src/main/java/org/jboss/dna/graph/observe/ChangeFeed.java
(rev 0)
+++ trunk/dna-graph/src/main/java/org/jboss/dna/graph/observe/ChangeFeed.java 2009-05-19
17:40:25 UTC (rev 912)
@@ -0,0 +1,52 @@
+/*
+ * JBoss DNA (
http://www.jboss.org/dna)
+ * See the COPYRIGHT.txt file distributed with this work for information
+ * regarding copyright ownership. Some portions may be licensed
+ * to Red Hat, Inc. under one or more contributor license agreements.
+ * See the AUTHORS.txt file in the distribution for a full listing of
+ * individual contributors.
+ *
+ * JBoss DNA is free software. Unless otherwise indicated, all code in JBoss DNA
+ * is licensed to you 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.
+ *
+ * JBoss DNA 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.graph.observe;
+
+import org.jboss.dna.graph.property.DateTime;
+
+/**
+ * Interface used to poll for the changes that have occurred during a specified time
period.
+ */
+public interface ChangeFeed {
+
+ /**
+ * Get the changes that were made since the supplied timestamp.
+ *
+ * @param timestamp the timestamp after which all changes should be returned
+ * @return the iterator over the changes that occurred after the supplied timestamp.
+ */
+ ChangeTimeline changesSince( DateTime timestamp );
+
+ /**
+ * Get the changes that were made since the supplied timestamp.
+ *
+ * @param beginning the timestamp at the beginning of the timeline (exclusive), or
null if the earliest timestamp should be
+ * used
+ * @param end the timestamp at the end of the timeline (inclusive), or null if the
current timestamp should be used
+ * @return the iterator over the changes that occurred after the supplied timestamp.
+ */
+ ChangeTimeline changesBetween( DateTime beginning,
+ DateTime end );
+
+}
Added: trunk/dna-graph/src/main/java/org/jboss/dna/graph/observe/ChangeObserver.java
===================================================================
--- trunk/dna-graph/src/main/java/org/jboss/dna/graph/observe/ChangeObserver.java
(rev 0)
+++
trunk/dna-graph/src/main/java/org/jboss/dna/graph/observe/ChangeObserver.java 2009-05-19
17:40:25 UTC (rev 912)
@@ -0,0 +1,159 @@
+/*
+ * JBoss DNA (
http://www.jboss.org/dna)
+ * See the COPYRIGHT.txt file distributed with this work for information
+ * regarding copyright ownership. Some portions may be licensed
+ * to Red Hat, Inc. under one or more contributor license agreements.
+ * See the AUTHORS.txt file in the distribution for a full listing of
+ * individual contributors.
+ *
+ * JBoss DNA is free software. Unless otherwise indicated, all code in JBoss DNA
+ * is licensed to you 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.
+ *
+ * JBoss DNA 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.graph.observe;
+
+import java.lang.ref.WeakReference;
+import java.util.concurrent.CopyOnWriteArraySet;
+import net.jcip.annotations.ThreadSafe;
+import org.jboss.dna.common.util.Logger;
+
+/**
+ * Abstract class that is used to signal that a change set has occurred. This class is
typically subclassed by those that wish to
+ * observe changes in content, and {@link Observable#register(ChangeObserver) registered}
with a {@link Observable}.
+ * <p>
+ * This class maintains a (weak) reference to the ChangeSource instances with which it is
registered. Therefore, the observers
+ * will not keep a ChangeSource from being garbage collected. And, if a change source is
garbage collected, calling
+ * {@link #unregister()} will clean up naturally.
+ * </p>
+ */
+@ThreadSafe
+public abstract class ChangeObserver {
+
+ private final CopyOnWriteArraySet<ChangeSourceReference> sources = new
CopyOnWriteArraySet<ChangeSourceReference>();
+
+ protected ChangeObserver() {
+ }
+
+ /**
+ * Records that this listener has successfully registered by the supplied {@link
Observable}.
+ *
+ * @param source the source with which this listener was registered
+ */
+ final void registeredWith( Observable source ) {
+ sources.add(new ChangeSourceReference(source));
+ }
+
+ /**
+ * Records that this listener has successfully unregistered by the supplied {@link
Observable}.
+ *
+ * @param source the source with which this listener was registered
+ */
+ final void unregisteredWith( Observable source ) {
+ sources.remove(new ChangeSourceReference(source));
+ }
+
+ /**
+ * Unregister this listener from all {@link Observable sources} that it was
registered with. This is preferred over calling
+ * {@link Observable#unregister(ChangeObserver)} directly.
+ */
+ public void unregister() {
+ doUnregister();
+ }
+
+ /**
+ * Method called by {@link #unregister()} that actually does the unregistering. This
method is final.
+ */
+ protected final void doUnregister() {
+ // Unregister this listener from each source ...
+ for (ChangeSourceReference sourceReference : sources) {
+ Observable source = sourceReference.get();
+ if (source != null) {
+ try {
+ source.unregister(this);
+ } catch (Throwable t) {
+ Logger.getLogger(getClass()).debug(t, "Error while unregistering
{0} from {1}", this, source);
+ }
+ }
+ }
+ }
+
+ /**
+ * Determine whether this observer is currently registered with any {@link
Observable} instances.
+ * <p>
+ * Although an observer might be registered with an {@link Observable}, if that
Observable is garbage collected, then this
+ * observer will no longer be registered with it.
+ * </p>
+ *
+ * @return true if this observer is registered with at least one {@link Observable}
instance, or false if this observer is not
+ * currently registered with any {@link Observable} instances.
+ */
+ public boolean isRegistered() {
+ for (ChangeSourceReference reference : sources) {
+ if (reference.get() != null) return true;
+ }
+ return false;
+ }
+
+ /**
+ * Method that is called for each {@link Changes} from the {@link Observable}
instance(s) with which this listener is
+ * registered.
+ *
+ * @param changeSet the change set
+ */
+ public abstract void notify( Changes changeSet );
+
+ /**
+ * A {@link WeakReference} implementation that provides a valid
+ */
+ protected final class ChangeSourceReference extends WeakReference<Observable>
{
+ final int hc;
+
+ protected ChangeSourceReference( Observable source ) {
+ super(source);
+ this.hc = source.hashCode();
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see java.lang.Object#hashCode()
+ */
+ @Override
+ public int hashCode() {
+ return hc;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see java.lang.Object#equals(java.lang.Object)
+ */
+ @Override
+ public boolean equals( Object obj ) {
+ if (obj == this) return true;
+ if (obj instanceof ChangeSourceReference) {
+ ChangeSourceReference that = (ChangeSourceReference)obj;
+ Observable thisSource = this.get();
+ Observable thatSource = that.get();
+ return thisSource == thatSource; // reference equality, not object
equality!
+ }
+ if (obj instanceof Observable) {
+ Observable that = (Observable)obj;
+ return this.get() == that; // reference equality, not object equality!
+ }
+ return false;
+ }
+ }
+
+}
Property changes on:
trunk/dna-graph/src/main/java/org/jboss/dna/graph/observe/ChangeObserver.java
___________________________________________________________________
Name: svn:keywords
+ Id Revision
Name: svn:eol-style
+ LF
Copied: trunk/dna-graph/src/main/java/org/jboss/dna/graph/observe/ChangeObservers.java
(from rev 911,
trunk/dna-graph/src/main/java/org/jboss/dna/graph/request/CacheableRequest.java)
===================================================================
--- trunk/dna-graph/src/main/java/org/jboss/dna/graph/observe/ChangeObservers.java
(rev 0)
+++
trunk/dna-graph/src/main/java/org/jboss/dna/graph/observe/ChangeObservers.java 2009-05-19
17:40:25 UTC (rev 912)
@@ -0,0 +1,66 @@
+/*
+ * JBoss DNA (
http://www.jboss.org/dna)
+ * See the COPYRIGHT.txt file distributed with this work for information
+ * regarding copyright ownership. Some portions may be licensed
+ * to Red Hat, Inc. under one or more contributor license agreements.
+ * See the AUTHORS.txt file in the distribution for a full listing of
+ * individual contributors.
+ *
+ * JBoss DNA is free software. Unless otherwise indicated, all code in JBoss DNA
+ * is licensed to you 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.
+ *
+ * JBoss DNA 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.graph.observe;
+
+import java.util.concurrent.CopyOnWriteArrayList;
+import net.jcip.annotations.ThreadSafe;
+
+/**
+ * Reusable manager of change listeners, typically employed by another {@link Observable}
implementation.
+ */
+@ThreadSafe
+public class ChangeObservers implements Observable {
+
+ private CopyOnWriteArrayList<ChangeObserver> observers = new
CopyOnWriteArrayList<ChangeObserver>();
+
+ public ChangeObservers() {
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see
org.jboss.dna.graph.observe.Observable#register(org.jboss.dna.graph.observe.ChangeObserver)
+ */
+ public boolean register( ChangeObserver observer ) {
+ if (observer != null && observers.addIfAbsent(observer)) {
+ observer.registeredWith(this);
+ return true;
+ }
+ return false;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see
org.jboss.dna.graph.observe.Observable#unregister(org.jboss.dna.graph.observe.ChangeObserver)
+ */
+ public boolean unregister( ChangeObserver observer ) {
+ if (observer != null && observers.remove(observer)) {
+ observer.unregisteredWith(this);
+ return true;
+ }
+ return false;
+ }
+
+}
Added: trunk/dna-graph/src/main/java/org/jboss/dna/graph/observe/ChangeTimeline.java
===================================================================
--- trunk/dna-graph/src/main/java/org/jboss/dna/graph/observe/ChangeTimeline.java
(rev 0)
+++
trunk/dna-graph/src/main/java/org/jboss/dna/graph/observe/ChangeTimeline.java 2009-05-19
17:40:25 UTC (rev 912)
@@ -0,0 +1,93 @@
+/*
+ * JBoss DNA (
http://www.jboss.org/dna)
+ * See the COPYRIGHT.txt file distributed with this work for information
+ * regarding copyright ownership. Some portions may be licensed
+ * to Red Hat, Inc. under one or more contributor license agreements.
+ * See the AUTHORS.txt file in the distribution for a full listing of
+ * individual contributors.
+ *
+ * JBoss DNA is free software. Unless otherwise indicated, all code in JBoss DNA
+ * is licensed to you 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.
+ *
+ * JBoss DNA 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.graph.observe;
+
+import java.util.Collection;
+import java.util.Iterator;
+import net.jcip.annotations.Immutable;
+import org.jboss.dna.graph.property.DateTime;
+
+/**
+ * The changes that were made since some time.
+ */
+@Immutable
+public class ChangeTimeline implements Iterable<Changes> {
+
+ private final Collection<Changes> changes;
+ private final DateTime after;
+ private final DateTime until;
+
+ public ChangeTimeline( Collection<Changes> changes,
+ DateTime after,
+ DateTime until ) {
+ this.changes = changes;
+ this.after = after;
+ this.until = until;
+ }
+
+ /**
+ * Get the timestamp after which all the changes occur.
+ *
+ * @return the timestamp of the changes; never null
+ */
+ public DateTime after() {
+ return after;
+ }
+
+ /**
+ * Get the timestamp of the last change set.
+ *
+ * @return the timestamp of the changes; never null
+ */
+ public DateTime until() {
+ return until;
+ }
+
+ /**
+ * Get the number of change sets.
+ *
+ * @return the number of change sets
+ */
+ public int size() {
+ return changes.size();
+ }
+
+ /**
+ * Deterine if there were no changes durign this timeline.
+ *
+ * @return true if this timeline is empty, or false if there is at least one change
+ */
+ public boolean isEmpty() {
+ return changes.isEmpty();
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see java.lang.Iterable#iterator()
+ */
+ public Iterator<Changes> iterator() {
+ return changes.iterator();
+ }
+}
Property changes on:
trunk/dna-graph/src/main/java/org/jboss/dna/graph/observe/ChangeTimeline.java
___________________________________________________________________
Name: svn:keywords
+ Id Revision
Name: svn:eol-style
+ LF
Copied: trunk/dna-graph/src/main/java/org/jboss/dna/graph/observe/Changes.java (from rev
911, trunk/dna-graph/src/main/java/org/jboss/dna/graph/request/CacheableRequest.java)
===================================================================
--- trunk/dna-graph/src/main/java/org/jboss/dna/graph/observe/Changes.java
(rev 0)
+++ trunk/dna-graph/src/main/java/org/jboss/dna/graph/observe/Changes.java 2009-05-19
17:40:25 UTC (rev 912)
@@ -0,0 +1,57 @@
+/*
+ * JBoss DNA (
http://www.jboss.org/dna)
+ * See the COPYRIGHT.txt file distributed with this work for information
+ * regarding copyright ownership. Some portions may be licensed
+ * to Red Hat, Inc. under one or more contributor license agreements.
+ * See the AUTHORS.txt file in the distribution for a full listing of
+ * individual contributors.
+ *
+ * JBoss DNA is free software. Unless otherwise indicated, all code in JBoss DNA
+ * is licensed to you 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.
+ *
+ * JBoss DNA 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.graph.observe;
+
+import javax.security.auth.Subject;
+import net.jcip.annotations.Immutable;
+import org.jboss.dna.graph.property.DateTime;
+import org.jboss.dna.graph.request.ChangeRequest;
+
+/**
+ * A set of changes that were made atomically. Each change is in the form of a frozen
{@link ChangeRequest}.
+ */
+@Immutable
+public interface Changes extends Iterable<ChangeRequest> {
+
+ /**
+ * Get the user that made these changes.
+ *
+ * @return the user; never null
+ */
+ public Subject getUser();
+
+ /**
+ * Get the name of the source that was changed.
+ *
+ * @return the source name; never null
+ */
+ public String getSourceName();
+
+ /**
+ * Get the timestamp that the changes were made. All changes within the change set
were all made at this instant in time.
+ *
+ * @return the timestamp of the changes; never null
+ */
+ public DateTime getTimestamp();
+}
Copied: trunk/dna-graph/src/main/java/org/jboss/dna/graph/observe/Observable.java (from
rev 911, trunk/dna-graph/src/main/java/org/jboss/dna/graph/request/CacheableRequest.java)
===================================================================
--- trunk/dna-graph/src/main/java/org/jboss/dna/graph/observe/Observable.java
(rev 0)
+++ trunk/dna-graph/src/main/java/org/jboss/dna/graph/observe/Observable.java 2009-05-19
17:40:25 UTC (rev 912)
@@ -0,0 +1,52 @@
+/*
+ * JBoss DNA (
http://www.jboss.org/dna)
+ * See the COPYRIGHT.txt file distributed with this work for information
+ * regarding copyright ownership. Some portions may be licensed
+ * to Red Hat, Inc. under one or more contributor license agreements.
+ * See the AUTHORS.txt file in the distribution for a full listing of
+ * individual contributors.
+ *
+ * JBoss DNA is free software. Unless otherwise indicated, all code in JBoss DNA
+ * is licensed to you 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.
+ *
+ * JBoss DNA 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.graph.observe;
+
+import net.jcip.annotations.ThreadSafe;
+
+/**
+ * Interface used to register {@link ChangeObserver listeners}. Implementations should
use a {@link ChangeObservers} to actually
+ * manage the listeners.
+ */
+@ThreadSafe
+public interface Observable {
+
+ /**
+ * Register the supplied observer. This method does nothing if the observer reference
is null.
+ *
+ * @param observer the observer to be added; may be null
+ * @return true if the observer was added, or false if the observer was null or if
the observer was already registered
+ */
+ boolean register( ChangeObserver observer );
+
+ /**
+ * Unregister the supplied observer. This method does nothing if the observer
reference is null.
+ *
+ * @param observer the observer to be removed; may not be null
+ * @return true if the observer was removed, or false if the observer was null or if
the observer was not registered on this
+ * source
+ */
+ boolean unregister( ChangeObserver observer );
+
+}
Added: trunk/dna-graph/src/main/java/org/jboss/dna/graph/observe/package-info.java
===================================================================
--- trunk/dna-graph/src/main/java/org/jboss/dna/graph/observe/package-info.java
(rev 0)
+++ trunk/dna-graph/src/main/java/org/jboss/dna/graph/observe/package-info.java 2009-05-19
17:40:25 UTC (rev 912)
@@ -0,0 +1,107 @@
+/*
+ * JBoss DNA (
http://www.jboss.org/dna)
+ * See the COPYRIGHT.txt file distributed with this work for information
+ * regarding copyright ownership. Some portions may be licensed
+ * to Red Hat, Inc. under one or more contributor license agreements.
+ * See the AUTHORS.txt file in the distribution for a full listing of
+ * individual contributors.
+ *
+ * JBoss DNA is free software. Unless otherwise indicated, all code in JBoss DNA
+ * is licensed to you 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.
+ *
+ * JBoss DNA 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.
+ */
+/**
+ * The Observation API provides several mechanisms for asynchronously observing changes
to content.
+ * <p>
+ * Many event frameworks define the listeners and sources as interfaces. While this is
often useful, it requires
+ * the implementations properly address the thread-safe semantics of managing and calling
the listeners.
+ * This observation framework uses abstract or concrete classes to minimize the effort
required for implementing
+ * {@link ChangeObserver} or {@link Observable}. The classes also allow the framework to
implement a number of
+ * utility methods, such as the {@link ChangeObserver#unregister() unregister()} method
on ChangeObserver, that
+ * also save effort and code.
+ * </p>
+ * <p>
+ * However, one of the more important reasons for providing classes is that {@link
ChangeObserver} uses
+ * {@link java.lang.ref.WeakReference weak references} to track the {@link Observable}
instances, and the {@link ChangeObservers}
+ * class uses weak references for the listeners. This means that if an observers do not
prevent {@link Observable} instances
+ * from being garbage collected, nor do observers prevent {@link Observable} instances
from being garbage collected.
+ * </p>
+ * <h3>Observable</h3>
+ * <p>
+ * Any component that can have changes and be observed can implement the {@link
Observable} interface. This interface
+ * allows Observers to register (or be registered) to receive notifications of the
changes. However, a concrete and thread-safe
+ * implementation of this interface, called {@link ChangeObservers}, is available and
should be used where possible, since it
+ * automatically manages the registered {@link ChangeObserver} instances and properly
implements the register and unregister mechanisms.
+ * </p>
+ * <h3>Observers</h3>
+ * <p>
+ * Components that are to recieve notifications of changes are called
<i>observers</i>. To create an observer, simply extend
+ * the {@link ChangeObserver} abstract class and provide an implementation of the {@link
ChangeObserver#notify(Changes)} method.
+ * Then, register the observer with an {@link Observable} using its {@link
Observable#register(ChangeObserver)} method.
+ * The observer's {@link ChangeObserver#notify(Changes)} method will then be called
with the changes that have
+ * been made to the Observable.
+ * </p>
+ * <p>When an observer is no longer needed, it should be unregistered from all
{@link Observable} instances with which
+ * it was registered. The {@link ChangeObserver} class automatically tracks which {@link
Observable} instances it is
+ * registered with, and calling the observer's {@link ChangeObserver#unregister()}
will unregister the observer from
+ * all of these Observables. Alternatively, an observer can be unregistered from a
single Observable using the
+ * Observable's {@link Observable#unregister(ChangeObserver)} method.
+ * </p>
+ * <h3>Changes</h3>
+ * <p>
+ * The {@link Changes} class represents the set of individual changes that have been made
during a single, atomic
+ * operation. Each {@link Changes} instance has information about the source of the
changes, the timestamp at which
+ * the changes occurred, and the individual changes that were made. These individual
changes take the form of
+ * {@link org.jboss.dna.graph.request.ChangeRequest} objects, such as {@link
org.jboss.dna.graph.request.CreateNodeRequest},
+ * {@link org.jboss.dna.graph.request.DeleteBranchRequest}, etc. Each request is
+ * {@link org.jboss.dna.graph.request.Request#isFrozen() frozen}, meaning it is immutable
and will not change. Also
+ * none of the requests will be {@link org.jboss.dna.graph.request.Request#isCancelled()
cancelled}.
+ * </p>
+ * <p>
+ * Using the actual {@link org.jboss.dna.graph.request.ChangeRequest} objects as the
"events" has a number of advantages.
+ * First, there are already a number of existing {@link
org.jboss.dna.graph.request.ChangeRequest} subclasses that describe
+ * various types of changes in quite a bit of detail; thus no need to duplicate the
structure or come up with a generic
+ * event class.
+ * </p>
+ * <p>
+ * Second, the requests have all the state required for an event, plus they often will
have more. For example,
+ * the DeleteBranchRequest has the actual location of the branch that was delete (and in
this way is not much different than
+ * a more generic event), but the CreateNodeRequest has the actual location of the
created node along with the properties
+ * of that node. Additionally, the RemovePropertyRequest has the actual location of the
node along with the name of the property
+ * that was removed. In many cases, these requests have all the information a more
general event class might have but
+ * then hopefully enough information for many observers to use directly without having to
read the graph to decide what
+ * actually changed.
+ * </p>
+ * <p>
+ * Third, the requests that make up a {@link Changes} instance can actually be replayed.
Consider the case of a cache
+ * that is backed by a {@link org.jboss.dna.graph.connector.RepositorySource}, which
might use an observer to keep the cache in sync.
+ * As the cache is notified of Changes, the cache can simply replay the changes against
its source.
+ * </p>
+ * <h3>Change feed and timelines</h3>
+ * <p>
+ * While it is often sufficient to register observers and receive notifications of the
changes as they occur, it
+ * is also often useful to be able to ask for the changes that have occurred since some
time or date. This allows
+ * a component to poll for changes or, for example, to catch up on the changes that
occurred previous to registering
+ * an observer.
+ * </p>
+ * <p>
+ * Components that implement {@link Observable} may also implement the {@link ChangeFeed}
interface to allow for
+ * components to {@link ChangeFeed#changesSince(org.jboss.dna.graph.property.DateTime)
poll for changes}. The result
+ * of this method is a {@link ChangeTimeline} object that contains the {@link Changes} as
well as the time period during which
+ * the change sets occurred. Note that an empty {@link ChangeTimeline} object implies
there were no changes made during the time period.
+ * </p>
+ */
+
+package org.jboss.dna.graph.observe;
+
Property changes on:
trunk/dna-graph/src/main/java/org/jboss/dna/graph/observe/package-info.java
___________________________________________________________________
Name: svn:keywords
+ Id Revision
Name: svn:eol-style
+ LF
Modified: trunk/dna-graph/src/main/java/org/jboss/dna/graph/request/CacheableRequest.java
===================================================================
---
trunk/dna-graph/src/main/java/org/jboss/dna/graph/request/CacheableRequest.java 2009-05-18
15:36:58 UTC (rev 911)
+++
trunk/dna-graph/src/main/java/org/jboss/dna/graph/request/CacheableRequest.java 2009-05-19
17:40:25 UTC (rev 912)
@@ -62,16 +62,20 @@
/**
* {@inheritDoc}
*
+ * @throws IllegalStateException if the request is frozen
* @see
org.jboss.dna.graph.cache.Cacheable#setCachePolicy(org.jboss.dna.graph.cache.CachePolicy)
*/
public void setCachePolicy( CachePolicy cachePolicy ) {
+ checkNotFrozen();
policy = cachePolicy;
}
/**
* @param timeLoaded Sets timeLoaded to the specified value.
+ * @throws IllegalStateException if the request is frozen
*/
public void setTimeLoaded( DateTime timeLoaded ) {
+ checkNotFrozen();
this.timeLoaded = timeLoaded;
}
}
Modified: trunk/dna-graph/src/main/java/org/jboss/dna/graph/request/ChangeRequest.java
===================================================================
---
trunk/dna-graph/src/main/java/org/jboss/dna/graph/request/ChangeRequest.java 2009-05-18
15:36:58 UTC (rev 911)
+++
trunk/dna-graph/src/main/java/org/jboss/dna/graph/request/ChangeRequest.java 2009-05-19
17:40:25 UTC (rev 912)
@@ -27,10 +27,15 @@
import org.jboss.dna.graph.property.Path;
/**
- *
+ * A Request to make changes in a graph.
*/
-public interface ChangeRequest {
+public abstract class ChangeRequest extends Request {
+ private static final long serialVersionUID = 1L;
+
+ protected ChangeRequest() {
+ }
+
/**
* Determine if this request changes the branch at the given path.
*
@@ -38,13 +43,13 @@
* @param path the path; may not be null
* @return true if this request changes a node under the given path
*/
- boolean changes( String workspace,
- Path path );
+ public abstract boolean changes( String workspace,
+ Path path );
/**
* Get the location of the top-most node that is to be changed by this request.
*
* @return the location changed by this request
*/
- Location changedLocation();
+ public abstract Location changedLocation();
}
Modified:
trunk/dna-graph/src/main/java/org/jboss/dna/graph/request/CloneWorkspaceRequest.java
===================================================================
---
trunk/dna-graph/src/main/java/org/jboss/dna/graph/request/CloneWorkspaceRequest.java 2009-05-18
15:36:58 UTC (rev 911)
+++
trunk/dna-graph/src/main/java/org/jboss/dna/graph/request/CloneWorkspaceRequest.java 2009-05-19
17:40:25 UTC (rev 912)
@@ -143,8 +143,10 @@
* name}.
*
* @param actualWorkspaceName the actual name of the workspace that was created, or
null if a workspace was not created
+ * @throws IllegalStateException if the request is frozen
*/
public void setActualWorkspaceName( String actualWorkspaceName ) {
+ checkNotFrozen();
this.actualWorkspaceName = actualWorkspaceName;
}
@@ -161,8 +163,10 @@
* Set the actual location of the root node in the new workspace.
*
* @param actualLocationOfRoot the actual location of the workspace's root node.
+ * @throws IllegalStateException if the request is frozen
*/
public void setActualRootLocation( Location actualLocationOfRoot ) {
+ checkNotFrozen();
this.actualLocationOfRoot = actualLocationOfRoot;
}
Modified: trunk/dna-graph/src/main/java/org/jboss/dna/graph/request/CompositeRequest.java
===================================================================
---
trunk/dna-graph/src/main/java/org/jboss/dna/graph/request/CompositeRequest.java 2009-05-18
15:36:58 UTC (rev 911)
+++
trunk/dna-graph/src/main/java/org/jboss/dna/graph/request/CompositeRequest.java 2009-05-19
17:40:25 UTC (rev 912)
@@ -29,6 +29,7 @@
import java.util.LinkedList;
import java.util.List;
import java.util.concurrent.atomic.AtomicBoolean;
+import net.jcip.annotations.Immutable;
import org.jboss.dna.common.util.CheckArg;
/**
@@ -42,6 +43,7 @@
*
* @author Randall Hauch
*/
+@Immutable
public class CompositeRequest extends Request implements Iterable<Request> {
private static final long serialVersionUID = 1L;
Modified:
trunk/dna-graph/src/main/java/org/jboss/dna/graph/request/CopyBranchRequest.java
===================================================================
---
trunk/dna-graph/src/main/java/org/jboss/dna/graph/request/CopyBranchRequest.java 2009-05-18
15:36:58 UTC (rev 911)
+++
trunk/dna-graph/src/main/java/org/jboss/dna/graph/request/CopyBranchRequest.java 2009-05-19
17:40:25 UTC (rev 912)
@@ -37,7 +37,7 @@
*
* @author Randall Hauch
*/
-public class CopyBranchRequest extends Request implements ChangeRequest {
+public class CopyBranchRequest extends ChangeRequest {
private static final long serialVersionUID = 1L;
@@ -205,9 +205,11 @@
* {@link Location#isSame(Location) same location} as the {@link #from() from
location}; if the new location does not
* represent the {@link Location#isSame(Location) same location} as the
{@link #into() into location}; if the either
* location does not have a path
+ * @throws IllegalStateException if the request is frozen
*/
public void setActualLocations( Location fromLocation,
Location intoLocation ) {
+ checkNotFrozen();
if (!from.isSame(fromLocation)) { // not same if actual is null
throw new
IllegalArgumentException(GraphI18n.actualLocationIsNotSameAsInputLocation.text(fromLocation,
from));
}
@@ -251,6 +253,7 @@
*
* @see org.jboss.dna.graph.request.ChangeRequest#changes(java.lang.String,
org.jboss.dna.graph.property.Path)
*/
+ @Override
public boolean changes( String workspace,
Path path ) {
return this.intoWorkspace.equals(workspace) && into.hasPath() &&
into.getPath().isAtOrBelow(path);
@@ -261,6 +264,7 @@
*
* @see org.jboss.dna.graph.request.ChangeRequest#changedLocation()
*/
+ @Override
public Location changedLocation() {
return into;
}
Modified:
trunk/dna-graph/src/main/java/org/jboss/dna/graph/request/CreateNodeRequest.java
===================================================================
---
trunk/dna-graph/src/main/java/org/jboss/dna/graph/request/CreateNodeRequest.java 2009-05-18
15:36:58 UTC (rev 911)
+++
trunk/dna-graph/src/main/java/org/jboss/dna/graph/request/CreateNodeRequest.java 2009-05-19
17:40:25 UTC (rev 912)
@@ -43,7 +43,7 @@
*
* @author Randall Hauch
*/
-public class CreateNodeRequest extends Request implements Iterable<Property>,
ChangeRequest {
+public class CreateNodeRequest extends ChangeRequest implements Iterable<Property>
{
private static final long serialVersionUID = 1L;
@@ -279,8 +279,10 @@
* used
* @throws IllegalArgumentException if the actual location does not represent the
{@link Location#isSame(Location) same
* location} as the {@link #under() current location}, or if the actual
location does not have a path.
+ * @throws IllegalStateException if the request is frozen
*/
public void setActualLocationOfNode( Location actual ) {
+ checkNotFrozen();
CheckArg.isNotNull(actual, "actual");
if (!under.isSame(actual, false)) { // not same if actual is null
}
@@ -309,6 +311,7 @@
*
* @see org.jboss.dna.graph.request.ChangeRequest#changes(java.lang.String,
org.jboss.dna.graph.property.Path)
*/
+ @Override
public boolean changes( String workspace,
Path path ) {
return this.workspaceName.equals(workspace) && under.hasPath() &&
under.getPath().isAtOrBelow(path);
@@ -319,6 +322,7 @@
*
* @see org.jboss.dna.graph.request.ChangeRequest#changedLocation()
*/
+ @Override
public Location changedLocation() {
return under;
}
Modified:
trunk/dna-graph/src/main/java/org/jboss/dna/graph/request/CreateWorkspaceRequest.java
===================================================================
---
trunk/dna-graph/src/main/java/org/jboss/dna/graph/request/CreateWorkspaceRequest.java 2009-05-18
15:36:58 UTC (rev 911)
+++
trunk/dna-graph/src/main/java/org/jboss/dna/graph/request/CreateWorkspaceRequest.java 2009-05-19
17:40:25 UTC (rev 912)
@@ -105,8 +105,10 @@
* {@link CreateConflictBehavior#CREATE_WITH_ADJUSTED_NAME alter the name}.
*
* @param actualWorkspaceName the actual name of the workspace that was created, or
null if a workspace was not created
+ * @throws IllegalStateException if the request is frozen
*/
public void setActualWorkspaceName( String actualWorkspaceName ) {
+ checkNotFrozen();
this.actualWorkspaceName = actualWorkspaceName;
}
@@ -123,8 +125,10 @@
* Set the actual location of the root node in the new workspace.
*
* @param actualLocationOfRoot the actual location of the workspace's root node.
+ * @throws IllegalStateException if the request is frozen
*/
public void setActualRootLocation( Location actualLocationOfRoot ) {
+ checkNotFrozen();
this.actualLocationOfRoot = actualLocationOfRoot;
}
Modified:
trunk/dna-graph/src/main/java/org/jboss/dna/graph/request/DeleteBranchRequest.java
===================================================================
---
trunk/dna-graph/src/main/java/org/jboss/dna/graph/request/DeleteBranchRequest.java 2009-05-18
15:36:58 UTC (rev 911)
+++
trunk/dna-graph/src/main/java/org/jboss/dna/graph/request/DeleteBranchRequest.java 2009-05-19
17:40:25 UTC (rev 912)
@@ -34,7 +34,7 @@
*
* @author Randall Hauch
*/
-public class DeleteBranchRequest extends Request implements ChangeRequest {
+public class DeleteBranchRequest extends ChangeRequest {
private static final long serialVersionUID = 1L;
@@ -92,8 +92,10 @@
* @param actual the actual location of the node being deleted, or null if the {@link
#at() current location} should be used
* @throws IllegalArgumentException if the actual location does not represent the
{@link Location#isSame(Location) same
* location} as the {@link #at() current location}, or if the actual location
does not have a path.
+ * @throws IllegalStateException if the request is frozen
*/
public void setActualLocationOfNode( Location actual ) {
+ checkNotFrozen();
if (!at.isSame(actual)) { // not same if actual is null
throw new
IllegalArgumentException(GraphI18n.actualLocationIsNotSameAsInputLocation.text(actual,
at));
}
@@ -118,6 +120,7 @@
*
* @see org.jboss.dna.graph.request.ChangeRequest#changes(java.lang.String,
org.jboss.dna.graph.property.Path)
*/
+ @Override
public boolean changes( String workspace,
Path path ) {
return this.workspaceName.equals(workspace) && at.hasPath() &&
at.getPath().isAtOrBelow(path);
@@ -128,6 +131,7 @@
*
* @see org.jboss.dna.graph.request.ChangeRequest#changedLocation()
*/
+ @Override
public Location changedLocation() {
return at;
}
Modified:
trunk/dna-graph/src/main/java/org/jboss/dna/graph/request/DeleteChildrenRequest.java
===================================================================
---
trunk/dna-graph/src/main/java/org/jboss/dna/graph/request/DeleteChildrenRequest.java 2009-05-18
15:36:58 UTC (rev 911)
+++
trunk/dna-graph/src/main/java/org/jboss/dna/graph/request/DeleteChildrenRequest.java 2009-05-19
17:40:25 UTC (rev 912)
@@ -32,7 +32,7 @@
* Instruction that all nodes below a supplied node be deleted. This is similar to {@link
DeleteBranchRequest}, except that the
* parent node (top node in the branch) is not deleted.
*/
-public class DeleteChildrenRequest extends Request implements ChangeRequest {
+public class DeleteChildrenRequest extends ChangeRequest {
private static final long serialVersionUID = 1L;
@@ -90,8 +90,10 @@
* @param actual the actual location of the node being deleted, or null if the {@link
#at() current location} should be used
* @throws IllegalArgumentException if the actual location does not represent the
{@link Location#isSame(Location) same
* location} as the {@link #at() current location}, or if the actual location
does not have a path.
+ * @throws IllegalStateException if the request is frozen
*/
public void setActualLocationOfNode( Location actual ) {
+ checkNotFrozen();
if (!at.isSame(actual)) { // not same if actual is null
throw new
IllegalArgumentException(GraphI18n.actualLocationIsNotSameAsInputLocation.text(actual,
at));
}
@@ -116,6 +118,7 @@
*
* @see org.jboss.dna.graph.request.ChangeRequest#changes(java.lang.String,
org.jboss.dna.graph.property.Path)
*/
+ @Override
public boolean changes( String workspace,
Path path ) {
return this.workspaceName.equals(workspace) && at.hasPath() &&
at.getPath().isAtOrBelow(path);
@@ -126,6 +129,7 @@
*
* @see org.jboss.dna.graph.request.ChangeRequest#changedLocation()
*/
+ @Override
public Location changedLocation() {
return at;
}
Modified:
trunk/dna-graph/src/main/java/org/jboss/dna/graph/request/GetWorkspacesRequest.java
===================================================================
---
trunk/dna-graph/src/main/java/org/jboss/dna/graph/request/GetWorkspacesRequest.java 2009-05-18
15:36:58 UTC (rev 911)
+++
trunk/dna-graph/src/main/java/org/jboss/dna/graph/request/GetWorkspacesRequest.java 2009-05-19
17:40:25 UTC (rev 912)
@@ -63,8 +63,10 @@
* Set the names of the workspaces that are available (at least to the current user)
*
* @param availableWorkspaceNames Sets availableWorkspaceNames to the specified
value.
+ * @throws IllegalStateException if the request is frozen
*/
public void setAvailableWorkspaceNames( Set<String> availableWorkspaceNames )
{
+ checkNotFrozen();
this.availableWorkspaceNames = availableWorkspaceNames;
}
Modified:
trunk/dna-graph/src/main/java/org/jboss/dna/graph/request/MoveBranchRequest.java
===================================================================
---
trunk/dna-graph/src/main/java/org/jboss/dna/graph/request/MoveBranchRequest.java 2009-05-18
15:36:58 UTC (rev 911)
+++
trunk/dna-graph/src/main/java/org/jboss/dna/graph/request/MoveBranchRequest.java 2009-05-19
17:40:25 UTC (rev 912)
@@ -36,7 +36,7 @@
*
* @author Randall Hauch
*/
-public class MoveBranchRequest extends Request implements ChangeRequest {
+public class MoveBranchRequest extends ChangeRequest {
private static final long serialVersionUID = 1L;
@@ -216,9 +216,11 @@
* {@link Location#isSame(Location) same location} as the {@link #from() from
location}, if the new location does not
* represent the {@link Location#isSame(Location) same location} as the
{@link #into() into location}, or if the
* either location does not have a path
+ * @throws IllegalStateException if the request is frozen
*/
public void setActualLocations( Location oldLocation,
Location newLocation ) {
+ checkNotFrozen();
CheckArg.isNotNull(oldLocation, "oldLocation");
CheckArg.isNotNull(newLocation, "newLocation");
if (!from.isSame(oldLocation)) { // not same if actual is null
@@ -265,6 +267,7 @@
*
* @see org.jboss.dna.graph.request.ChangeRequest#changes(java.lang.String,
org.jboss.dna.graph.property.Path)
*/
+ @Override
public boolean changes( String workspace,
Path path ) {
return this.workspaceName.equals(workspace)
@@ -276,6 +279,7 @@
*
* @see org.jboss.dna.graph.request.ChangeRequest#changedLocation()
*/
+ @Override
public Location changedLocation() {
return into;
}
Modified:
trunk/dna-graph/src/main/java/org/jboss/dna/graph/request/ReadAllChildrenRequest.java
===================================================================
---
trunk/dna-graph/src/main/java/org/jboss/dna/graph/request/ReadAllChildrenRequest.java 2009-05-18
15:36:58 UTC (rev 911)
+++
trunk/dna-graph/src/main/java/org/jboss/dna/graph/request/ReadAllChildrenRequest.java 2009-05-19
17:40:25 UTC (rev 912)
@@ -116,11 +116,13 @@
*
* @param children the locations of the children that were read
* @throws IllegalArgumentException if the parameter is null
+ * @throws IllegalStateException if the request is frozen
* @see #addChild(Location)
* @see #addChild(Path, Property)
* @see #addChild(Path, Property, Property...)
*/
public void addChildren( Iterable<Location> children ) {
+ checkNotFrozen();
CheckArg.isNotNull(children, "children");
for (Location child : children) {
if (child != null) this.children.add(child);
@@ -133,10 +135,12 @@
*
* @param child the location of the child that was read
* @throws IllegalArgumentException if the location is null
+ * @throws IllegalStateException if the request is frozen
* @see #addChild(Path, Property)
* @see #addChild(Path, Property, Property...)
*/
public void addChild( Location child ) {
+ checkNotFrozen();
CheckArg.isNotNull(child, "child");
this.children.add(child);
}
@@ -149,12 +153,14 @@
* @param firstIdProperty the first identification property of the child that was
just read
* @param remainingIdProperties the remaining identification properties of the child
that was just read
* @throws IllegalArgumentException if the path or identification properties are
null
+ * @throws IllegalStateException if the request is frozen
* @see #addChild(Location)
* @see #addChild(Path, Property)
*/
public void addChild( Path pathToChild,
Property firstIdProperty,
Property... remainingIdProperties ) {
+ checkNotFrozen();
Location child = Location.create(pathToChild, firstIdProperty,
remainingIdProperties);
this.children.add(child);
}
@@ -166,11 +172,13 @@
* @param pathToChild the path of the child that was just read
* @param idProperty the identification property of the child that was just read
* @throws IllegalArgumentException if the path or identification properties are
null
+ * @throws IllegalStateException if the request is frozen
* @see #addChild(Location)
* @see #addChild(Path, Property, Property...)
*/
public void addChild( Path pathToChild,
Property idProperty ) {
+ checkNotFrozen();
Location child = Location.create(pathToChild, idProperty);
this.children.add(child);
}
@@ -184,8 +192,10 @@
* @throws IllegalArgumentException if the actual location does not represent the
{@link Location#isSame(Location) same
* location} as the {@link #of() current location}; if the actual location
does not have a path; or if the actual
* workspace name is null
+ * @throws IllegalStateException if the request is frozen
*/
public void setActualLocationOfNode( Location actualLocation ) {
+ checkNotFrozen();
if (!this.of.isSame(actualLocation)) { // not same if actualLocation is null
throw new
IllegalArgumentException(GraphI18n.actualLocationIsNotSameAsInputLocation.text(actualLocation,
of));
}
Modified:
trunk/dna-graph/src/main/java/org/jboss/dna/graph/request/ReadAllPropertiesRequest.java
===================================================================
---
trunk/dna-graph/src/main/java/org/jboss/dna/graph/request/ReadAllPropertiesRequest.java 2009-05-18
15:36:58 UTC (rev 911)
+++
trunk/dna-graph/src/main/java/org/jboss/dna/graph/request/ReadAllPropertiesRequest.java 2009-05-19
17:40:25 UTC (rev 912)
@@ -129,8 +129,10 @@
* @return the previous property that had the same name, or null if there was no
previously-recorded property with the same
* name
* @throws IllegalArgumentException if the property is null
+ * @throws IllegalStateException if the request is frozen
*/
public Property addProperty( Property property ) {
+ checkNotFrozen();
return this.properties.put(property.getName(), property);
}
@@ -139,8 +141,10 @@
*
* @param properties the properties that were read
* @throws IllegalArgumentException if the property is null
+ * @throws IllegalStateException if the request is frozen
*/
public void addProperties( Property... properties ) {
+ checkNotFrozen();
for (Property property : properties) {
this.properties.put(property.getName(), property);
}
@@ -151,8 +155,10 @@
*
* @param properties the properties that were read
* @throws IllegalArgumentException if the property is null
+ * @throws IllegalStateException if the request is frozen
*/
public void addProperties( Iterable<Property> properties ) {
+ checkNotFrozen();
for (Property property : properties) {
this.properties.put(property.getName(), property);
}
@@ -172,8 +178,10 @@
*
* @param numberOfChildren the number of children
* @throws IllegalArgumentException if the number of childre is negative
+ * @throws IllegalStateException if the request is frozen
*/
public void setNumberOfChildren( int numberOfChildren ) {
+ checkNotFrozen();
CheckArg.isNonNegative(numberOfChildren, "numberOfChildren");
this.numberOfChildren = numberOfChildren;
}
@@ -185,8 +193,10 @@
* @param actual the actual location of the node being read, or null if the {@link
#at() current location} should be used
* @throws IllegalArgumentException if the actual location does not represent the
{@link Location#isSame(Location) same
* location} as the {@link #at() current location}, or if the actual location
does not have a path.
+ * @throws IllegalStateException if the request is frozen
*/
public void setActualLocationOfNode( Location actual ) {
+ checkNotFrozen();
if (!at.isSame(actual)) { // not same if actual is null
throw new
IllegalArgumentException(GraphI18n.actualLocationIsNotSameAsInputLocation.text(actual,
at));
}
Modified:
trunk/dna-graph/src/main/java/org/jboss/dna/graph/request/ReadBlockOfChildrenRequest.java
===================================================================
---
trunk/dna-graph/src/main/java/org/jboss/dna/graph/request/ReadBlockOfChildrenRequest.java 2009-05-18
15:36:58 UTC (rev 911)
+++
trunk/dna-graph/src/main/java/org/jboss/dna/graph/request/ReadBlockOfChildrenRequest.java 2009-05-19
17:40:25 UTC (rev 912)
@@ -163,11 +163,13 @@
*
* @param children the locations of the children that were read
* @throws IllegalArgumentException if the parameter is null
+ * @throws IllegalStateException if the request is frozen
* @see #addChild(Location)
* @see #addChild(Path, Property)
* @see #addChild(Path, Property, Property...)
*/
public void addChildren( Iterable<Location> children ) {
+ checkNotFrozen();
CheckArg.isNotNull(children, "children");
for (Location child : children) {
if (child != null) this.children.add(child);
@@ -180,10 +182,12 @@
*
* @param child the location of the child that was read
* @throws IllegalArgumentException if the location is null
+ * @throws IllegalStateException if the request is frozen
* @see #addChild(Path, Property)
* @see #addChild(Path, Property, Property...)
*/
public void addChild( Location child ) {
+ checkNotFrozen();
CheckArg.isNotNull(child, "child");
this.children.add(child);
}
@@ -196,12 +200,14 @@
* @param firstIdProperty the first identification property of the child that was
just read
* @param remainingIdProperties the remaining identification properties of the child
that was just read
* @throws IllegalArgumentException if the path or identification properties are
null
+ * @throws IllegalStateException if the request is frozen
* @see #addChild(Location)
* @see #addChild(Path, Property)
*/
public void addChild( Path pathToChild,
Property firstIdProperty,
Property... remainingIdProperties ) {
+ checkNotFrozen();
Location child = Location.create(pathToChild, firstIdProperty,
remainingIdProperties);
this.children.add(child);
}
@@ -213,11 +219,13 @@
* @param pathToChild the path of the child that was just read
* @param idProperty the identification property of the child that was just read
* @throws IllegalArgumentException if the path or identification properties are
null
+ * @throws IllegalStateException if the request is frozen
* @see #addChild(Location)
* @see #addChild(Path, Property, Property...)
*/
public void addChild( Path pathToChild,
Property idProperty ) {
+ checkNotFrozen();
Location child = Location.create(pathToChild, idProperty);
this.children.add(child);
}
@@ -229,8 +237,10 @@
* @param actual the actual location of the node being read, or null if the {@link
#of() current location} should be used
* @throws IllegalArgumentException if the actual location does not represent the
{@link Location#isSame(Location) same
* location} as the {@link #of() current location}, or if the actual location
does not have a path.
+ * @throws IllegalStateException if the request is frozen
*/
public void setActualLocationOfNode( Location actual ) {
+ checkNotFrozen();
if (!of.isSame(actual)) { // not same if actual is null
throw new
IllegalArgumentException(GraphI18n.actualLocationIsNotSameAsInputLocation.text(actual,
of));
}
Modified:
trunk/dna-graph/src/main/java/org/jboss/dna/graph/request/ReadBranchRequest.java
===================================================================
---
trunk/dna-graph/src/main/java/org/jboss/dna/graph/request/ReadBranchRequest.java 2009-05-18
15:36:58 UTC (rev 911)
+++
trunk/dna-graph/src/main/java/org/jboss/dna/graph/request/ReadBranchRequest.java 2009-05-19
17:40:25 UTC (rev 912)
@@ -199,9 +199,11 @@
* @param node the location of the node that appears on this branch; must {@link
Location#hasPath() have a path}
* @param properties the properties on the node
* @throws IllegalArgumentException if the node is null
+ * @throws IllegalStateException if the request is frozen
*/
public void setProperties( Location node,
Property... properties ) {
+ checkNotFrozen();
CheckArg.isNotNull(node, "node");
assert node.hasPath();
Node nodeObj = nodes.get(node.getPath());
@@ -222,9 +224,11 @@
* @param node the location of the node that appears on this branch; must {@link
Location#hasPath() have a path}
* @param properties the properties on the node
* @throws IllegalArgumentException if the node is null
+ * @throws IllegalStateException if the request is frozen
*/
public void setProperties( Location node,
Iterable<Property> properties ) {
+ checkNotFrozen();
CheckArg.isNotNull(node, "node");
assert node.hasPath();
Node nodeObj = nodes.get(node.getPath());
@@ -243,9 +247,11 @@
*
* @param parent the location of the parent; must {@link Location#hasPath() have a
path}
* @param children the location of each child, in the order they appear in the
parent
+ * @throws IllegalStateException if the request is frozen
*/
public void setChildren( Location parent,
Location... children ) {
+ checkNotFrozen();
CheckArg.isNotNull(parent, "parent");
CheckArg.isNotNull(children, "children");
assert parent.hasPath();
@@ -262,9 +268,11 @@
*
* @param parent the location of the parent; must {@link Location#hasPath() have a
path}
* @param children the location of each child, in the order they appear in the
parent
+ * @throws IllegalStateException if the request is frozen
*/
public void setChildren( Location parent,
List<Location> children ) {
+ checkNotFrozen();
CheckArg.isNotNull(parent, "parent");
CheckArg.isNotNull(children, "children");
assert parent.hasPath();
Modified:
trunk/dna-graph/src/main/java/org/jboss/dna/graph/request/ReadNextBlockOfChildrenRequest.java
===================================================================
---
trunk/dna-graph/src/main/java/org/jboss/dna/graph/request/ReadNextBlockOfChildrenRequest.java 2009-05-18
15:36:58 UTC (rev 911)
+++
trunk/dna-graph/src/main/java/org/jboss/dna/graph/request/ReadNextBlockOfChildrenRequest.java 2009-05-19
17:40:25 UTC (rev 912)
@@ -131,11 +131,13 @@
*
* @param children the locations of the children that were read
* @throws IllegalArgumentException if the parameter is null
+ * @throws IllegalStateException if the request is frozen
* @see #addChild(Location)
* @see #addChild(Path, Property)
* @see #addChild(Path, Property, Property...)
*/
public void addChildren( Iterable<Location> children ) {
+ checkNotFrozen();
CheckArg.isNotNull(children, "children");
for (Location child : children) {
if (child != null) this.children.add(child);
@@ -148,10 +150,12 @@
*
* @param child the location of the child that was read
* @throws IllegalArgumentException if the location is null
+ * @throws IllegalStateException if the request is frozen
* @see #addChild(Path, Property)
* @see #addChild(Path, Property, Property...)
*/
public void addChild( Location child ) {
+ checkNotFrozen();
CheckArg.isNotNull(child, "child");
this.children.add(child);
}
@@ -164,12 +168,14 @@
* @param firstIdProperty the first identification property of the child that was
just read
* @param remainingIdProperties the remaining identification properties of the child
that was just read
* @throws IllegalArgumentException if the path or identification properties are
null
+ * @throws IllegalStateException if the request is frozen
* @see #addChild(Location)
* @see #addChild(Path, Property)
*/
public void addChild( Path pathToChild,
Property firstIdProperty,
Property... remainingIdProperties ) {
+ checkNotFrozen();
Location child = Location.create(pathToChild, firstIdProperty,
remainingIdProperties);
this.children.add(child);
}
@@ -181,11 +187,13 @@
* @param pathToChild the path of the child that was just read
* @param idProperty the identification property of the child that was just read
* @throws IllegalArgumentException if the path or identification properties are
null
+ * @throws IllegalStateException if the request is frozen
* @see #addChild(Location)
* @see #addChild(Path, Property, Property...)
*/
public void addChild( Path pathToChild,
Property idProperty ) {
+ checkNotFrozen();
Location child = Location.create(pathToChild, idProperty);
this.children.add(child);
}
@@ -198,8 +206,10 @@
* should be used
* @throws IllegalArgumentException if the actual location does not represent the
{@link Location#isSame(Location) same
* location} as the {@link #startingAfter() starting after location}, or if
the actual location does not have a path.
+ * @throws IllegalStateException if the request is frozen
*/
public void setActualLocationOfStartingAfterNode( Location actual ) {
+ checkNotFrozen();
if (!startingAfter.isSame(actual)) { // not same if actual is null
throw new
IllegalArgumentException(GraphI18n.actualLocationIsNotSameAsInputLocation.text(actual,
startingAfter));
}
Modified: trunk/dna-graph/src/main/java/org/jboss/dna/graph/request/ReadNodeRequest.java
===================================================================
---
trunk/dna-graph/src/main/java/org/jboss/dna/graph/request/ReadNodeRequest.java 2009-05-18
15:36:58 UTC (rev 911)
+++
trunk/dna-graph/src/main/java/org/jboss/dna/graph/request/ReadNodeRequest.java 2009-05-19
17:40:25 UTC (rev 912)
@@ -121,8 +121,10 @@
* @return the previous property that had the same name, or null if there was no
previously-recorded property with the same
* name
* @throws IllegalArgumentException if the property is null
+ * @throws IllegalStateException if the request is frozen
*/
public Property addProperty( Property property ) {
+ checkNotFrozen();
return this.properties.put(property.getName(), property);
}
@@ -130,9 +132,12 @@
* Add a property that was read from the {@link RepositoryConnection}
*
* @param properties the properties that were read
- * @throws IllegalArgumentException if the property is null
+ * @throws IllegalArgumentException if the properties array is null
+ * @throws IllegalStateException if the request is frozen
*/
public void addProperties( Property... properties ) {
+ checkNotFrozen();
+ CheckArg.isNotNull(properties, "properties");
for (Property property : properties) {
this.properties.put(property.getName(), property);
}
@@ -142,9 +147,12 @@
* Add a property that was read from the {@link RepositoryConnection}
*
* @param properties the properties that were read
- * @throws IllegalArgumentException if the property is null
+ * @throws IllegalArgumentException if the iterable reference is null
+ * @throws IllegalStateException if the request is frozen
*/
public void addProperties( Iterable<Property> properties ) {
+ checkNotFrozen();
+ CheckArg.isNotNull(properties, "properties");
for (Property property : properties) {
this.properties.put(property.getName(), property);
}
@@ -175,11 +183,13 @@
*
* @param children the locations of the children that were read
* @throws IllegalArgumentException if the parameter is null
+ * @throws IllegalStateException if the request is frozen
* @see #addChild(Location)
* @see #addChild(Path, Property)
* @see #addChild(Path, Property, Property...)
*/
public void addChildren( Iterable<Location> children ) {
+ checkNotFrozen();
CheckArg.isNotNull(children, "children");
for (Location child : children) {
if (child != null) this.children.add(child);
@@ -192,10 +202,12 @@
*
* @param child the location of the child that was read
* @throws IllegalArgumentException if the location is null
+ * @throws IllegalStateException if the request is frozen
* @see #addChild(Path, Property)
* @see #addChild(Path, Property, Property...)
*/
public void addChild( Location child ) {
+ checkNotFrozen();
CheckArg.isNotNull(child, "child");
this.children.add(child);
}
@@ -208,12 +220,14 @@
* @param firstIdProperty the first identification property of the child that was
just read
* @param remainingIdProperties the remaining identification properties of the child
that was just read
* @throws IllegalArgumentException if the path or identification properties are
null
+ * @throws IllegalStateException if the request is frozen
* @see #addChild(Location)
* @see #addChild(Path, Property)
*/
public void addChild( Path pathToChild,
Property firstIdProperty,
Property... remainingIdProperties ) {
+ checkNotFrozen();
Location child = Location.create(pathToChild, firstIdProperty,
remainingIdProperties);
this.children.add(child);
}
@@ -225,11 +239,13 @@
* @param pathToChild the path of the child that was just read
* @param idProperty the identification property of the child that was just read
* @throws IllegalArgumentException if the path or identification properties are
null
+ * @throws IllegalStateException if the request is frozen
* @see #addChild(Location)
* @see #addChild(Path, Property, Property...)
*/
public void addChild( Path pathToChild,
Property idProperty ) {
+ checkNotFrozen();
Location child = Location.create(pathToChild, idProperty);
this.children.add(child);
}
@@ -241,8 +257,10 @@
* @param actual the actual location of the node being read, or null if the {@link
#at() current location} should be used
* @throws IllegalArgumentException if the actual location does not represent the
{@link Location#isSame(Location) same
* location} as the {@link #at() current location}, or if the actual location
does not have a path.
+ * @throws IllegalStateException if the request is frozen
*/
public void setActualLocationOfNode( Location actual ) {
+ checkNotFrozen();
if (!at.isSame(actual)) { // not same if actual is null
throw new
IllegalArgumentException(GraphI18n.actualLocationIsNotSameAsInputLocation.text(actual,
at));
}
Modified:
trunk/dna-graph/src/main/java/org/jboss/dna/graph/request/ReadPropertyRequest.java
===================================================================
---
trunk/dna-graph/src/main/java/org/jboss/dna/graph/request/ReadPropertyRequest.java 2009-05-18
15:36:58 UTC (rev 911)
+++
trunk/dna-graph/src/main/java/org/jboss/dna/graph/request/ReadPropertyRequest.java 2009-05-19
17:40:25 UTC (rev 912)
@@ -117,8 +117,10 @@
* @param property the property that was read
* @throws IllegalArgumentException if the property's name does not match the
{@link #named() name of the property} that was
* to be read
+ * @throws IllegalStateException if the request is frozen
*/
public void setProperty( Property property ) {
+ checkNotFrozen();
if (property != null) CheckArg.isEquals(property.getName(), "property's
name", named(), "property name");
this.property = property;
}
@@ -130,8 +132,10 @@
* @param actual the actual location of the node being read, or null if the {@link
#on() current location} should be used
* @throws IllegalArgumentException if the actual location does not represent the
{@link Location#isSame(Location) same
* location} as the {@link #on() current location}, or if the actual location
does not have a path.
+ * @throws IllegalStateException if the request is frozen
*/
public void setActualLocationOfNode( Location actual ) {
+ checkNotFrozen();
if (!on.isSame(actual)) { // not same if actual is null
throw new
IllegalArgumentException(GraphI18n.actualLocationIsNotSameAsInputLocation.text(actual,
on));
}
Modified:
trunk/dna-graph/src/main/java/org/jboss/dna/graph/request/RemovePropertyRequest.java
===================================================================
---
trunk/dna-graph/src/main/java/org/jboss/dna/graph/request/RemovePropertyRequest.java 2009-05-18
15:36:58 UTC (rev 911)
+++
trunk/dna-graph/src/main/java/org/jboss/dna/graph/request/RemovePropertyRequest.java 2009-05-19
17:40:25 UTC (rev 912)
@@ -36,7 +36,7 @@
*
* @author Randall Hauch
*/
-public class RemovePropertyRequest extends Request implements ChangeRequest {
+public class RemovePropertyRequest extends ChangeRequest {
private static final long serialVersionUID = 1L;
@@ -108,8 +108,10 @@
* @param actual the actual location of the node being updated, or null if the {@link
#from() current location} should be used
* @throws IllegalArgumentException if the actual location does represent the {@link
Location#isSame(Location) same location}
* as the {@link #from() current location}, or if the actual location does
not have a path.
+ * @throws IllegalStateException if the request is frozen
*/
public void setActualLocationOfNode( Location actual ) {
+ checkNotFrozen();
if (!from.isSame(actual)) { // not same if actual is null
throw new
IllegalArgumentException(GraphI18n.actualLocationIsNotSameAsInputLocation.text(actual,
from));
}
@@ -134,6 +136,7 @@
*
* @see org.jboss.dna.graph.request.ChangeRequest#changes(java.lang.String,
org.jboss.dna.graph.property.Path)
*/
+ @Override
public boolean changes( String workspace,
Path path ) {
return this.workspaceName.equals(workspace) && from.hasPath() &&
from.getPath().isAtOrBelow(path);
@@ -183,6 +186,7 @@
*
* @see org.jboss.dna.graph.request.ChangeRequest#changedLocation()
*/
+ @Override
public Location changedLocation() {
return from;
}
Modified:
trunk/dna-graph/src/main/java/org/jboss/dna/graph/request/RenameNodeRequest.java
===================================================================
---
trunk/dna-graph/src/main/java/org/jboss/dna/graph/request/RenameNodeRequest.java 2009-05-18
15:36:58 UTC (rev 911)
+++
trunk/dna-graph/src/main/java/org/jboss/dna/graph/request/RenameNodeRequest.java 2009-05-19
17:40:25 UTC (rev 912)
@@ -36,7 +36,7 @@
*
* @author Randall Hauch
*/
-public class RenameNodeRequest extends Request implements ChangeRequest {
+public class RenameNodeRequest extends ChangeRequest {
private static final long serialVersionUID = 1L;
@@ -113,9 +113,11 @@
* location does not have the same parent as the old location, or if the new
location does not have the same
* {@link Path.Segment#getName() name} on {@link Path#getLastSegment() last
segment} as that {@link #toName()
* specified on the request}
+ * @throws IllegalStateException if the request is frozen
*/
public void setActualLocations( Location oldLocation,
Location newLocation ) {
+ checkNotFrozen();
if (!at.isSame(oldLocation)) { // not same if actual is null
throw new
IllegalArgumentException(GraphI18n.actualLocationIsNotSameAsInputLocation.text(oldLocation,
at));
}
@@ -164,6 +166,7 @@
*
* @see org.jboss.dna.graph.request.ChangeRequest#changes(java.lang.String,
org.jboss.dna.graph.property.Path)
*/
+ @Override
public boolean changes( String workspace,
Path path ) {
return this.workspaceName.equals(workspace) && at.hasPath() &&
at.getPath().getParent().isAtOrBelow(path);
@@ -174,6 +177,7 @@
*
* @see org.jboss.dna.graph.request.ChangeRequest#changedLocation()
*/
+ @Override
public Location changedLocation() {
return at;
}
Modified: trunk/dna-graph/src/main/java/org/jboss/dna/graph/request/Request.java
===================================================================
--- trunk/dna-graph/src/main/java/org/jboss/dna/graph/request/Request.java 2009-05-18
15:36:58 UTC (rev 911)
+++ trunk/dna-graph/src/main/java/org/jboss/dna/graph/request/Request.java 2009-05-19
17:40:25 UTC (rev 912)
@@ -25,6 +25,7 @@
import java.io.Serializable;
import java.util.concurrent.atomic.AtomicBoolean;
+import org.jboss.dna.graph.GraphI18n;
import org.jboss.dna.graph.connector.RepositoryConnection;
/**
@@ -37,18 +38,20 @@
private static final long serialVersionUID = 1L;
private Throwable error;
- private AtomicBoolean cancelled;
+ private AtomicBoolean cancelled = new AtomicBoolean(false);
+ private final AtomicBoolean frozen = new AtomicBoolean(false);
protected Request() {
- this.cancelled = new AtomicBoolean(false);
}
/**
* Set the error for this request.
*
* @param error the error to be associated with this request, or null if this request
is to have no error
+ * @throws IllegalStateException if the request is frozen
*/
public void setError( Throwable error ) {
+ checkNotFrozen();
this.error = error;
}
@@ -117,8 +120,11 @@
* <p>
* This method is safe to be called by different threads.
* </p>
+ *
+ * @throws IllegalStateException if the request is frozen
*/
public void cancel() {
+ checkNotFrozen();
this.cancelled.set(true);
}
@@ -128,4 +134,31 @@
* @return true if this request reads information, or false if it requests that the
repository content be changed in some way
*/
public abstract boolean isReadOnly();
+
+ /**
+ * Determine whether this request has been frozen, preventing any further updates.
+ *
+ * @return true if the request has been frozen, or false otherwise
+ */
+ public boolean isFrozen() {
+ return frozen.get();
+ }
+
+ /**
+ * Freeze this request to prevent any further modification. This method does nothing
if the request is already frozen.
+ */
+ public void freeze() {
+ frozen.set(true);
+ }
+
+ /**
+ * Utility method to check that the request is not frozen, and if it is to throw an
{@link IllegalStateException}.
+ *
+ * @throws IllegalStateException if the request is frozen
+ */
+ protected void checkNotFrozen() throws IllegalStateException {
+ if (frozen.get()) {
+ throw new
IllegalStateException(GraphI18n.requestIsFrozenAndMayNotBeChanged.text(this));
+ }
+ }
}
Modified:
trunk/dna-graph/src/main/java/org/jboss/dna/graph/request/SetPropertyRequest.java
===================================================================
---
trunk/dna-graph/src/main/java/org/jboss/dna/graph/request/SetPropertyRequest.java 2009-05-18
15:36:58 UTC (rev 911)
+++
trunk/dna-graph/src/main/java/org/jboss/dna/graph/request/SetPropertyRequest.java 2009-05-19
17:40:25 UTC (rev 912)
@@ -36,7 +36,7 @@
*
* @author Randall Hauch
*/
-public class SetPropertyRequest extends Request implements ChangeRequest {
+public class SetPropertyRequest extends ChangeRequest {
private static final long serialVersionUID = 1L;
@@ -108,8 +108,10 @@
* @param actual the actual location of the node being updated, or null if the {@link
#on() current location} should be used
* @throws IllegalArgumentException if the actual location does represent the {@link
Location#isSame(Location) same location}
* as the {@link #on() current location}, or if the actual location does not
have a path.
+ * @throws IllegalStateException if the request is frozen
*/
public void setActualLocationOfNode( Location actual ) {
+ checkNotFrozen();
if (!on.isSame(actual)) { // not same if actual is null
throw new
IllegalArgumentException(GraphI18n.actualLocationIsNotSameAsInputLocation.text(actual,
on));
}
@@ -134,6 +136,7 @@
*
* @see org.jboss.dna.graph.request.ChangeRequest#changes(java.lang.String,
org.jboss.dna.graph.property.Path)
*/
+ @Override
public boolean changes( String workspace,
Path path ) {
return this.workspaceName.equals(workspace) && on.hasPath() &&
on.getPath().isAtOrBelow(path);
@@ -183,6 +186,7 @@
*
* @see org.jboss.dna.graph.request.ChangeRequest#changedLocation()
*/
+ @Override
public Location changedLocation() {
return on;
}
Modified:
trunk/dna-graph/src/main/java/org/jboss/dna/graph/request/UpdatePropertiesRequest.java
===================================================================
---
trunk/dna-graph/src/main/java/org/jboss/dna/graph/request/UpdatePropertiesRequest.java 2009-05-18
15:36:58 UTC (rev 911)
+++
trunk/dna-graph/src/main/java/org/jboss/dna/graph/request/UpdatePropertiesRequest.java 2009-05-19
17:40:25 UTC (rev 912)
@@ -53,7 +53,7 @@
*
* @author Randall Hauch
*/
-public class UpdatePropertiesRequest extends Request implements ChangeRequest {
+public class UpdatePropertiesRequest extends ChangeRequest {
private static final long serialVersionUID = 1L;
@@ -126,8 +126,10 @@
* @param actual the actual location of the node being updated, or null if the {@link
#on() current location} should be used
* @throws IllegalArgumentException if the actual location does represent the {@link
Location#isSame(Location) same location}
* as the {@link #on() current location}, or if the actual location does not
have a path.
+ * @throws IllegalStateException if the request is frozen
*/
public void setActualLocationOfNode( Location actual ) {
+ checkNotFrozen();
if (!on.isSame(actual)) { // not same if actual is null
throw new
IllegalArgumentException(GraphI18n.actualLocationIsNotSameAsInputLocation.text(actual,
on));
}
@@ -152,6 +154,7 @@
*
* @see org.jboss.dna.graph.request.ChangeRequest#changes(java.lang.String,
org.jboss.dna.graph.property.Path)
*/
+ @Override
public boolean changes( String workspace,
Path path ) {
return this.workspaceName.equals(workspace) && on.hasPath() &&
on.getPath().isAtOrBelow(path);
@@ -201,6 +204,7 @@
*
* @see org.jboss.dna.graph.request.ChangeRequest#changedLocation()
*/
+ @Override
public Location changedLocation() {
return on;
}
Modified:
trunk/dna-graph/src/main/java/org/jboss/dna/graph/request/VerifyNodeExistsRequest.java
===================================================================
---
trunk/dna-graph/src/main/java/org/jboss/dna/graph/request/VerifyNodeExistsRequest.java 2009-05-18
15:36:58 UTC (rev 911)
+++
trunk/dna-graph/src/main/java/org/jboss/dna/graph/request/VerifyNodeExistsRequest.java 2009-05-19
17:40:25 UTC (rev 912)
@@ -91,8 +91,10 @@
* @param actual the actual location of the node being read, or null if the {@link
#at() current location} should be used
* @throws IllegalArgumentException if the actual location does not represent the
{@link Location#isSame(Location) same
* location} as the {@link #at() current location}, or if the actual location
does not have a path.
+ * @throws IllegalStateException if the request is frozen
*/
public void setActualLocationOfNode( Location actual ) {
+ checkNotFrozen();
if (!at.isSame(actual)) { // not same if actual is null
throw new
IllegalArgumentException(GraphI18n.actualLocationIsNotSameAsInputLocation.text(actual,
at));
}
Modified:
trunk/dna-graph/src/main/java/org/jboss/dna/graph/request/VerifyWorkspaceRequest.java
===================================================================
---
trunk/dna-graph/src/main/java/org/jboss/dna/graph/request/VerifyWorkspaceRequest.java 2009-05-18
15:36:58 UTC (rev 911)
+++
trunk/dna-graph/src/main/java/org/jboss/dna/graph/request/VerifyWorkspaceRequest.java 2009-05-19
17:40:25 UTC (rev 912)
@@ -69,8 +69,10 @@
* Set the actual name of the workspace.
*
* @param actualWorkspaceName the actual name of the workspace; never null
+ * @throws IllegalStateException if the request is frozen
*/
public void setActualWorkspaceName( String actualWorkspaceName ) {
+ checkNotFrozen();
CheckArg.isNotNull(actualWorkspaceName, "actualWorkspaceName");
this.actualWorkspaceName = actualWorkspaceName;
}
@@ -88,8 +90,10 @@
* Set the actual location of the root node in the new workspace.
*
* @param actualLocationOfRoot the actual location of the workspace's root node.
+ * @throws IllegalStateException if the request is frozen
*/
public void setActualRootLocation( Location actualLocationOfRoot ) {
+ checkNotFrozen();
this.actualLocationOfRoot = actualLocationOfRoot;
}
Modified:
trunk/dna-graph/src/main/java/org/jboss/dna/graph/request/processor/RequestProcessor.java
===================================================================
---
trunk/dna-graph/src/main/java/org/jboss/dna/graph/request/processor/RequestProcessor.java 2009-05-18
15:36:58 UTC (rev 911)
+++
trunk/dna-graph/src/main/java/org/jboss/dna/graph/request/processor/RequestProcessor.java 2009-05-19
17:40:25 UTC (rev 912)
@@ -187,58 +187,66 @@
*/
public void process( Request request ) {
if (request == null) return;
- if (request.isCancelled()) return;
- if (request instanceof CompositeRequest) {
- process((CompositeRequest)request);
- } else if (request instanceof CopyBranchRequest) {
- process((CopyBranchRequest)request);
- } else if (request instanceof CreateNodeRequest) {
- process((CreateNodeRequest)request);
- } else if (request instanceof DeleteBranchRequest) {
- process((DeleteBranchRequest)request);
- } else if (request instanceof DeleteChildrenRequest) {
- process((DeleteChildrenRequest)request);
- } else if (request instanceof MoveBranchRequest) {
- process((MoveBranchRequest)request);
- } else if (request instanceof ReadAllChildrenRequest) {
- process((ReadAllChildrenRequest)request);
- } else if (request instanceof ReadNextBlockOfChildrenRequest) {
- process((ReadNextBlockOfChildrenRequest)request);
- } else if (request instanceof ReadBlockOfChildrenRequest) {
- process((ReadBlockOfChildrenRequest)request);
- } else if (request instanceof ReadBranchRequest) {
- process((ReadBranchRequest)request);
- } else if (request instanceof ReadNodeRequest) {
- process((ReadNodeRequest)request);
- } else if (request instanceof ReadAllPropertiesRequest) {
- process((ReadAllPropertiesRequest)request);
- } else if (request instanceof ReadPropertyRequest) {
- process((ReadPropertyRequest)request);
- } else if (request instanceof RemovePropertyRequest) {
- process((RemovePropertyRequest)request);
- } else if (request instanceof SetPropertyRequest) {
- process((SetPropertyRequest)request);
- } else if (request instanceof RenameNodeRequest) {
- process((RenameNodeRequest)request);
- } else if (request instanceof UpdatePropertiesRequest) {
- process((UpdatePropertiesRequest)request);
- } else if (request instanceof VerifyNodeExistsRequest) {
- process((VerifyNodeExistsRequest)request);
- } else if (request instanceof VerifyWorkspaceRequest) {
- process((VerifyWorkspaceRequest)request);
- } else if (request instanceof GetWorkspacesRequest) {
- process((GetWorkspacesRequest)request);
- } else if (request instanceof CreateWorkspaceRequest) {
- process((CreateWorkspaceRequest)request);
- } else if (request instanceof CloneWorkspaceRequest) {
- process((CloneWorkspaceRequest)request);
- } else if (request instanceof DestroyWorkspaceRequest) {
- process((DestroyWorkspaceRequest)request);
- } else {
- processUnknownRequest(request);
+ try {
+ if (request.isCancelled()) return;
+ if (request instanceof CompositeRequest) {
+ process((CompositeRequest)request);
+ } else if (request instanceof CopyBranchRequest) {
+ process((CopyBranchRequest)request);
+ } else if (request instanceof CreateNodeRequest) {
+ process((CreateNodeRequest)request);
+ } else if (request instanceof DeleteBranchRequest) {
+ process((DeleteBranchRequest)request);
+ } else if (request instanceof DeleteChildrenRequest) {
+ process((DeleteChildrenRequest)request);
+ } else if (request instanceof MoveBranchRequest) {
+ process((MoveBranchRequest)request);
+ } else if (request instanceof ReadAllChildrenRequest) {
+ process((ReadAllChildrenRequest)request);
+ } else if (request instanceof ReadNextBlockOfChildrenRequest) {
+ process((ReadNextBlockOfChildrenRequest)request);
+ } else if (request instanceof ReadBlockOfChildrenRequest) {
+ process((ReadBlockOfChildrenRequest)request);
+ } else if (request instanceof ReadBranchRequest) {
+ process((ReadBranchRequest)request);
+ } else if (request instanceof ReadNodeRequest) {
+ process((ReadNodeRequest)request);
+ } else if (request instanceof ReadAllPropertiesRequest) {
+ process((ReadAllPropertiesRequest)request);
+ } else if (request instanceof ReadPropertyRequest) {
+ process((ReadPropertyRequest)request);
+ } else if (request instanceof RemovePropertyRequest) {
+ process((RemovePropertyRequest)request);
+ } else if (request instanceof SetPropertyRequest) {
+ process((SetPropertyRequest)request);
+ } else if (request instanceof RenameNodeRequest) {
+ process((RenameNodeRequest)request);
+ } else if (request instanceof UpdatePropertiesRequest) {
+ process((UpdatePropertiesRequest)request);
+ } else if (request instanceof VerifyNodeExistsRequest) {
+ process((VerifyNodeExistsRequest)request);
+ } else if (request instanceof VerifyWorkspaceRequest) {
+ process((VerifyWorkspaceRequest)request);
+ } else if (request instanceof GetWorkspacesRequest) {
+ process((GetWorkspacesRequest)request);
+ } else if (request instanceof CreateWorkspaceRequest) {
+ process((CreateWorkspaceRequest)request);
+ } else if (request instanceof CloneWorkspaceRequest) {
+ process((CloneWorkspaceRequest)request);
+ } else if (request instanceof DestroyWorkspaceRequest) {
+ process((DestroyWorkspaceRequest)request);
+ } else {
+ processUnknownRequest(request);
+ }
+ } finally {
+ completeRequest(request);
}
}
+ protected void completeRequest( Request request ) {
+ request.freeze();
+ }
+
/**
* Process a request that is composed of multiple other (non-composite) requests. If
any of the embedded requests
* {@link Request#hasError() has an error} after it is processed, the submitted
request will be marked with an error.
Modified: trunk/dna-graph/src/main/resources/org/jboss/dna/graph/GraphI18n.properties
===================================================================
--- trunk/dna-graph/src/main/resources/org/jboss/dna/graph/GraphI18n.properties 2009-05-18
15:36:58 UTC (rev 911)
+++ trunk/dna-graph/src/main/resources/org/jboss/dna/graph/GraphI18n.properties 2009-05-19
17:40:25 UTC (rev 912)
@@ -71,6 +71,7 @@
actualOldLocationMustHavePath = The actual old location of {0} must have a path
actualNewLocationMustHaveSameParentAsOldLocation = The new location of {0} must be a
sibling of the old location of {1}
actualNewLocationMustHaveSameNameAsRequest = The new location of {0} must have the same
name as in the request ({1})
+requestIsFrozenAndMayNotBeChanged = Request is frozen and may not be changed: {0}
errorImportingContent = Error importing {0} content from {1}
unableToFindRepositorySourceWithName = Unable to find a repository source named
"{0}"
Modified:
trunk/extensions/dna-connector-federation/src/main/java/org/jboss/dna/connector/federation/FederatingRequestProcessor.java
===================================================================
---
trunk/extensions/dna-connector-federation/src/main/java/org/jboss/dna/connector/federation/FederatingRequestProcessor.java 2009-05-18
15:36:58 UTC (rev 911)
+++
trunk/extensions/dna-connector-federation/src/main/java/org/jboss/dna/connector/federation/FederatingRequestProcessor.java 2009-05-19
17:40:25 UTC (rev 912)
@@ -324,8 +324,8 @@
}
// Delete in the cache ...
- DeleteBranchRequest cacheRequest = new DeleteBranchRequest(request.at(),
-
workspace.getCacheProjection().getWorkspaceName());
+ DeleteBranchRequest cacheRequest = new DeleteBranchRequest(request.at(),
workspace.getCacheProjection()
+
.getWorkspaceName());
executeInCache(cacheRequest, workspace);
}
@@ -379,8 +379,8 @@
}
// Delete from the cache the parent of the new location ...
- DeleteBranchRequest cacheRequest = new DeleteBranchRequest(request.into(),
-
fromWorkspace.getCacheProjection().getWorkspaceName());
+ DeleteBranchRequest cacheRequest = new DeleteBranchRequest(request.into(),
fromWorkspace.getCacheProjection()
+
.getWorkspaceName());
executeInCache(cacheRequest, fromWorkspace);
}
@@ -425,8 +425,8 @@
intoProjection.convertToRepository(sourceRequest.getActualLocationAfter()));
}
// Delete from the cache ...
- DeleteBranchRequest cacheRequest = new DeleteBranchRequest(request.from(),
-
workspace.getCacheProjection().getWorkspaceName());
+ DeleteBranchRequest cacheRequest = new DeleteBranchRequest(request.from(),
workspace.getCacheProjection()
+
.getWorkspaceName());
executeInCache(cacheRequest, workspace);
// Mark the new parent node as being expired ...
cacheRequest = new DeleteBranchRequest(request.into(),
workspace.getCacheProjection().getWorkspaceName());
@@ -461,8 +461,8 @@
}
// Update the cache ...
- UpdatePropertiesRequest cacheRequest = new UpdatePropertiesRequest(request.on(),
-
workspace.getCacheProjection().getWorkspaceName(),
+ UpdatePropertiesRequest cacheRequest = new UpdatePropertiesRequest(request.on(),
workspace.getCacheProjection()
+
.getWorkspaceName(),
request.properties());
executeInCache(cacheRequest, workspace);
}
@@ -647,7 +647,10 @@
// that already exists in the cache.
PathNotFoundException notFound =
(PathNotFoundException)fromCache.getError();
Path lowestExistingAncestor = notFound.getLowestAncestorThatDoesExist();
+
if (location.hasPath()) {
+ // Create a new instance so that we can update it ...
+ fromCache = new ReadNodeRequest(location,
workspace.getCacheProjection().getWorkspaceName());
Path path = location.getPath();
Path ancestor = path.getParent();
if (!ancestor.equals(lowestExistingAncestor)) {
@@ -1144,9 +1147,9 @@
readable(registry, create.properties()));
} else if (request instanceof UpdatePropertiesRequest) {
UpdatePropertiesRequest update = (UpdatePropertiesRequest)request;
- logger.trace(" updating {0} with properties {1}",
- update.on().getString(registry),
- readable(registry, update.properties().values()));
+ logger.trace(" updating {0} with properties {1}",
update.on().getString(registry), readable(registry,
+
update.properties()
+
.values()));
} else {
logger.trace(" " + request.toString());
}
@@ -1165,9 +1168,9 @@
readable(registry, create.properties()));
} else if (request instanceof UpdatePropertiesRequest) {
UpdatePropertiesRequest update = (UpdatePropertiesRequest)request;
- logger.trace(" updating {0} with properties {1}",
- update.on().getString(registry),
- readable(registry, update.properties().values()));
+ logger.trace(" updating {0} with properties {1}",
update.on().getString(registry), readable(registry,
+
update.properties()
+
.values()));
} else {
logger.trace(" " + request.toString());
}