Author: rhauch
Date: 2009-04-07 17:23:28 -0400 (Tue, 07 Apr 2009)
New Revision: 809
Added:
trunk/dna-graph/src/main/java/org/jboss/dna/graph/request/BatchRequestBuilder.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/RequestBuilder.java
trunk/dna-graph/src/main/java/org/jboss/dna/graph/request/SetPropertyRequest.java
Removed:
trunk/dna-graph/src/main/java/org/jboss/dna/graph/request/RemovePropertiesRequest.java
trunk/dna-graph/src/test/java/org/jboss/dna/graph/request/RemovePropertiesRequestTest.java
Modified:
trunk/dna-graph/src/main/java/org/jboss/dna/graph/Graph.java
trunk/dna-graph/src/main/java/org/jboss/dna/graph/GraphImporter.java
trunk/dna-graph/src/main/java/org/jboss/dna/graph/connector/inmemory/InMemoryRequestProcessor.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/DeleteBranchRequest.java
trunk/dna-graph/src/main/java/org/jboss/dna/graph/request/DestroyWorkspaceRequest.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/package-info.java
trunk/dna-graph/src/main/java/org/jboss/dna/graph/request/processor/LoggingRequestProcessor.java
trunk/dna-graph/src/main/java/org/jboss/dna/graph/request/processor/RequestProcessor.java
trunk/dna-graph/src/test/java/org/jboss/dna/graph/GraphTest.java
trunk/dna-graph/src/test/java/org/jboss/dna/graph/connector/test/AbstractConnectorTest.java
trunk/dna-graph/src/test/java/org/jboss/dna/graph/request/UpdatePropertiesRequestTest.java
trunk/dna-jcr/src/main/java/org/jboss/dna/jcr/SessionCache.java
trunk/extensions/dna-connector-filesystem/src/main/java/org/jboss/dna/connector/filesystem/FileSystemRequestProcessor.java
trunk/extensions/dna-connector-jbosscache/src/main/java/org/jboss/dna/connector/jbosscache/JBossCacheRequestProcessor.java
trunk/extensions/dna-connector-store-jpa/src/main/java/org/jboss/dna/connector/store/jpa/model/basic/BasicRequestProcessor.java
trunk/extensions/dna-connector-store-jpa/src/main/java/org/jboss/dna/connector/store/jpa/util/Serializer.java
trunk/extensions/dna-connector-store-jpa/src/test/java/org/jboss/dna/connector/store/jpa/JpaConnectorReadingTest.java
trunk/extensions/dna-connector-store-jpa/src/test/java/org/jboss/dna/connector/store/jpa/util/SerializerTest.java
trunk/extensions/dna-connector-svn/src/main/java/org/jboss/dna/connector/svn/SVNRepositoryRequestProcessor.java
Log:
DNA-341 Graph API behavior when removing all property values doesn't reflect that of
JCR
Applied patch that changes the connector API. Specifically the semantics and a few method
signatures of UpdatePropertiesRequest class were changed to no longer assume that an empty
property should be removed; rather, the names of properties that are to be removed are
tracked explicitly, and the number of values in a property no longer has any relationship
to whether the property is to be removed. All connectors were changed to apply these new
semantics.
A number of other changes to the connector API were made. New SetPropertyRequest and
RemovePropertyRequest requests types were added as being more efficient when a single
property is being set or removed. These are optional requests, meaning that the
RequestProcessor has default implementations for the corresponding "process"
methods that convert the reqeusts to UpdatedPropertiesRequest. Thus, a connector
doesn't have to implement these, but it may be more efficient for it to do so. The
RemovedPropertiesRequest was also removed, since it didn't offer any benefit over
UpdatePropertiesRequest (and since it is simpler to only have one). All connectors were
updated to reflect these semantics.
Also, the Graph batch implementation was improved to optimize adjacent calls to set/remove
properties on the same node. In other words, if a batch is used to set a property on node
A and then is immediately used to set another property on the same node, the batch will
combine the two requests. However, this optimization does not apply if any other
operations are performed between the set/remove property operations.
Finally, a minor error was found and corrected in how the connector unit tests reported
the (trivial) metrics for creating nodes. The total times (line 2) were correct, but the
average and the times for additional nodes (line 3) were all incorrect.
Modified: trunk/dna-graph/src/main/java/org/jboss/dna/graph/Graph.java
===================================================================
--- trunk/dna-graph/src/main/java/org/jboss/dna/graph/Graph.java 2009-04-06 15:55:23 UTC
(rev 808)
+++ trunk/dna-graph/src/main/java/org/jboss/dna/graph/Graph.java 2009-04-07 21:23:28 UTC
(rev 809)
@@ -43,6 +43,7 @@
import java.util.UUID;
import net.jcip.annotations.Immutable;
import net.jcip.annotations.NotThreadSafe;
+import org.jboss.dna.common.collection.EmptyIterator;
import org.jboss.dna.common.util.CheckArg;
import org.jboss.dna.graph.cache.CachePolicy;
import org.jboss.dna.graph.connector.RepositoryConnection;
@@ -60,27 +61,22 @@
import org.jboss.dna.graph.property.Reference;
import org.jboss.dna.graph.property.ValueFormatException;
import org.jboss.dna.graph.property.Path.Segment;
+import org.jboss.dna.graph.request.BatchRequestBuilder;
import org.jboss.dna.graph.request.CloneWorkspaceRequest;
import org.jboss.dna.graph.request.CompositeRequest;
-import org.jboss.dna.graph.request.CopyBranchRequest;
import org.jboss.dna.graph.request.CreateNodeRequest;
import org.jboss.dna.graph.request.CreateWorkspaceRequest;
-import org.jboss.dna.graph.request.DeleteBranchRequest;
-import org.jboss.dna.graph.request.GetWorkspacesRequest;
import org.jboss.dna.graph.request.InvalidRequestException;
import org.jboss.dna.graph.request.InvalidWorkspaceException;
-import org.jboss.dna.graph.request.MoveBranchRequest;
import org.jboss.dna.graph.request.ReadAllChildrenRequest;
import org.jboss.dna.graph.request.ReadAllPropertiesRequest;
import org.jboss.dna.graph.request.ReadBlockOfChildrenRequest;
import org.jboss.dna.graph.request.ReadBranchRequest;
-import org.jboss.dna.graph.request.ReadNextBlockOfChildrenRequest;
import org.jboss.dna.graph.request.ReadNodeRequest;
import org.jboss.dna.graph.request.ReadPropertyRequest;
-import org.jboss.dna.graph.request.RemovePropertiesRequest;
import org.jboss.dna.graph.request.Request;
+import org.jboss.dna.graph.request.RequestBuilder;
import org.jboss.dna.graph.request.UnsupportedRequestException;
-import org.jboss.dna.graph.request.UpdatePropertiesRequest;
import org.jboss.dna.graph.request.VerifyWorkspaceRequest;
import org.jboss.dna.graph.request.CloneWorkspaceRequest.CloneConflictBehavior;
import org.jboss.dna.graph.request.CreateWorkspaceRequest.CreateConflictBehavior;
@@ -97,6 +93,13 @@
@NotThreadSafe
public class Graph {
+ protected static final Iterator<Property> EMPTY_PROPERTIES = new
EmptyIterator<Property>();
+ protected static final Iterable<Property> NO_PROPERTIES = new
Iterable<Property>() {
+ public final Iterator<Property> iterator() {
+ return EMPTY_PROPERTIES;
+ }
+ };
+
/**
* Create a graph instance that uses the supplied repository and {@link
ExecutionContext context}.
*
@@ -157,8 +160,8 @@
private final String sourceName;
private final RepositoryConnectionFactory connectionFactory;
private final ExecutionContext context;
- private final RequestQueue requestQueue;
- private final Conjunction<Graph> nextGraph;
+ protected final RequestBuilder requests;
+ protected final Conjunction<Graph> nextGraph;
private Workspace currentWorkspace;
protected Graph( String sourceName,
@@ -175,7 +178,13 @@
return Graph.this;
}
};
- this.requestQueue = new GraphRequestQueue();
+ this.requests = new RequestBuilder() {
+ @Override
+ protected <T extends Request> T process( T request ) {
+ Graph.this.execute(request);
+ return request;
+ }
+ };
}
/**
@@ -207,16 +216,12 @@
return context;
}
- /*package*/RequestQueue queue() {
- return this.requestQueue;
- }
-
/**
* Obtain a connection to the source, execute the supplied request, and check the
request for {@link Request#getError()
* errors}. If an error is found, then it is thrown (or wrapped by a {@link
RepositorySourceException} if the error is not a
* {@link RuntimeException}.
* <p>
- * This method is called by one of the {@link RequestQueue} implementations.
+ * This method is called automatically when the {@link #requests request builder}
creates each request.
* </p>
*
* @param request the request to be executed (may be a {@link CompositeRequest}.
@@ -314,9 +319,7 @@
* @return the set of workspace names; never null
*/
public Set<String> getWorkspaces() {
- GetWorkspacesRequest request = new GetWorkspacesRequest();
- this.requestQueue.submit(request);
- return request.getAvailableWorkspaceNames();
+ return requests.getWorkspaces().getAvailableWorkspaceNames();
}
/**
@@ -329,8 +332,7 @@
* workspace name but the source does not have a default workspace
*/
public Workspace useWorkspace( String workspaceName ) {
- VerifyWorkspaceRequest request = new VerifyWorkspaceRequest(workspaceName);
- requestQueue.submit(request); // will throw error if there is one ...
+ VerifyWorkspaceRequest request = requests.verifyWorkspace(workspaceName);
return setWorkspace(request.getActualWorkspaceName(),
request.getActualLocationOfRoot());
}
@@ -349,8 +351,7 @@
* @see org.jboss.dna.graph.Graph.NameWorkspace#named(java.lang.String)
*/
public Workspace named( String workspaceName ) {
- CreateWorkspaceRequest request = new
CreateWorkspaceRequest(workspaceName, CreateConflictBehavior.DO_NOT_CREATE);
- queue().submit(request); // will throw error if there is one ...
+ CreateWorkspaceRequest request = requests.createWorkspace(workspaceName,
CreateConflictBehavior.DO_NOT_CREATE);
return setWorkspace(request.getActualWorkspaceName(),
request.getActualLocationOfRoot());
}
@@ -360,9 +361,8 @@
* @see
org.jboss.dna.graph.Graph.CreateWorkspace#namedSomethingLike(java.lang.String)
*/
public Workspace namedSomethingLike( String workspaceName ) {
- CreateWorkspaceRequest request = new
CreateWorkspaceRequest(workspaceName,
-
CreateConflictBehavior.CREATE_WITH_ADJUSTED_NAME);
- queue().submit(request); // will throw error if there is one ...
+ CreateWorkspaceRequest request = requests.createWorkspace(workspaceName,
+
CreateConflictBehavior.CREATE_WITH_ADJUSTED_NAME);
return setWorkspace(request.getActualWorkspaceName(),
request.getActualLocationOfRoot());
}
@@ -379,11 +379,10 @@
* @see
org.jboss.dna.graph.Graph.NameWorkspace#named(java.lang.String)
*/
public Workspace named( String nameOfWorkspaceToCreate ) {
- CloneWorkspaceRequest request = new
CloneWorkspaceRequest(nameOfWorkspaceToClone,
-
nameOfWorkspaceToCreate,
-
CreateConflictBehavior.DO_NOT_CREATE,
-
CloneConflictBehavior.DO_NOT_CLONE);
- queue().submit(request); // will throw error if there is one ...
+ CloneWorkspaceRequest request =
requests.cloneWorkspace(nameOfWorkspaceToClone,
+
nameOfWorkspaceToCreate,
+
CreateConflictBehavior.DO_NOT_CREATE,
+
CloneConflictBehavior.DO_NOT_CLONE);
return setWorkspace(request.getActualWorkspaceName(),
request.getActualLocationOfRoot());
}
@@ -393,12 +392,10 @@
* @see
org.jboss.dna.graph.Graph.NameWorkspace#namedSomethingLike(java.lang.String)
*/
public Workspace namedSomethingLike( String nameOfWorkspaceToCreate )
{
- CloneWorkspaceRequest request = new CloneWorkspaceRequest(
-
nameOfWorkspaceToClone,
-
nameOfWorkspaceToCreate,
-
CreateConflictBehavior.CREATE_WITH_ADJUSTED_NAME,
-
CloneConflictBehavior.DO_NOT_CLONE);
- queue().submit(request); // will throw error if there is one ...
+ CloneWorkspaceRequest request =
requests.cloneWorkspace(nameOfWorkspaceToClone,
+
nameOfWorkspaceToCreate,
+
CreateConflictBehavior.CREATE_WITH_ADJUSTED_NAME,
+
CloneConflictBehavior.DO_NOT_CLONE);
return setWorkspace(request.getActualWorkspaceName(),
request.getActualLocationOfRoot());
}
};
@@ -419,7 +416,7 @@
* be moved
*/
public Move<Conjunction<Graph>> move( Node from ) {
- return new MoveAction<Conjunction<Graph>>(this.nextGraph,
this.requestQueue, from.getLocation());
+ return move(from.getLocation());
}
/**
@@ -435,7 +432,17 @@
* be moved
*/
public Move<Conjunction<Graph>> move( Location from ) {
- return new MoveAction<Conjunction<Graph>>(this.nextGraph,
this.requestQueue, from);
+ return new MoveAction<Conjunction<Graph>>(this.nextGraph, from) {
+ @Override
+ protected Conjunction<Graph> submit( Locations from,
+ Location into ) {
+ String workspaceName = getCurrentWorkspaceName();
+ do {
+ requests.moveBranch(from.getLocation(), into, workspaceName);
+ } while ((from = from.next()) != null);
+ return and();
+ }
+ };
}
/**
@@ -451,7 +458,7 @@
* be moved
*/
public Move<Conjunction<Graph>> move( String fromPath ) {
- return new MoveAction<Conjunction<Graph>>(this.nextGraph,
this.requestQueue, Location.create(createPath(fromPath)));
+ return move(Location.create(createPath(fromPath)));
}
/**
@@ -467,7 +474,7 @@
* be moved
*/
public Move<Conjunction<Graph>> move( Path from ) {
- return new MoveAction<Conjunction<Graph>>(this.nextGraph,
this.requestQueue, Location.create(from));
+ return move(Location.create(from));
}
/**
@@ -483,7 +490,7 @@
* be moved
*/
public Move<Conjunction<Graph>> move( UUID from ) {
- return new MoveAction<Conjunction<Graph>>(this.nextGraph,
this.requestQueue, Location.create(from));
+ return move(Location.create(from));
}
/**
@@ -500,7 +507,7 @@
* be moved
*/
public Move<Conjunction<Graph>> move( Property idProperty ) {
- return new MoveAction<Conjunction<Graph>>(this.nextGraph,
this.requestQueue, Location.create(idProperty));
+ return move(Location.create(idProperty));
}
/**
@@ -519,8 +526,7 @@
*/
public Move<Conjunction<Graph>> move( Property firstIdProperty,
Property... additionalIdProperties ) {
- return new MoveAction<Conjunction<Graph>>(this.nextGraph,
this.requestQueue, Location.create(firstIdProperty,
-
additionalIdProperties));
+ return move(Location.create(firstIdProperty, additionalIdProperties));
}
/**
@@ -536,7 +542,7 @@
* be copied
*/
public Copy<Graph> copy( Node from ) {
- return new CopyAction<Graph>(this, this.requestQueue, from.getLocation());
+ return copy(from.getLocation());
}
/**
@@ -552,7 +558,23 @@
* be copied
*/
public Copy<Graph> copy( Location from ) {
- return new CopyAction<Graph>(this, this.requestQueue, from);
+ return new CopyAction<Graph>(this, from) {
+ @Override
+ protected Graph submit( Locations from,
+ Location into,
+ Name childName ) {
+ String workspaceName = getCurrentWorkspaceName();
+ do {
+ requests.copyBranch(from.getLocation(),
+ workspaceName,
+ into,
+ workspaceName,
+ childName,
+ NodeConflictBehavior.APPEND);
+ } while ((from = from.next()) != null);
+ return and();
+ }
+ };
}
/**
@@ -568,7 +590,7 @@
* be copied
*/
public Copy<Graph> copy( String fromPath ) {
- return new CopyAction<Graph>(this, this.requestQueue,
Location.create(createPath(fromPath)));
+ return copy(Location.create(createPath(fromPath)));
}
/**
@@ -584,7 +606,7 @@
* be copied
*/
public Copy<Graph> copy( Path from ) {
- return new CopyAction<Graph>(this, this.requestQueue,
Location.create(from));
+ return copy(Location.create(from));
}
/**
@@ -600,7 +622,7 @@
* be copied
*/
public Copy<Graph> copy( UUID from ) {
- return new CopyAction<Graph>(this, this.requestQueue,
Location.create(from));
+ return copy(Location.create(from));
}
/**
@@ -617,7 +639,7 @@
* be copied
*/
public Copy<Graph> copy( Property idProperty ) {
- return new CopyAction<Graph>(this, this.requestQueue,
Location.create(idProperty));
+ return copy(Location.create(idProperty));
}
/**
@@ -636,7 +658,7 @@
*/
public Copy<Graph> copy( Property firstIdProperty,
Property... additionalIdProperties ) {
- return new CopyAction<Graph>(this, this.requestQueue,
Location.create(firstIdProperty, additionalIdProperties));
+ return copy(Location.create(firstIdProperty, additionalIdProperties));
}
/**
@@ -646,7 +668,7 @@
* @return an object that may be used to start another request
*/
public Conjunction<Graph> delete( Node at ) {
- this.requestQueue.submit(new DeleteBranchRequest(at.getLocation(),
getCurrentWorkspaceName()));
+ requests.deleteBranch(at.getLocation(), getCurrentWorkspaceName());
return nextGraph;
}
@@ -657,7 +679,7 @@
* @return an object that may be used to start another request
*/
public Conjunction<Graph> delete( Location at ) {
- this.requestQueue.submit(new DeleteBranchRequest(at,
getCurrentWorkspaceName()));
+ requests.deleteBranch(at, getCurrentWorkspaceName());
return nextGraph;
}
@@ -668,8 +690,7 @@
* @return an object that may be used to start another request
*/
public Conjunction<Graph> delete( String atPath ) {
- this.requestQueue.submit(new
DeleteBranchRequest(Location.create(createPath(atPath)), getCurrentWorkspaceName()));
- return nextGraph;
+ return delete(Location.create(createPath(atPath)));
}
/**
@@ -679,8 +700,7 @@
* @return an object that may be used to start another request
*/
public Conjunction<Graph> delete( Path at ) {
- this.requestQueue.submit(new DeleteBranchRequest(Location.create(at),
getCurrentWorkspaceName()));
- return nextGraph;
+ return delete(Location.create(at));
}
/**
@@ -690,8 +710,7 @@
* @return an object that may be used to start another request
*/
public Conjunction<Graph> delete( UUID at ) {
- this.requestQueue.submit(new DeleteBranchRequest(Location.create(at),
getCurrentWorkspaceName()));
- return nextGraph;
+ return delete(Location.create(at));
}
/**
@@ -702,8 +721,7 @@
* @return an object that may be used to start another request
*/
public Conjunction<Graph> delete( Property idProperty ) {
- this.requestQueue.submit(new DeleteBranchRequest(Location.create(idProperty),
getCurrentWorkspaceName()));
- return nextGraph;
+ return delete(Location.create(idProperty));
}
/**
@@ -716,9 +734,7 @@
*/
public Conjunction<Graph> delete( Property firstIdProperty,
Property... additionalIdProperties ) {
- this.requestQueue.submit(new DeleteBranchRequest(Location.create(firstIdProperty,
additionalIdProperties),
- getCurrentWorkspaceName()));
- return nextGraph;
+ return delete(Location.create(firstIdProperty, additionalIdProperties));
}
/**
@@ -758,7 +774,7 @@
private final List<Property> properties = new
LinkedList<Property>();
public CreateAt<Graph> and( UUID uuid ) {
- PropertyFactory factory =
queue().getGraph().getContext().getPropertyFactory();
+ PropertyFactory factory = getContext().getPropertyFactory();
properties.add(factory.create(DnaLexicon.UUID, uuid));
return this;
}
@@ -777,7 +793,7 @@
public CreateAt<Graph> and( String name,
Object... values ) {
- ExecutionContext context = queue().getGraph().getContext();
+ ExecutionContext context = getContext();
PropertyFactory factory = context.getPropertyFactory();
NameFactory nameFactory = context.getValueFactories().getNameFactory();
properties.add(factory.create(nameFactory.create(name), values));
@@ -786,7 +802,7 @@
public CreateAt<Graph> and( Name name,
Object... values ) {
- ExecutionContext context = queue().getGraph().getContext();
+ ExecutionContext context = getContext();
PropertyFactory factory = context.getPropertyFactory();
properties.add(factory.create(name, values));
return this;
@@ -830,20 +846,18 @@
public Location getLocation() {
Location parentLoc = Location.create(parent);
- CreateNodeRequest request = new CreateNodeRequest(parentLoc,
workspaceName, childName, this.properties);
- queue().submit(request); // immediate
+ CreateNodeRequest request = requests.createNode(parentLoc, workspaceName,
childName, this.properties.iterator());
return request.getActualLocationOfNode();
}
public Node getNode() {
Location parentLoc = Location.create(parent);
- CreateNodeRequest request = new CreateNodeRequest(parentLoc,
workspaceName, childName, this.properties);
- queue().submit(request); // immediate
+ CreateNodeRequest request = requests.createNode(parentLoc, workspaceName,
childName, this.properties.iterator());
return getNodeAt(request.getActualLocationOfNode());
}
public Graph and() {
- queue().submit(new CreateNodeRequest(Location.create(parent),
workspaceName, childName, this.properties));
+ requests.createNode(Location.create(parent), workspaceName, childName,
this.properties.iterator());
return Graph.this;
}
};
@@ -864,7 +878,7 @@
Path at = createPath(atPath);
Path parent = at.getParent();
Name child = at.getLastSegment().getName();
- this.requestQueue.submit(new CreateNodeRequest(Location.create(parent),
getCurrentWorkspaceName(), child));
+ requests.createNode(Location.create(parent), getCurrentWorkspaceName(), child,
EMPTY_PROPERTIES);
return nextGraph;
}
@@ -882,7 +896,7 @@
public Conjunction<Graph> create( final Path at ) {
Path parent = at.getParent();
Name child = at.getLastSegment().getName();
- this.requestQueue.submit(new CreateNodeRequest(Location.create(parent),
getCurrentWorkspaceName(), child));
+ requests.createNode(Location.create(parent), getCurrentWorkspaceName(), child,
EMPTY_PROPERTIES);
return nextGraph;
}
@@ -903,7 +917,7 @@
Path at = createPath(atPath);
Path parent = at.getParent();
Name child = at.getLastSegment().getName();
- this.requestQueue.submit(new CreateNodeRequest(Location.create(parent),
getCurrentWorkspaceName(), child, properties));
+ requests.createNode(Location.create(parent), getCurrentWorkspaceName(), child,
properties);
return nextGraph;
}
@@ -924,7 +938,7 @@
CheckArg.isNotNull(at, "at");
Path parent = at.getParent();
Name child = at.getLastSegment().getName();
- this.requestQueue.submit(new CreateNodeRequest(Location.create(parent),
getCurrentWorkspaceName(), child, properties));
+ requests.createNode(Location.create(parent), getCurrentWorkspaceName(), child,
properties);
return nextGraph;
}
@@ -945,7 +959,7 @@
CheckArg.isNotNull(at, "at");
Path parent = at.getParent();
Name child = at.getLastSegment().getName();
- this.requestQueue.submit(new CreateNodeRequest(Location.create(parent),
getCurrentWorkspaceName(), child, properties));
+ requests.createNode(Location.create(parent), getCurrentWorkspaceName(), child,
properties.iterator());
return nextGraph;
}
@@ -964,27 +978,24 @@
final NameFactory nameFactory =
getContext().getValueFactories().getNameFactory();
CheckArg.isNotNull(parent, "parent");
return new CreateNode<Conjunction<Graph>>() {
- @SuppressWarnings( "synthetic-access" )
public Conjunction<Graph> node( String name,
Property... properties ) {
Name child = nameFactory.create(name);
- requestQueue.submit(new CreateNodeRequest(parent,
getCurrentWorkspaceName(), child, properties));
+ requests.createNode(parent, getCurrentWorkspaceName(), child,
properties);
return nextGraph;
}
- @SuppressWarnings( "synthetic-access" )
public Conjunction<Graph> node( String name,
Iterator<Property> properties ) {
Name child = nameFactory.create(name);
- requestQueue.submit(new CreateNodeRequest(parent,
getCurrentWorkspaceName(), child, properties));
+ requests.createNode(parent, getCurrentWorkspaceName(), child,
properties);
return nextGraph;
}
- @SuppressWarnings( "synthetic-access" )
public Conjunction<Graph> node( String name,
Iterable<Property> properties ) {
Name child = nameFactory.create(name);
- requestQueue.submit(new CreateNodeRequest(parent,
getCurrentWorkspaceName(), child, properties));
+ requests.createNode(parent, getCurrentWorkspaceName(), child,
properties.iterator());
return nextGraph;
}
};
@@ -998,10 +1009,8 @@
*/
public On<Conjunction<Graph>> set( final Property... properties ) {
return new On<Conjunction<Graph>>() {
- @SuppressWarnings( "synthetic-access" )
public Conjunction<Graph> on( Location location ) {
- UpdatePropertiesRequest request = new UpdatePropertiesRequest(location,
getCurrentWorkspaceName(), properties);
- queue().submit(request);
+ requests.setProperties(location, getCurrentWorkspaceName(), properties);
return nextGraph;
}
@@ -1053,7 +1062,6 @@
*/
public SetValues<Conjunction<Graph>> set( final Name propertyName ) {
return new SetValues<Conjunction<Graph>>() {
- @SuppressWarnings( "synthetic-access" )
public SetValuesTo<Conjunction<Graph>> on( final Location
location ) {
return new SetValuesTo<Conjunction<Graph>>() {
public Conjunction<Graph> to( Node value ) {
@@ -1063,17 +1071,13 @@
public Conjunction<Graph> to( Location value ) {
Reference ref = (Reference)convertReferenceValue(value);
Property property =
getContext().getPropertyFactory().create(propertyName, ref);
- UpdatePropertiesRequest request = new
UpdatePropertiesRequest(location, getCurrentWorkspaceName(),
-
property);
- queue().submit(request);
+ requests.setProperty(location, getCurrentWorkspaceName(),
property);
return nextGraph;
}
protected Conjunction<Graph> toValue( Object value ) {
Property property =
getContext().getPropertyFactory().create(propertyName, value);
- UpdatePropertiesRequest request = new
UpdatePropertiesRequest(location, getCurrentWorkspaceName(),
-
property);
- queue().submit(request);
+ requests.setProperty(location, getCurrentWorkspaceName(),
property);
return nextGraph;
}
@@ -1160,9 +1164,7 @@
public Conjunction<Graph> to( Object value ) {
value = convertReferenceValue(value);
Property property =
getContext().getPropertyFactory().create(propertyName, value);
- UpdatePropertiesRequest request = new
UpdatePropertiesRequest(location, getCurrentWorkspaceName(),
-
property);
- queue().submit(request);
+ requests.setProperty(location, getCurrentWorkspaceName(),
property);
return nextGraph;
}
@@ -1173,9 +1175,7 @@
otherValues[i] = convertReferenceValue(otherValues[i]);
}
Property property =
getContext().getPropertyFactory().create(propertyName, firstValue, otherValues);
- UpdatePropertiesRequest request = new
UpdatePropertiesRequest(location, getCurrentWorkspaceName(),
-
property);
- queue().submit(request);
+ requests.setProperty(location, getCurrentWorkspaceName(),
property);
return nextGraph;
}
@@ -1186,9 +1186,7 @@
valueList.add(value);
}
Property property =
getContext().getPropertyFactory().create(propertyName, valueList);
- UpdatePropertiesRequest request = new
UpdatePropertiesRequest(location, getCurrentWorkspaceName(),
-
property);
- queue().submit(request);
+ requests.setProperty(location, getCurrentWorkspaceName(),
property);
return nextGraph;
}
@@ -1199,9 +1197,7 @@
valueList.add(value);
}
Property property =
getContext().getPropertyFactory().create(propertyName, valueList);
- UpdatePropertiesRequest request = new
UpdatePropertiesRequest(location, getCurrentWorkspaceName(),
-
property);
- queue().submit(request);
+ requests.setProperty(location, getCurrentWorkspaceName(),
property);
return nextGraph;
}
};
@@ -1368,10 +1364,8 @@
*/
public On<Conjunction<Graph>> remove( final Name... propertyNames ) {
return new On<Conjunction<Graph>>() {
- @SuppressWarnings( "synthetic-access" )
public Conjunction<Graph> on( Location location ) {
- RemovePropertiesRequest request = new RemovePropertiesRequest(location,
getCurrentWorkspaceName(), propertyNames);
- queue().submit(request);
+ requests.removeProperties(location, getCurrentWorkspaceName(),
propertyNames);
return nextGraph;
}
@@ -1408,17 +1402,16 @@
* @param propertyNames the names of the properties to be removed
* @return the remove request object that should be used to specify the node from
which the properties are to be removed.
*/
- public On<Conjunction<Graph>> remove( String... propertyNames ) {
+ public On<Conjunction<Graph>> remove( final String... propertyNames ) {
NameFactory nameFactory = getContext().getValueFactories().getNameFactory();
- final List<Name> names = new LinkedList<Name>();
- for (String propertyName : propertyNames) {
- names.add(nameFactory.create(propertyName));
+ int number = propertyNames.length;
+ final Name[] names = new Name[number];
+ for (int i = 0; i != number; ++i) {
+ names[i] = nameFactory.create(propertyNames[i]);
}
return new On<Conjunction<Graph>>() {
- @SuppressWarnings( "synthetic-access" )
public Conjunction<Graph> on( Location location ) {
- RemovePropertiesRequest request = new RemovePropertiesRequest(location,
getCurrentWorkspaceName(), names);
- queue().submit(request);
+ requests.removeProperties(location, getCurrentWorkspaceName(), names);
return nextGraph;
}
@@ -1458,9 +1451,7 @@
public On<Collection<Property>> getProperties() {
return new On<Collection<Property>>() {
public Collection<Property> on( Location location ) {
- ReadAllPropertiesRequest request = new ReadAllPropertiesRequest(location,
getCurrentWorkspaceName());
- queue().submit(request);
- return request.getProperties();
+ return requests.readAllProperties(location,
getCurrentWorkspaceName()).getProperties();
}
public Collection<Property> on( String path ) {
@@ -1500,9 +1491,7 @@
public On<Map<Name, Property>> getPropertiesByName() {
return new On<Map<Name, Property>>() {
public Map<Name, Property> on( Location location ) {
- ReadAllPropertiesRequest request = new ReadAllPropertiesRequest(location,
getCurrentWorkspaceName());
- queue().submit(request);
- return request.getPropertiesByName();
+ return requests.readAllProperties(location,
getCurrentWorkspaceName()).getPropertiesByName();
}
public Map<Name, Property> on( String path ) {
@@ -1567,9 +1556,7 @@
}
public List<Location> of( Location at ) {
- ReadAllChildrenRequest request = new ReadAllChildrenRequest(at,
getCurrentWorkspaceName());
- queue().submit(request);
- return request.getChildren();
+ return requests.readAllChildren(at,
getCurrentWorkspaceName()).getChildren();
}
public BlockOfChildren<List<Location>> inBlockOf( final int
blockSize ) {
@@ -1598,21 +1585,15 @@
}
public List<Location> under( Location at ) {
- ReadBlockOfChildrenRequest request = new
ReadBlockOfChildrenRequest(at,
-
getCurrentWorkspaceName(),
-
startingIndex, blockSize);
- queue().submit(request);
- return request.getChildren();
+ return requests.readBlockOfChildren(at,
getCurrentWorkspaceName(), startingIndex, blockSize)
+ .getChildren();
}
};
}
public List<Location> startingAfter( final Location
previousSibling ) {
- ReadNextBlockOfChildrenRequest request = new
ReadNextBlockOfChildrenRequest(previousSibling,
-
getCurrentWorkspaceName(),
-
blockSize);
- queue().submit(request);
- return request.getChildren();
+ return requests.readNextBlockOfChildren(previousSibling,
getCurrentWorkspaceName(), blockSize)
+ .getChildren();
}
public List<Location> startingAfter( String
pathOfPreviousSibling ) {
@@ -1688,9 +1669,7 @@
}
public Property on( Location at ) {
- ReadPropertyRequest request = new ReadPropertyRequest(at,
getCurrentWorkspaceName(), name);
- queue().submit(request);
- return request.getProperty();
+ return requests.readProperty(at, getCurrentWorkspaceName(),
name).getProperty();
}
};
}
@@ -1712,9 +1691,7 @@
* @return the node that is read from the repository
*/
public Node getNodeAt( Location location ) {
- ReadNodeRequest request = new ReadNodeRequest(location,
getCurrentWorkspaceName());
- this.requestQueue.submit(request);
- return new GraphNode(request);
+ return new GraphNode(requests.readNode(location, getCurrentWorkspaceName()));
}
/**
@@ -1794,9 +1771,7 @@
public At<Subgraph> getSubgraphOfDepth( final int depth ) {
return new At<Subgraph>() {
public Subgraph at( Location location ) {
- ReadBranchRequest request = new ReadBranchRequest(location,
getCurrentWorkspaceName(), depth);
- queue().submit(request);
- return new SubgraphResults(request);
+ return new SubgraphResults(requests.readBranch(location,
getCurrentWorkspaceName(), depth));
}
public Subgraph at( String path ) {
@@ -1868,7 +1843,6 @@
return into(Location.create(uuid));
}
- @SuppressWarnings( "synthetic-access" )
public Conjunction<Graph> into( Location at ) throws IOException,
SAXException {
GraphImporter importer = new GraphImporter(Graph.this);
importer.importXml(uri, at, skipRootElement).execute(); //
'importXml' creates and uses a new batch
@@ -1925,7 +1899,7 @@
* @see Results
*/
public Batch batch() {
- return new Batch(new LinkedList<Request>());
+ return new Batch(null);
}
/**
@@ -1934,14 +1908,14 @@
* {@link #getSourceName() repository source}. The {@link Results results} are not
available until the {@link Batch#execute()}
* method is invoked.
*
- * @param queue the queue where all batched requests should be placed
+ * @param builder the request builder that should be used; may not be null
* @return the batch object used to build and accumulate multiple requests and to
submit them all for processing at once.
* @see Batch#execute()
* @see Results
*/
- public Batch batch( LinkedList<Request> queue ) {
- CheckArg.isNotNull(queue, "queue");
- return new Batch(queue);
+ public Batch batch( BatchRequestBuilder builder ) {
+ CheckArg.isNotNull(builder, "builder");
+ return new Batch(builder);
}
/**
@@ -1953,13 +1927,13 @@
*/
@Immutable
public final class Batch implements Executable<Node> {
- protected final CompositingRequestQueue requestQueue;
+ protected final BatchRequestBuilder requestQueue;
protected final BatchConjunction nextRequests;
protected final String workspaceName;
protected boolean executed = false;
- /*package*/Batch( LinkedList<Request> queue ) {
- this.requestQueue = new CompositingRequestQueue(queue);
+ /*package*/Batch( BatchRequestBuilder builder ) {
+ this.requestQueue = builder != null ? builder : new BatchRequestBuilder();
this.workspaceName = Graph.this.getCurrentWorkspaceName();
this.nextRequests = new BatchConjunction() {
public Batch and() {
@@ -1967,8 +1941,7 @@
}
public Results execute() {
- executed = true;
- return Batch.this.requestQueue.execute();
+ return Batch.this.execute();
}
};
}
@@ -1988,7 +1961,7 @@
* @return true if there are some requests in this batch that need to be
executed, or false execution is not required
*/
public boolean isExecuteRequired() {
- return !executed || requestQueue.size() != 0;
+ return !executed || requestQueue.hasRequests();
}
/**
@@ -2028,8 +2001,7 @@
* to be moved
*/
public Move<BatchConjunction> move( Node from ) {
- assertNotExecuted();
- return new MoveAction<BatchConjunction>(this.nextRequests,
this.requestQueue, from.getLocation());
+ return move(from.getLocation());
}
/**
@@ -2044,9 +2016,19 @@
* @return the object that can be used to specify addition nodes to be moved or
the location of the node where the node is
* to be moved
*/
- public Move<BatchConjunction> move( Location from ) {
+ public final Move<BatchConjunction> move( Location from ) {
assertNotExecuted();
- return new MoveAction<BatchConjunction>(this.nextRequests,
this.requestQueue, from);
+ return new MoveAction<BatchConjunction>(this.nextRequests, from) {
+ @Override
+ protected BatchConjunction submit( Locations from,
+ Location into ) {
+ String workspaceName = getCurrentWorkspaceName();
+ do {
+ requestQueue.moveBranch(from.getLocation(), into,
workspaceName);
+ } while ((from = from.next()) != null);
+ return and();
+ }
+ };
}
/**
@@ -2062,8 +2044,7 @@
* to be moved
*/
public Move<BatchConjunction> move( String fromPath ) {
- assertNotExecuted();
- return new MoveAction<BatchConjunction>(this.nextRequests,
this.requestQueue, Location.create(createPath(fromPath)));
+ return move(Location.create(createPath(fromPath)));
}
/**
@@ -2079,8 +2060,7 @@
* to be moved
*/
public Move<BatchConjunction> move( Path from ) {
- assertNotExecuted();
- return new MoveAction<BatchConjunction>(this.nextRequests,
this.requestQueue, Location.create(from));
+ return move(Location.create(from));
}
/**
@@ -2096,8 +2076,7 @@
* to be moved
*/
public Move<BatchConjunction> move( UUID from ) {
- assertNotExecuted();
- return new MoveAction<BatchConjunction>(this.nextRequests,
this.requestQueue, Location.create(from));
+ return move(Location.create(from));
}
/**
@@ -2114,8 +2093,7 @@
* to be moved
*/
public Move<BatchConjunction> move( Property idProperty ) {
- assertNotExecuted();
- return new MoveAction<BatchConjunction>(this.nextRequests,
this.requestQueue, Location.create(idProperty));
+ return move(Location.create(idProperty));
}
/**
@@ -2134,9 +2112,7 @@
*/
public Move<BatchConjunction> move( Property firstIdProperty,
Property... additionalIdProperties ) {
- assertNotExecuted();
- return new MoveAction<BatchConjunction>(this.nextRequests,
this.requestQueue, Location.create(firstIdProperty,
-
additionalIdProperties));
+ return move(Location.create(firstIdProperty, additionalIdProperties));
}
/**
@@ -2153,8 +2129,7 @@
* to be moved
*/
public Move<BatchConjunction> move( Iterable<Property> idProperties )
{
- assertNotExecuted();
- return new MoveAction<BatchConjunction>(this.nextRequests,
this.requestQueue, Location.create(idProperties));
+ return move(Location.create(idProperties));
}
/**
@@ -2170,8 +2145,7 @@
* is to be copied
*/
public Copy<BatchConjunction> copy( Node from ) {
- assertNotExecuted();
- return new CopyAction<BatchConjunction>(nextRequests,
this.requestQueue, from.getLocation());
+ return copy(from.getLocation());
}
/**
@@ -2188,7 +2162,18 @@
*/
public Copy<BatchConjunction> copy( Location from ) {
assertNotExecuted();
- return new CopyAction<BatchConjunction>(nextRequests,
this.requestQueue, from);
+ return new CopyAction<BatchConjunction>(this.nextRequests, from) {
+ @Override
+ protected BatchConjunction submit( Locations from,
+ Location into,
+ Name copyName ) {
+ String workspaceName = getCurrentWorkspaceName();
+ do {
+ requestQueue.copyBranch(from.getLocation(), workspaceName, into,
workspaceName, copyName);
+ } while ((from = from.next()) != null);
+ return and();
+ }
+ };
}
/**
@@ -2204,8 +2189,7 @@
* is to be copied
*/
public Copy<BatchConjunction> copy( String fromPath ) {
- assertNotExecuted();
- return new CopyAction<BatchConjunction>(nextRequests,
this.requestQueue, Location.create(createPath(fromPath)));
+ return copy(Location.create(createPath(fromPath)));
}
/**
@@ -2221,8 +2205,7 @@
* is to be copied
*/
public Copy<BatchConjunction> copy( Path from ) {
- assertNotExecuted();
- return new CopyAction<BatchConjunction>(nextRequests,
this.requestQueue, Location.create(from));
+ return copy(Location.create(from));
}
/**
@@ -2238,8 +2221,7 @@
* is to be copied
*/
public Copy<BatchConjunction> copy( UUID from ) {
- assertNotExecuted();
- return new CopyAction<BatchConjunction>(nextRequests,
this.requestQueue, Location.create(from));
+ return copy(Location.create(from));
}
/**
@@ -2256,8 +2238,7 @@
* is to be copied
*/
public Copy<BatchConjunction> copy( Property idProperty ) {
- assertNotExecuted();
- return new CopyAction<BatchConjunction>(nextRequests,
this.requestQueue, Location.create(idProperty));
+ return copy(Location.create(idProperty));
}
/**
@@ -2276,9 +2257,7 @@
*/
public Copy<BatchConjunction> copy( Property firstIdProperty,
Property... additionalIdProperties ) {
- assertNotExecuted();
- return new CopyAction<BatchConjunction>(nextRequests,
this.requestQueue, Location.create(firstIdProperty,
-
additionalIdProperties));
+ return copy(Location.create(firstIdProperty, additionalIdProperties));
}
/**
@@ -2295,8 +2274,7 @@
* is to be copied
*/
public Copy<BatchConjunction> copy( Iterable<Property> idProperties )
{
- assertNotExecuted();
- return new CopyAction<BatchConjunction>(nextRequests,
this.requestQueue, Location.create(idProperties));
+ return copy(Location.create(idProperties));
}
/**
@@ -2310,9 +2288,7 @@
* @return an object that may be used to start another request
*/
public BatchConjunction delete( Node at ) {
- assertNotExecuted();
- this.requestQueue.submit(new DeleteBranchRequest(at.getLocation(),
getCurrentWorkspaceName()));
- return nextRequests;
+ return delete(at.getLocation());
}
/**
@@ -2327,7 +2303,7 @@
*/
public BatchConjunction delete( Location at ) {
assertNotExecuted();
- this.requestQueue.submit(new DeleteBranchRequest(at,
getCurrentWorkspaceName()));
+ this.requestQueue.deleteBranch(at, getCurrentWorkspaceName());
return nextRequests;
}
@@ -2342,9 +2318,7 @@
* @return an object that may be used to start another request
*/
public BatchConjunction delete( String atPath ) {
- assertNotExecuted();
- this.requestQueue.submit(new
DeleteBranchRequest(Location.create(createPath(atPath)), getCurrentWorkspaceName()));
- return nextRequests;
+ return delete(Location.create(createPath(atPath)));
}
/**
@@ -2358,9 +2332,7 @@
* @return an object that may be used to start another request
*/
public BatchConjunction delete( Path at ) {
- assertNotExecuted();
- this.requestQueue.submit(new DeleteBranchRequest(Location.create(at),
getCurrentWorkspaceName()));
- return nextRequests;
+ return delete(Location.create(at));
}
/**
@@ -2374,9 +2346,7 @@
* @return an object that may be used to start another request
*/
public BatchConjunction delete( UUID at ) {
- assertNotExecuted();
- this.requestQueue.submit(new DeleteBranchRequest(Location.create(at),
getCurrentWorkspaceName()));
- return nextRequests;
+ return delete(Location.create(at));
}
/**
@@ -2390,9 +2360,7 @@
* @return an object that may be used to start another request
*/
public BatchConjunction delete( Property idProperty ) {
- assertNotExecuted();
- this.requestQueue.submit(new DeleteBranchRequest(Location.create(idProperty),
getCurrentWorkspaceName()));
- return nextRequests;
+ return delete(Location.create(idProperty));
}
/**
@@ -2409,10 +2377,7 @@
*/
public BatchConjunction delete( Property firstIdProperty,
Property... additionalIdProperties ) {
- assertNotExecuted();
- this.requestQueue.submit(new
DeleteBranchRequest(Location.create(firstIdProperty, additionalIdProperties),
-
getCurrentWorkspaceName()));
- return nextRequests;
+ return delete(Location.create(firstIdProperty, additionalIdProperties));
}
/**
@@ -2427,9 +2392,7 @@
* @return an object that may be used to start another request
*/
public BatchConjunction delete( Iterable<Property> idProperties ) {
- assertNotExecuted();
- this.requestQueue.submit(new
DeleteBranchRequest(Location.create(idProperties), getCurrentWorkspaceName()));
- return nextRequests;
+ return delete(Location.create(idProperties));
}
/**
@@ -2444,11 +2407,7 @@
* node where the node is to be created
*/
public Create<Batch> create( String atPath ) {
- assertNotExecuted();
- Path at = createPath(atPath);
- Path parent = at.getParent();
- Name name = at.getLastSegment().getName();
- return new CreateAction<Batch>(this, requestQueue,
Location.create(parent), getCurrentWorkspaceName(), name);
+ return create(createPath(atPath));
}
/**
@@ -2465,11 +2424,7 @@
*/
public Create<Batch> create( String atPath,
Property property ) {
- assertNotExecuted();
- Path at = createPath(atPath);
- Path parent = at.getParent();
- Name name = at.getLastSegment().getName();
- return new CreateAction<Batch>(this, requestQueue,
Location.create(parent), getCurrentWorkspaceName(), name).with(property);
+ return create(createPath(atPath)).with(property);
}
/**
@@ -2488,12 +2443,7 @@
public Create<Batch> create( String atPath,
Property firstProperty,
Property... additionalProperties ) {
- assertNotExecuted();
- Path at = createPath(atPath);
- Path parent = at.getParent();
- Name name = at.getLastSegment().getName();
- return new CreateAction<Batch>(this, requestQueue,
Location.create(parent), getCurrentWorkspaceName(), name).with(firstProperty,
-
additionalProperties);
+ return create(createPath(atPath)).with(firstProperty, additionalProperties);
}
/**
@@ -2507,14 +2457,38 @@
* @return the object that can be used to specify addition properties for the new
node to be copied or the location of the
* node where the node is to be created
*/
- public Create<Batch> create( Path at ) {
+ public final Create<Batch> create( Path at ) {
assertNotExecuted();
CheckArg.isNotNull(at, "at");
Path parent = at.getParent();
Name name = at.getLastSegment().getName();
- return new CreateAction<Batch>(this, requestQueue,
Location.create(parent), getCurrentWorkspaceName(), name);
+ return create(Location.create(parent), name);
}
+ protected final CreateAction<Batch> create( Location parent,
+ Name child ) {
+ return new CreateAction<Batch>(this, parent, getCurrentWorkspaceName(),
child) {
+ @Override
+ protected Batch submit( Location parent,
+ String workspaceName,
+ Name childName,
+ Collection<Property> properties ) {
+ requestQueue.createNode(parent, workspaceName, childName,
properties.iterator());
+ return Batch.this;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.jboss.dna.graph.Graph.Executable#execute()
+ */
+ public Results execute() {
+ and();
+ return Batch.this.execute();
+ }
+ };
+ }
+
/**
* Begin the request to create a node located at the supplied path.
* <p>
@@ -2529,12 +2503,7 @@
*/
public Create<Batch> create( Path at,
Iterable<Property> properties ) {
- assertNotExecuted();
- CheckArg.isNotNull(at, "at");
- Path parent = at.getParent();
- Name name = at.getLastSegment().getName();
- CreateAction<Batch> action = new CreateAction<Batch>(this,
requestQueue, Location.create(parent),
-
getCurrentWorkspaceName(), name);
+ Create<Batch> action = create(at);
for (Property property : properties) {
action.and(property);
}
@@ -2555,11 +2524,7 @@
*/
public Create<Batch> create( Path at,
Property property ) {
- assertNotExecuted();
- CheckArg.isNotNull(at, "at");
- Path parent = at.getParent();
- Name name = at.getLastSegment().getName();
- return new CreateAction<Batch>(this, requestQueue,
Location.create(parent), getCurrentWorkspaceName(), name).with(property);
+ return create(at).with(property);
}
/**
@@ -2578,12 +2543,7 @@
public Create<Batch> create( Path at,
Property firstProperty,
Property... additionalProperties ) {
- assertNotExecuted();
- CheckArg.isNotNull(at, "at");
- Path parent = at.getParent();
- Name name = at.getLastSegment().getName();
- return new CreateAction<Batch>(this, requestQueue,
Location.create(parent), getCurrentWorkspaceName(), name).with(firstProperty,
-
additionalProperties);
+ return create(at).with(firstProperty, additionalProperties);
}
/**
@@ -2595,7 +2555,14 @@
*/
public CreateNodeNamed<Batch> createUnder( Location parent ) {
CheckArg.isNotNull(parent, "parent");
- return new CreateNodeNamedAction<Batch>(this, requestQueue, parent,
getCurrentWorkspaceName());
+ return new CreateNodeNamedAction<Batch>(this, parent) {
+ @Override
+ protected CreateAction<Batch> createWith( Batch batch,
+ Location parent,
+ Name childName ) {
+ return Batch.this.create(parent, childName);
+ }
+ };
}
/**
@@ -2607,8 +2574,7 @@
public On<BatchConjunction> set( final Property... properties ) {
return new On<BatchConjunction>() {
public BatchConjunction on( Location location ) {
- UpdatePropertiesRequest request = new
UpdatePropertiesRequest(location, getCurrentWorkspaceName(), properties);
- requestQueue.submit(request);
+ requestQueue.setProperties(location, getCurrentWorkspaceName(),
properties);
return nextRequests;
}
@@ -2669,17 +2635,13 @@
public BatchConjunction to( Location value ) {
Reference ref = (Reference)convertReferenceValue(value);
Property property =
getContext().getPropertyFactory().create(propertyName, ref);
- UpdatePropertiesRequest request = new
UpdatePropertiesRequest(location, getCurrentWorkspaceName(),
-
property);
- requestQueue.submit(request);
+ requestQueue.setProperty(location, getCurrentWorkspaceName(),
property);
return nextRequests;
}
protected BatchConjunction toValue( Object value ) {
Property property =
getContext().getPropertyFactory().create(propertyName, value);
- UpdatePropertiesRequest request = new
UpdatePropertiesRequest(location, getCurrentWorkspaceName(),
-
property);
- requestQueue.submit(request);
+ requestQueue.setProperty(location, getCurrentWorkspaceName(),
property);
return nextRequests;
}
@@ -2766,9 +2728,7 @@
public BatchConjunction to( Object value ) {
value = convertReferenceValue(value);
Property property =
getContext().getPropertyFactory().create(propertyName, value);
- UpdatePropertiesRequest request = new
UpdatePropertiesRequest(location, getCurrentWorkspaceName(),
-
property);
- requestQueue.submit(request);
+ requestQueue.setProperty(location, getCurrentWorkspaceName(),
property);
return nextRequests;
}
@@ -2779,9 +2739,7 @@
otherValues[i] = convertReferenceValue(otherValues[i]);
}
Property property =
getContext().getPropertyFactory().create(propertyName, firstValue, otherValues);
- UpdatePropertiesRequest request = new
UpdatePropertiesRequest(location, getCurrentWorkspaceName(),
-
property);
- requestQueue.submit(request);
+ requestQueue.setProperty(location, getCurrentWorkspaceName(),
property);
return nextRequests;
}
@@ -2792,9 +2750,7 @@
valueList.add(value);
}
Property property =
getContext().getPropertyFactory().create(propertyName, valueList);
- UpdatePropertiesRequest request = new
UpdatePropertiesRequest(location, getCurrentWorkspaceName(),
-
property);
- requestQueue.submit(request);
+ requestQueue.setProperty(location, getCurrentWorkspaceName(),
property);
return nextRequests;
}
@@ -2805,9 +2761,7 @@
valueList.add(value);
}
Property property =
getContext().getPropertyFactory().create(propertyName, valueList);
- UpdatePropertiesRequest request = new
UpdatePropertiesRequest(location, getCurrentWorkspaceName(),
-
property);
- requestQueue.submit(request);
+ requestQueue.setProperty(location, getCurrentWorkspaceName(),
property);
return nextRequests;
}
@@ -2976,9 +2930,7 @@
public On<BatchConjunction> remove( final Name... propertyNames ) {
return new On<BatchConjunction>() {
public BatchConjunction on( Location location ) {
- RemovePropertiesRequest request = new
RemovePropertiesRequest(location, getCurrentWorkspaceName(),
-
propertyNames);
- requestQueue.submit(request);
+ requestQueue.removeProperties(location, getCurrentWorkspaceName(),
propertyNames);
return nextRequests;
}
@@ -3017,14 +2969,14 @@
*/
public On<BatchConjunction> remove( String... propertyNames ) {
NameFactory nameFactory = getContext().getValueFactories().getNameFactory();
- final List<Name> names = new LinkedList<Name>();
- for (String propertyName : propertyNames) {
- names.add(nameFactory.create(propertyName));
+ int number = propertyNames.length;
+ final Name[] names = new Name[number];
+ for (int i = 0; i != number; ++i) {
+ names[i] = nameFactory.create(propertyNames[i]);
}
return new On<BatchConjunction>() {
public BatchConjunction on( Location location ) {
- RemovePropertiesRequest request = new
RemovePropertiesRequest(location, getCurrentWorkspaceName(), names);
- requestQueue.submit(request);
+ requestQueue.removeProperties(location, getCurrentWorkspaceName(),
names);
return nextRequests;
}
@@ -3081,8 +3033,7 @@
*/
public BatchConjunction read( Location location ) {
assertNotExecuted();
- ReadNodeRequest request = new ReadNodeRequest(location,
getCurrentWorkspaceName());
- requestQueue.submit(request);
+ requestQueue.readNode(location, getCurrentWorkspaceName());
return nextRequests;
}
@@ -3216,8 +3167,7 @@
}
public BatchConjunction on( Location at ) {
- ReadPropertyRequest request = new ReadPropertyRequest(at,
getCurrentWorkspaceName(), name);
- requestQueue.submit(request);
+ requestQueue.readProperty(at, getCurrentWorkspaceName(), name);
return Batch.this.nextRequests;
}
};
@@ -3237,8 +3187,7 @@
assertNotExecuted();
return new On<BatchConjunction>() {
public BatchConjunction on( Location location ) {
- ReadAllPropertiesRequest request = new
ReadAllPropertiesRequest(location, getCurrentWorkspaceName());
- requestQueue.submit(request);
+ requestQueue.readAllProperties(location, getCurrentWorkspaceName());
return Batch.this.nextRequests;
}
@@ -3308,8 +3257,7 @@
}
public BatchConjunction of( Location at ) {
- ReadAllChildrenRequest request = new ReadAllChildrenRequest(at,
getCurrentWorkspaceName());
- requestQueue.submit(request);
+ requestQueue.readAllChildren(at, getCurrentWorkspaceName());
return Batch.this.nextRequests;
}
};
@@ -3330,8 +3278,7 @@
assertNotExecuted();
return new At<BatchConjunction>() {
public BatchConjunction at( Location location ) {
- ReadBranchRequest request = new ReadBranchRequest(location,
getCurrentWorkspaceName(), depth);
- requestQueue.submit(request);
+ requestQueue.readBranch(location, getCurrentWorkspaceName());
return Batch.this.nextRequests;
}
@@ -3368,7 +3315,17 @@
* @see org.jboss.dna.graph.Graph.Executable#execute()
*/
public Results execute() {
- return this.requestQueue.execute();
+ executed = true;
+ Request request = requestQueue.pop();
+ if (request == null) {
+ return new BatchResults();
+ }
+ Graph.this.execute(request);
+ if (request instanceof CompositeRequest) {
+ CompositeRequest composite = (CompositeRequest)request;
+ return new BatchResults(composite.getRequests());
+ }
+ return new BatchResults(request);
}
}
@@ -4700,116 +4657,6 @@
}
//
----------------------------------------------------------------------------------------------------------------
- // RequestQueue and the different implementations
- //
----------------------------------------------------------------------------------------------------------------
-
- /**
- * A queue to which each each {@link AbstractAction} can submit its {@link Request}
objects, either in single or multiple.
- * This interface abstracts away from the {@link AbstractAction} what it is to do
with its {@link Request} objects, allowing
- * the same <code>AbstractAction</code> classes to be used by the {@link
Graph} and {@link Graph.Batch} components.
- *
- * @author Randall Hauch
- */
- protected interface RequestQueue extends Executable<Node> {
- Graph getGraph();
-
- void submit( Request request );
-
- void submit( List<Request> requests );
-
- }
-
- /**
- * A RequestQueue that is used by the Graph instance to immediately execute the
submitted requests.
- *
- * @author Randall Hauch
- */
- @NotThreadSafe
- protected class GraphRequestQueue implements RequestQueue {
- public Graph getGraph() {
- return Graph.this;
- }
-
- public void submit( Request request ) {
- // Execute the request immediately ...
- Graph.this.execute(request);
- }
-
- public void submit( List<Request> requests ) {
- Request request = CompositeRequest.with(requests);
- // Execute the request immediately ...
- Graph.this.execute(request);
- }
-
- public Results execute() {
- throw new UnsupportedOperationException();
- }
- }
-
- /**
- * A RequestQueue that is used by the {@link Graph.Batch} component to enqueue {@link
Request}s until they are to be submitted
- * to the repository connections.
- *
- * @author Randall Hauch
- */
- @NotThreadSafe
- /*package*/class CompositingRequestQueue implements RequestQueue {
- private final LinkedList<Request> requests;
-
- CompositingRequestQueue( LinkedList<Request> queue ) {
- assert queue != null;
- this.requests = queue;
- }
-
- public Graph getGraph() {
- return Graph.this;
- }
-
- public List<Request> getRequests() {
- return this.requests;
- }
-
- /**
- * Determine the number of requests that are currently in the queue.
- *
- * @return the number of currently-enqueued requests
- */
- public int size() {
- return requests.size();
- }
-
- public void submit( Request request ) {
- if (!requests.isEmpty() && request instanceof
UpdatePropertiesRequest) {
- // If the previous request was also an update, then maybe they can be
merged ...
- Request previous = requests.getLast();
- if (previous instanceof UpdatePropertiesRequest) {
- // They can be merged if the have the same location ...
- UpdatePropertiesRequest next = (UpdatePropertiesRequest)request;
- UpdatePropertiesRequest prev = (UpdatePropertiesRequest)previous;
- if (next.on().equals(prev.on())) {
- requests.removeLast();
- requests.add(prev.mergeWith(next));
- }
- }
- }
- this.requests.add(request);
- }
-
- public void submit( List<Request> requests ) {
- this.requests.addAll(requests);
- }
-
- public Results execute() {
- if (!requests.isEmpty()) {
- // Execute the requests ...
- Request request = CompositeRequest.with(requests);
- Graph.this.execute(request);
- }
- return new BatchResults(requests);
- }
- }
-
- //
----------------------------------------------------------------------------------------------------------------
// Node Implementation
//
----------------------------------------------------------------------------------------------------------------
@Immutable
@@ -4920,6 +4767,39 @@
}
}
+ /*package*/BatchResults( Request request ) {
+ if (request instanceof ReadAllPropertiesRequest) {
+ ReadAllPropertiesRequest read = (ReadAllPropertiesRequest)request;
+
getOrCreateNode(read.getActualLocationOfNode()).setProperties(read.getPropertiesByName());
+ } else if (request instanceof ReadPropertyRequest) {
+ ReadPropertyRequest read = (ReadPropertyRequest)request;
+
getOrCreateNode(read.getActualLocationOfNode()).addProperty(read.getProperty());
+ } else if (request instanceof ReadNodeRequest) {
+ ReadNodeRequest read = (ReadNodeRequest)request;
+ BatchResultsNode node = getOrCreateNode(read.getActualLocationOfNode());
+ node.setProperties(read.getPropertiesByName());
+ node.setChildren(read.getChildren());
+ } else if (request instanceof ReadBlockOfChildrenRequest) {
+ throw new IllegalStateException();
+ } else if (request instanceof ReadAllChildrenRequest) {
+ ReadAllChildrenRequest read = (ReadAllChildrenRequest)request;
+
getOrCreateNode(read.getActualLocationOfNode()).setChildren(read.getChildren());
+ } else if (request instanceof ReadBranchRequest) {
+ ReadBranchRequest read = (ReadBranchRequest)request;
+ for (Location location : read) {
+ BatchResultsNode node = getOrCreateNode(location);
+ node.setProperties(read.getPropertiesFor(location));
+ node.setChildren(read.getChildren(location));
+ }
+ }
+ for (Map.Entry<Path, BatchResultsNode> entry : nodes.entrySet()) {
+ entry.getValue().freeze();
+ }
+ }
+
+ /*package*/BatchResults() {
+ }
+
private BatchResultsNode getOrCreateNode( Location location ) {
BatchResultsNode node = nodes.get(location);
if (node == null) {
@@ -5290,20 +5170,13 @@
// Action Implementations
//
----------------------------------------------------------------------------------------------------------------
@Immutable
- protected static abstract class AbstractAction<T> implements
Conjunction<T>, Executable<Node> {
- private final RequestQueue queue;
+ protected abstract class AbstractAction<T> implements Conjunction<T> {
private final T afterConjunction;
- /*package*/AbstractAction( T afterConjunction,
- RequestQueue queue ) {
- this.queue = queue;
+ /*package*/AbstractAction( T afterConjunction ) {
this.afterConjunction = afterConjunction;
}
- /*package*/RequestQueue queue() {
- return this.queue;
- }
-
/*package*/T afterConjunction() {
return this.afterConjunction;
}
@@ -5313,22 +5186,17 @@
}
/*package*/Path createPath( String path ) {
- return
queue.getGraph().getContext().getValueFactories().getPathFactory().create(path);
+ return
Graph.this.getContext().getValueFactories().getPathFactory().create(path);
}
-
- public Results execute() {
- return queue.execute();
- }
}
@NotThreadSafe
- protected class MoveAction<T> extends AbstractAction<T> implements
Move<T> {
+ protected abstract class MoveAction<T> extends AbstractAction<T>
implements Move<T> {
private final Locations from;
/*package*/MoveAction( T afterConjunction,
- RequestQueue queue,
Location from ) {
- super(afterConjunction, queue);
+ super(afterConjunction);
this.from = new Locations(from);
}
@@ -5371,65 +5239,46 @@
/**
* Submit any requests to move the targets into the supplied parent location
*
+ * @param from the location(s) that are being moved; never null
* @param into the parent location
* @return this object, for method chaining
*/
- private T submit( Location into ) {
- String workspaceName = getCurrentWorkspaceName();
- if (this.from.hasNext()) {
- List<Request> requests = new LinkedList<Request>();
- Locations locations = this.from;
- while (locations.hasNext()) {
- Location location = locations.getLocation();
- requests.add(new MoveBranchRequest(location, into, workspaceName));
- locations = locations.next();
- }
- queue().submit(requests);
- } else {
- queue().submit(new MoveBranchRequest(this.from.getLocation(), into,
workspaceName));
- }
- return and();
- }
+ protected abstract T submit( Locations from,
+ Location into );
public T into( Location into ) {
- return submit(into);
+ return submit(from, into);
}
public T into( Path into ) {
- return submit(Location.create(into));
+ return submit(from, Location.create(into));
}
public T into( UUID into ) {
- return submit(Location.create(into));
+ return submit(from, Location.create(into));
}
public T into( Property firstIdProperty,
Property... additionalIdProperties ) {
- return submit(Location.create(firstIdProperty, additionalIdProperties));
+ return submit(from, Location.create(firstIdProperty,
additionalIdProperties));
}
public T into( Property into ) {
- return submit(Location.create(into));
+ return submit(from, Location.create(into));
}
public T into( String into ) {
- return submit(Location.create(createPath(into)));
+ return submit(from, Location.create(createPath(into)));
}
-
- @Override
- public Results execute() {
- return queue().execute();
- }
}
@NotThreadSafe
- protected class CopyAction<T> extends AbstractAction<T> implements
Copy<T> {
+ protected abstract class CopyAction<T> extends AbstractAction<T>
implements Copy<T> {
private final Locations from;
/*package*/CopyAction( T afterConjunction,
- RequestQueue queue,
Location from ) {
- super(afterConjunction, queue);
+ super(afterConjunction);
this.from = new Locations(from);
}
@@ -5472,51 +5321,38 @@
/**
* Submit any requests to move the targets into the supplied parent location
*
+ * @param from the locations that are being copied
* @param into the parent location
* @param nameForCopy the name that should be used for the copy, or null if the
name should be the same as the original
* @return this object, for method chaining
*/
- private T submit( Location into,
- Name nameForCopy ) {
- String workspaceName = getCurrentWorkspaceName();
- if (this.from.hasNext()) {
- List<Request> requests = new LinkedList<Request>();
- Locations locations = this.from;
- while (locations.hasNext()) {
- Location location = locations.getLocation();
- requests.add(new CopyBranchRequest(location, workspaceName, into,
workspaceName, nameForCopy));
- locations = locations.next();
- }
- queue().submit(requests);
- } else {
- queue().submit(new CopyBranchRequest(this.from.getLocation(),
workspaceName, into, workspaceName, nameForCopy));
- }
- return and();
- }
+ protected abstract T submit( Locations from,
+ Location into,
+ Name nameForCopy );
public T into( Location into ) {
- return submit(into, null);
+ return submit(from, into, null);
}
public T into( Path into ) {
- return submit(Location.create(into), null);
+ return submit(from, Location.create(into), null);
}
public T into( UUID into ) {
- return submit(Location.create(into), null);
+ return submit(from, Location.create(into), null);
}
public T into( Property firstIdProperty,
Property... additionalIdProperties ) {
- return submit(Location.create(firstIdProperty, additionalIdProperties),
null);
+ return submit(from, Location.create(firstIdProperty, additionalIdProperties),
null);
}
public T into( Property into ) {
- return submit(Location.create(into), null);
+ return submit(from, Location.create(into), null);
}
public T into( String into ) {
- return submit(Location.create(createPath(into)), null);
+ return submit(from, Location.create(createPath(into)), null);
}
public T to( Location desiredLocation ) {
@@ -5528,7 +5364,7 @@
throw new
IllegalArgumentException(GraphI18n.unableToCopyToTheRoot.text(this.from,
desiredLocation));
}
Path parent = desiredPath.getParent();
- return submit(Location.create(parent),
desiredPath.getLastSegment().getName());
+ return submit(from, Location.create(parent),
desiredPath.getLastSegment().getName());
}
public T to( Path desiredPath ) {
@@ -5536,77 +5372,72 @@
throw new
IllegalArgumentException(GraphI18n.unableToCopyToTheRoot.text(this.from, desiredPath));
}
Path parent = desiredPath.getParent();
- return submit(Location.create(parent),
desiredPath.getLastSegment().getName());
+ return submit(from, Location.create(parent),
desiredPath.getLastSegment().getName());
}
public T to( String desiredPath ) {
return to(createPath(desiredPath));
}
-
- @Override
- public Results execute() {
- return queue().execute();
- }
}
@NotThreadSafe
- protected static class CreateAction<T> extends AbstractAction<T>
implements Create<T> {
+ protected abstract class CreateAction<T> extends AbstractAction<T>
implements Create<T> {
private final String workspaceName;
private final Location parent;
private final Name childName;
- private final List<Property> properties = new
LinkedList<Property>();
+ private final Map<Name, Property> properties = new HashMap<Name,
Property>();
+ private boolean submitted = false;
/*package*/CreateAction( T afterConjunction,
- RequestQueue queue,
Location parent,
String workspaceName,
Name childName ) {
- super(afterConjunction, queue);
+ super(afterConjunction);
this.parent = parent;
this.workspaceName = workspaceName;
this.childName = childName;
}
public Create<T> and( UUID uuid ) {
- PropertyFactory factory =
queue().getGraph().getContext().getPropertyFactory();
- properties.add(factory.create(DnaLexicon.UUID, uuid));
+ PropertyFactory factory = getContext().getPropertyFactory();
+ properties.put(DnaLexicon.UUID, factory.create(DnaLexicon.UUID, uuid));
return this;
}
public Create<T> and( Property property ) {
- properties.add(property);
+ properties.put(property.getName(), property);
return this;
}
public Create<T> and( Iterable<Property> properties ) {
for (Property property : properties) {
- this.properties.add(property);
+ this.properties.put(property.getName(), property);
}
return this;
}
public Create<T> and( String name,
Object... values ) {
- ExecutionContext context = queue().getGraph().getContext();
+ ExecutionContext context = getContext();
PropertyFactory factory = context.getPropertyFactory();
NameFactory nameFactory = context.getValueFactories().getNameFactory();
- properties.add(factory.create(nameFactory.create(name), values));
+ Name propertyName = nameFactory.create(name);
+ properties.put(propertyName, factory.create(propertyName, values));
return this;
}
public Create<T> and( Name name,
Object... values ) {
- ExecutionContext context = queue().getGraph().getContext();
- PropertyFactory factory = context.getPropertyFactory();
- properties.add(factory.create(name, values));
+ PropertyFactory factory = getContext().getPropertyFactory();
+ properties.put(name, factory.create(name, values));
return this;
}
public Create<T> and( Property property,
Property... additionalProperties ) {
- properties.add(property);
+ properties.put(property.getName(), property);
for (Property additionalProperty : additionalProperties) {
- properties.add(additionalProperty);
+ properties.put(additionalProperty.getName(), additionalProperty);
}
return this;
}
@@ -5638,43 +5469,44 @@
return and(name, values);
}
+ protected abstract T submit( Location parent,
+ String workspaceName,
+ Name childName,
+ Collection<Property> properties );
+
@Override
public T and() {
- this.queue().submit(new CreateNodeRequest(parent, workspaceName, childName,
this.properties));
+ if (!submitted) {
+ submit(parent, workspaceName, childName, this.properties.values());
+ submitted = true;
+ }
return super.and();
}
-
- @Override
- public Results execute() {
- this.queue().submit(new CreateNodeRequest(parent, workspaceName, childName,
this.properties));
- return queue().execute();
- }
}
@NotThreadSafe
- protected static class CreateNodeNamedAction<T> extends AbstractAction<T>
implements CreateNodeNamed<T> {
+ protected abstract class CreateNodeNamedAction<T> extends
AbstractAction<T> implements CreateNodeNamed<T> {
private final Location parent;
- private final String workspaceName;
- /*package*/CreateNodeNamedAction( T afterConjunction,
- RequestQueue queue,
- Location parent,
- String workspaceName ) {
- super(afterConjunction, queue);
+ protected CreateNodeNamedAction( T afterConjunction,
+ Location parent ) {
+ super(afterConjunction);
this.parent = parent;
- this.workspaceName = workspaceName;
}
public CreateAction<T> nodeNamed( String name ) {
- ExecutionContext context = queue().getGraph().getContext();
- NameFactory factory = context.getValueFactories().getNameFactory();
+ NameFactory factory = getContext().getValueFactories().getNameFactory();
Name nameObj = factory.create(name);
- return new CreateAction<T>(afterConjunction(), queue(), parent,
workspaceName, nameObj);
+ return createWith(afterConjunction(), parent, nameObj);
}
public CreateAction<T> nodeNamed( Name name ) {
- return new CreateAction<T>(afterConjunction(), queue(), parent,
workspaceName, name);
+ return createWith(afterConjunction(), parent, name);
}
+
+ protected abstract CreateAction<T> createWith( T afterConjunction,
+ Location parent,
+ Name nodeName );
}
@Immutable
Modified: trunk/dna-graph/src/main/java/org/jboss/dna/graph/GraphImporter.java
===================================================================
--- trunk/dna-graph/src/main/java/org/jboss/dna/graph/GraphImporter.java 2009-04-06
15:55:23 UTC (rev 808)
+++ trunk/dna-graph/src/main/java/org/jboss/dna/graph/GraphImporter.java 2009-04-07
21:23:28 UTC (rev 809)
@@ -254,7 +254,7 @@
if (firstProperty == null) {
batch.create(path).and();
} else {
- batch.create(path, firstProperty, additionalProperties);
+ batch.create(path, firstProperty, additionalProperties).and();
}
}
Modified:
trunk/dna-graph/src/main/java/org/jboss/dna/graph/connector/inmemory/InMemoryRequestProcessor.java
===================================================================
---
trunk/dna-graph/src/main/java/org/jboss/dna/graph/connector/inmemory/InMemoryRequestProcessor.java 2009-04-06
15:55:23 UTC (rev 808)
+++
trunk/dna-graph/src/main/java/org/jboss/dna/graph/connector/inmemory/InMemoryRequestProcessor.java 2009-04-07
21:23:28 UTC (rev 809)
@@ -208,12 +208,13 @@
InMemoryNode node = getTargetNode(workspace, request, request.on());
if (node == null) return;
// Now set (or remove) the properties to the supplied node ...
- for (Property property : request.properties()) {
- Name propName = property.getName();
- if (property.size() == 0) {
- node.getProperties().remove(propName);
+ for (Map.Entry<Name, Property> propertyEntry :
request.properties().entrySet()) {
+ Property property = propertyEntry.getValue();
+ if (property == null) {
+ node.getProperties().remove(propertyEntry.getKey());
continue;
}
+ Name propName = property.getName();
if (!propName.equals(DnaLexicon.UUID)) {
node.getProperties().put(propName, property);
}
Added: trunk/dna-graph/src/main/java/org/jboss/dna/graph/request/BatchRequestBuilder.java
===================================================================
--- trunk/dna-graph/src/main/java/org/jboss/dna/graph/request/BatchRequestBuilder.java
(rev 0)
+++
trunk/dna-graph/src/main/java/org/jboss/dna/graph/request/BatchRequestBuilder.java 2009-04-07
21:23:28 UTC (rev 809)
@@ -0,0 +1,671 @@
+/*
+ * 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.
+ *
+ * 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.request;
+
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.LinkedList;
+import java.util.Map;
+import org.jboss.dna.graph.Location;
+import org.jboss.dna.graph.NodeConflictBehavior;
+import org.jboss.dna.graph.property.Name;
+import org.jboss.dna.graph.property.Path;
+import org.jboss.dna.graph.property.Property;
+import org.jboss.dna.graph.request.CloneWorkspaceRequest.CloneConflictBehavior;
+import org.jboss.dna.graph.request.CreateWorkspaceRequest.CreateConflictBehavior;
+
+/**
+ * A component that can be used to build up a list of requests. This implementation does
perform some simple optimizations, such
+ * as combining adjacent compatible requests.
+ * <p>
+ * This builder can be used to add multiple requests. When the enqueued requests are to
be processed, calling {@link #pop()} will
+ * remove and return the enqueued requests (as a {@link CompositeRequest} if there is
more than one enqueued request).
+ * </p>
+ */
+public class BatchRequestBuilder {
+
+ private LinkedList<Request> requests;
+ private NodeChange pendingRequest;
+
+ public BatchRequestBuilder() {
+ this.requests = new LinkedList<Request>();
+ }
+
+ public BatchRequestBuilder( LinkedList<Request> requests ) {
+ this.requests = requests != null ? requests : new LinkedList<Request>();
+ }
+
+ /**
+ * Determine whether this builder has built any requests.
+ *
+ * @return true if there are requests (i.e., {@link #pop()} will return a non-null
request), or false if there are no requests
+ */
+ public boolean hasRequests() {
+ return pendingRequest != null || !requests.isEmpty();
+ }
+
+ /**
+ * Finish any pending request
+ */
+ public void finishPendingRequest() {
+ if (pendingRequest != null) {
+ // There's a pending request, we need to build it ...
+ add(pendingRequest.toRequest());
+ }
+ }
+
+ /**
+ * Remove and return any requests that have been built by this builder since the last
call to this method. This method will
+ * return null if no requests have been built. If only one request was built, then it
will be returned. If multiple requests
+ * have been built, then this method will return a {@link CompositeRequest}
containing them.
+ *
+ * @return the request (or {@link CompositeRequest}) representing those requests that
this builder has created since the last
+ * call to this method, or null if there are no requests to return
+ */
+ public Request pop() {
+ int number = requests.size();
+ if (pendingRequest != null) {
+ // There's a pending request, we need to build it ...
+ Request newRequest = pendingRequest.toRequest();
+ if (number == 0) {
+ // There's no other request ...
+ return newRequest;
+ }
+ // We have at least one other request, so add the pending request ...
+ add(newRequest);
+ ++number;
+ } else {
+ // There is no pending request ...
+ if (number == 0) {
+ // And no enqueued request ...
+ return null;
+ }
+ if (number == 1) {
+ // There's only one request, so return just the one ...
+ Request result = requests.getFirst();
+ requests.clear();
+ return result;
+ }
+ }
+ assert number >= 2;
+ // Build a composite request (reusing the existing list), and then replace the
list
+ Request result = CompositeRequest.with(requests);
+ requests = new LinkedList<Request>();
+ return result;
+ }
+
+ protected final BatchRequestBuilder add( Request request ) {
+ addPending();
+ requests.add(request);
+ return this;
+ }
+
+ protected final BatchRequestBuilder addPending() {
+ if (pendingRequest != null) {
+ requests.add(pendingRequest.toRequest());
+ pendingRequest = null;
+ }
+ return this;
+ }
+
+ /**
+ * Add a request to obtain the information about the available workspaces.
+ *
+ * @return this builder for method chaining; never null
+ */
+ public BatchRequestBuilder getWorkspaces() {
+ return add(new GetWorkspacesRequest());
+ }
+
+ /**
+ * Add a request to verify the existance of the named workspace.
+ *
+ * @param workspaceName the desired name of the workspace, or null if the
source's default workspace should be used
+ * @return this builder for method chaining; never null
+ */
+ public BatchRequestBuilder verifyWorkspace( String workspaceName ) {
+ return add(new VerifyWorkspaceRequest(workspaceName));
+ }
+
+ /**
+ * Add a request to create a new workspace, and specify the behavior should a
workspace already exists with a name that
+ * matches the desired name for the new workspace.
+ *
+ * @param desiredNameOfNewWorkspace the desired name of the new workspace
+ * @param createConflictBehavior the behavior if a workspace already exists with the
same name, or null if the default
+ * behavior should be used
+ * @return this builder for method chaining; never null
+ */
+ public BatchRequestBuilder createWorkspace( String desiredNameOfNewWorkspace,
+ CreateConflictBehavior
createConflictBehavior ) {
+ return add(new CreateWorkspaceRequest(desiredNameOfNewWorkspace,
createConflictBehavior));
+ }
+
+ /**
+ * Add a request to clone an existing workspace to create a new workspace, and
specify the behavior should a workspace already
+ * exists with a name that matches the desired name for the new workspace.
+ *
+ * @param nameOfWorkspaceToBeCloned the name of the existing workspace that is to be
cloned
+ * @param desiredNameOfTargetWorkspace the desired name of the target workspace
+ * @param createConflictBehavior the behavior if a workspace already exists with the
same name
+ * @param cloneConflictBehavior the behavior if the workspace to be cloned does not
exist
+ * @return this builder for method chaining; never null
+ * @throws IllegalArgumentException if the either workspace name is null
+ */
+ public BatchRequestBuilder cloneWorkspace( String nameOfWorkspaceToBeCloned,
+ String desiredNameOfTargetWorkspace,
+ CreateConflictBehavior
createConflictBehavior,
+ CloneConflictBehavior
cloneConflictBehavior ) {
+ return add(new CloneWorkspaceRequest(nameOfWorkspaceToBeCloned,
desiredNameOfTargetWorkspace, createConflictBehavior,
+ cloneConflictBehavior));
+ }
+
+ /**
+ * Add a request to destroy an existing workspace.
+ *
+ * @param workspaceName the name of the workspace that is to be destroyed
+ * @return this builder for method chaining; never null
+ * @throws IllegalArgumentException if the workspace name is null
+ */
+ public BatchRequestBuilder destroyWorkspace( String workspaceName ) {
+ return add(new DestroyWorkspaceRequest(workspaceName));
+ }
+
+ /**
+ * Add a request to verify the existance and location of a node at the supplied
location.
+ *
+ * @param at the location of the node to be verified
+ * @param workspaceName the name of the workspace containing the node
+ * @return this builder for method chaining; never null
+ * @throws IllegalArgumentException if the location or workspace name is null
+ */
+ public BatchRequestBuilder verifyNodeExists( Location at,
+ String workspaceName ) {
+ return add(new VerifyNodeExistsRequest(at, workspaceName));
+ }
+
+ /**
+ * Add a request to read the properties and number of children of a node at the
supplied location.
+ *
+ * @param at the location of the node to be read
+ * @param workspaceName the name of the workspace containing the node
+ * @return this builder for method chaining; never null
+ * @throws IllegalArgumentException if the location or workspace name is null
+ */
+ public BatchRequestBuilder readNode( Location at,
+ String workspaceName ) {
+ return add(new ReadNodeRequest(at, workspaceName));
+ }
+
+ /**
+ * Add a request to read the children of a node at the supplied location in the
designated workspace.
+ *
+ * @param of the location of the node whose children are to be read
+ * @param workspaceName the name of the workspace
+ * @return this builder for method chaining; never null
+ * @throws IllegalArgumentException if the location or workspace name is null
+ */
+ public BatchRequestBuilder readAllChildren( Location of,
+ String workspaceName ) {
+ return add(new ReadAllChildrenRequest(of, workspaceName));
+ }
+
+ /**
+ * Add a request to read the properties and number of children of a node at the
supplied location.
+ *
+ * @param of the location of the node whose children are to be read
+ * @param workspaceName the name of the workspace
+ * @return this builder for method chaining; never null
+ * @throws IllegalArgumentException if the location or workspace name is null
+ */
+ public BatchRequestBuilder readAllProperties( Location of,
+ String workspaceName ) {
+ return add(new ReadAllPropertiesRequest(of, workspaceName));
+ }
+
+ /**
+ * Add a request to read the properties and number of children of a node at the
supplied location.
+ *
+ * @param of the location of the node whose children are to be read
+ * @param workspaceName the name of the workspace
+ * @param propertyName the name of the property to read
+ * @return this builder for method chaining; never null
+ * @throws IllegalArgumentException if the location or workspace name is null
+ */
+ public BatchRequestBuilder readProperty( Location of,
+ String workspaceName,
+ Name propertyName ) {
+ return add(new ReadPropertyRequest(of, workspaceName, propertyName));
+ }
+
+ /**
+ * Add a request to read the branch at the supplied location, to a maximum depth of
2.
+ *
+ * @param at the location of the branch
+ * @param workspaceName the name of the workspace containing the branch
+ * @return this builder for method chaining; never null
+ * @throws IllegalArgumentException if the location or workspace name is null or if
the maximum depth is not positive
+ */
+ public BatchRequestBuilder readBranch( Location at,
+ String workspaceName ) {
+ return add(new ReadBranchRequest(at, workspaceName));
+ }
+
+ /**
+ * Add a request to read the branch (of given depth) at the supplied location.
+ *
+ * @param at the location of the branch
+ * @param workspaceName the name of the workspace containing the branch
+ * @param maxDepth the maximum depth to read
+ * @return this builder for method chaining; never null
+ * @throws IllegalArgumentException if the location or workspace name is null or if
the maximum depth is not positive
+ */
+ public BatchRequestBuilder readBranch( Location at,
+ String workspaceName,
+ int maxDepth ) {
+ return add(new ReadBranchRequest(at, workspaceName, maxDepth));
+ }
+
+ /**
+ * Add a request to read a block of the children of a node at the supplied location.
The block is defined by the starting
+ * index of the first child and the number of children to include. Note that this
index is <i>not</i> the
+ * {@link Path.Segment#getIndex() same-name-sibiling index}, but rather is the index
of the child as if the children were in
+ * an array.
+ *
+ * @param of the location of the node whose children are to be read
+ * @param workspaceName the name of the workspace containing the parent
+ * @param startingIndex the zero-based index of the first child to be included in the
block
+ * @param count the maximum number of children that should be included in the block
+ * @return this builder for method chaining; never null
+ * @throws IllegalArgumentException if the location or workspace name is null, if
<code>startingIndex</code> is negative, or
+ * if <code>count</count> is less than 1.
+ */
+ public BatchRequestBuilder readBlockOfChildren( Location of,
+ String workspaceName,
+ int startingIndex,
+ int count ) {
+ return add(new ReadBlockOfChildrenRequest(of, workspaceName, startingIndex,
count));
+ }
+
+ /**
+ * Add a request to read those children of a node that are immediately after a
supplied sibling node.
+ *
+ * @param startingAfter the location of the previous sibling that was the last child
of the previous block of children read
+ * @param workspaceName the name of the workspace containing the node
+ * @param count the maximum number of children that should be included in the block
+ * @return this builder for method chaining; never null
+ * @throws IllegalArgumentException if the workspace name or
<code>startingAfter</code> location is null, or if
+ * <code>count</count> is less than 1.
+ */
+ public BatchRequestBuilder readNextBlockOfChildren( Location startingAfter,
+ String workspaceName,
+ int count ) {
+ return add(new ReadNextBlockOfChildrenRequest(startingAfter, workspaceName,
count));
+ }
+
+ /**
+ * Add a request to create a node with the given properties under the supplied
location.
+ *
+ * @param parentLocation the location of the existing parent node, under which the
new child should be created
+ * @param workspaceName the name of the workspace containing the parent
+ * @param childName the name of the new child to create under the existing parent
+ * @param properties the properties of the new node, which should include any {@link
Location#getIdProperties() identification
+ * properties} for the new node
+ * @return this builder for method chaining; never null
+ * @throws IllegalArgumentException if the location, workspace name, or child name is
null
+ */
+ public BatchRequestBuilder createNode( Location parentLocation,
+ String workspaceName,
+ Name childName,
+ Iterator<Property> properties ) {
+ return add(new CreateNodeRequest(parentLocation, workspaceName, childName,
CreateNodeRequest.DEFAULT_CONFLICT_BEHAVIOR,
+ properties));
+ }
+
+ /**
+ * Add a request to create a node with the given properties under the supplied
location.
+ *
+ * @param parentLocation the location of the existing parent node, under which the
new child should be created
+ * @param workspaceName the name of the workspace containing the parent
+ * @param childName the name of the new child to create under the existing parent
+ * @param properties the properties of the new node, which should include any {@link
Location#getIdProperties() identification
+ * properties} for the new node
+ * @param conflictBehavior the expected behavior if an equivalently-named child
already exists under the <code>into</code>
+ * location
+ * @return this builder for method chaining; never null
+ * @throws IllegalArgumentException if the location, workspace name, or child name is
null
+ */
+ public BatchRequestBuilder createNode( Location parentLocation,
+ String workspaceName,
+ Name childName,
+ Iterator<Property> properties,
+ NodeConflictBehavior conflictBehavior ) {
+ if (conflictBehavior == null) conflictBehavior =
CreateNodeRequest.DEFAULT_CONFLICT_BEHAVIOR;
+ return add(new CreateNodeRequest(parentLocation, workspaceName, childName,
conflictBehavior, properties));
+ }
+
+ /**
+ * Add a request to create a node with the given properties under the supplied
location.
+ *
+ * @param parentLocation the location of the existing parent node, under which the
new child should be created
+ * @param workspaceName the name of the workspace containing the parent
+ * @param childName the name of the new child to create under the existing parent
+ * @param properties the properties of the new node, which should include any {@link
Location#getIdProperties() identification
+ * properties} for the new node
+ * @return this builder for method chaining; never null
+ * @throws IllegalArgumentException if the location, workspace name, or child name is
null
+ */
+ public BatchRequestBuilder createNode( Location parentLocation,
+ String workspaceName,
+ Name childName,
+ Property[] properties ) {
+ return add(new CreateNodeRequest(parentLocation, workspaceName, childName,
CreateNodeRequest.DEFAULT_CONFLICT_BEHAVIOR,
+ properties));
+ }
+
+ /**
+ * Add a request to create a node with the given properties under the supplied
location.
+ *
+ * @param parentLocation the location of the existing parent node, under which the
new child should be created
+ * @param workspaceName the name of the workspace containing the parent
+ * @param childName the name of the new child to create under the existing parent
+ * @param properties the properties of the new node, which should include any {@link
Location#getIdProperties() identification
+ * properties} for the new node
+ * @param conflictBehavior the expected behavior if an equivalently-named child
already exists under the <code>into</code>
+ * location
+ * @return this builder for method chaining; never null
+ * @throws IllegalArgumentException if the location, workspace name, or child name is
null
+ */
+ public BatchRequestBuilder createNode( Location parentLocation,
+ String workspaceName,
+ Name childName,
+ Property[] properties,
+ NodeConflictBehavior conflictBehavior ) {
+ if (conflictBehavior == null) conflictBehavior =
CreateNodeRequest.DEFAULT_CONFLICT_BEHAVIOR;
+ return add(new CreateNodeRequest(parentLocation, workspaceName, childName,
conflictBehavior, properties));
+ }
+
+ /**
+ * Add a request to update the property on the node at the supplied location. This
request will create the property if it does
+ * not yet exist.
+ *
+ * @param on the location of the node to be read
+ * @param workspaceName the name of the workspace containing the node
+ * @param property the new property on the node
+ * @return this builder for method chaining; never null
+ * @throws IllegalArgumentException if the location or workspace name is null or if
there are no properties to update
+ */
+ public BatchRequestBuilder setProperty( Location on,
+ String workspaceName,
+ Property property ) {
+ // If there's a pending request ...
+ if (pendingRequest != null) {
+ // Compare the supplied location with that of the pending request
+ if (pendingRequest.location.equals(on)) {
+ // They are the same location, so we can add the properties to the
pending request ...
+ pendingRequest.pendingProperties.put(property.getName(), property);
+ return this;
+ }
+ // Not the exact same location, so push the existing pending request ...
+ addPending();
+ }
+
+ // Record this operation as a pending change ...
+ pendingRequest = new NodeChange(on, workspaceName);
+ pendingRequest.pendingProperties.put(property.getName(), property);
+ return this;
+ }
+
+ /**
+ * Add a request to update the properties on the node at the supplied location.
+ *
+ * @param on the location of the node to be read
+ * @param workspaceName the name of the workspace containing the node
+ * @param properties the new properties on the node
+ * @return this builder for method chaining; never null
+ * @throws IllegalArgumentException if the location or workspace name is null or if
there are no properties to update
+ */
+ public BatchRequestBuilder setProperties( Location on,
+ String workspaceName,
+ Property... properties ) {
+ // If there's a pending request ...
+ if (pendingRequest != null) {
+ // Compare the supplied location with that of the pending request
+ if (pendingRequest.location.equals(on)) {
+ // They are the same location, so we can add the properties to the
pending request ...
+ for (Property property : properties) {
+ pendingRequest.pendingProperties.put(property.getName(), property);
+ }
+ return this;
+ }
+ // Not the exact same location, so push the existing pending request ...
+ addPending();
+ }
+
+ // Record this operation as a pending change ...
+ pendingRequest = new NodeChange(on, workspaceName);
+ for (Property property : properties) {
+ pendingRequest.pendingProperties.put(property.getName(), property);
+ }
+ return this;
+ }
+
+ /**
+ * Add a request to remove the property with the supplied name from the given node.
Supplying a name for a property that does
+ * not exist will not cause an error.
+ *
+ * @param on the location of the node to be read
+ * @param workspaceName the name of the workspace containing the node
+ * @param propertyName the name of the property that is to be removed
+ * @return this builder for method chaining; never null
+ * @throws IllegalArgumentException if the location or workspace name is null or if
there are no properties to remove
+ */
+ public BatchRequestBuilder removeProperty( Location on,
+ String workspaceName,
+ Name propertyName ) {
+ // If there's a pending request ...
+ if (pendingRequest != null) {
+ // Compare the supplied location with that of the pending request
+ if (pendingRequest.location.equals(on)) {
+ // They are the same location, so we can add the properties to the
pending request ...
+ pendingRequest.pendingProperties.put(propertyName, null);
+ return this;
+ }
+ // Not the exact same location, so push the existing pending request ...
+ addPending();
+ }
+
+ // Record this operation as a pending change ...
+ pendingRequest = new NodeChange(on, workspaceName);
+ pendingRequest.pendingProperties.put(propertyName, null);
+ return this;
+ }
+
+ /**
+ * Add a request to remove from the node the properties with the supplied names.
Supplying a name for a property that does not
+ * exist will not cause an error.
+ *
+ * @param on the location of the node to be read
+ * @param workspaceName the name of the workspace containing the node
+ * @param propertyNames the names of the properties that are to be removed
+ * @return this builder for method chaining; never null
+ * @throws IllegalArgumentException if the location or workspace name is null or if
there are no properties to remove
+ */
+ public BatchRequestBuilder removeProperties( Location on,
+ String workspaceName,
+ Name... propertyNames ) {
+ // If there's a pending request ...
+ if (pendingRequest != null) {
+ // Compare the supplied location with that of the pending request
+ if (pendingRequest.location.equals(on)) {
+ // They are the same location, so we can add the properties to the
pending request ...
+ for (Name propertyName : propertyNames) {
+ pendingRequest.pendingProperties.put(propertyName, null);
+ }
+ return this;
+ }
+ // Not the exact same location, so push the existing pending request ...
+ addPending();
+ }
+
+ // Record this operation as a pending change ...
+ pendingRequest = new NodeChange(on, workspaceName);
+ for (Name propertyName : propertyNames) {
+ pendingRequest.pendingProperties.put(propertyName, null);
+ }
+ return this;
+ }
+
+ /**
+ * Add a request to rename the node at the supplied location.
+ *
+ * @param at the location of the node to be read
+ * @param workspaceName the name of the workspace containing the node
+ * @param newName the new name for the node
+ * @return this builder for method chaining; never null
+ * @throws IllegalArgumentException if the location or workspace name is null
+ */
+ public BatchRequestBuilder renameNode( Location at,
+ String workspaceName,
+ Name newName ) {
+ return add(new RenameNodeRequest(at, workspaceName, newName));
+ }
+
+ /**
+ * Add a request to copy a branch to another.
+ *
+ * @param from the location of the top node in the existing branch that is to be
copied
+ * @param fromWorkspace the name of the workspace where the
<code>from</code> node exists
+ * @param into the location of the existing node into which the copy should be
placed
+ * @param intoWorkspace the name of the workspace where the
<code>into</code> node is to be copied
+ * @param nameForCopy the desired name for the node that results from the copy, or
null if the name of the original should be
+ * used
+ * @return this builder for method chaining; never null
+ * @throws IllegalArgumentException if either of the locations or workspace names are
null
+ */
+ public BatchRequestBuilder copyBranch( Location from,
+ String fromWorkspace,
+ Location into,
+ String intoWorkspace,
+ Name nameForCopy ) {
+ return add(new CopyBranchRequest(from, fromWorkspace, into, intoWorkspace,
nameForCopy,
+ CopyBranchRequest.DEFAULT_CONFLICT_BEHAVIOR));
+ }
+
+ /**
+ * Add a request to copy a branch to another.
+ *
+ * @param from the location of the top node in the existing branch that is to be
copied
+ * @param fromWorkspace the name of the workspace where the
<code>from</code> node exists
+ * @param into the location of the existing node into which the copy should be
placed
+ * @param intoWorkspace the name of the workspace where the
<code>into</code> node is to be copied
+ * @param nameForCopy the desired name for the node that results from the copy, or
null if the name of the original should be
+ * used
+ * @param conflictBehavior the expected behavior if an equivalently-named child
already exists at the <code>into</code>
+ * location, or null if the default conflict behavior should be used
+ * @return this builder for method chaining; never null
+ * @throws IllegalArgumentException if either of the locations or workspace names are
null
+ */
+ public BatchRequestBuilder copyBranch( Location from,
+ String fromWorkspace,
+ Location into,
+ String intoWorkspace,
+ Name nameForCopy,
+ NodeConflictBehavior conflictBehavior ) {
+ if (conflictBehavior == null) conflictBehavior =
CopyBranchRequest.DEFAULT_CONFLICT_BEHAVIOR;
+ return add(new CopyBranchRequest(from, fromWorkspace, into, intoWorkspace,
nameForCopy, conflictBehavior));
+ }
+
+ /**
+ * Create a request to move a branch from one location into another.
+ *
+ * @param from the location of the top node in the existing branch that is to be
moved
+ * @param into the location of the existing node into which the branch should be
moved
+ * @param workspaceName the name of the workspace
+ * @return this builder for method chaining; never null
+ * @throws IllegalArgumentException if any of the parameters are null
+ */
+ public BatchRequestBuilder moveBranch( Location from,
+ Location into,
+ String workspaceName ) {
+ return add(new MoveBranchRequest(from, into, workspaceName,
MoveBranchRequest.DEFAULT_CONFLICT_BEHAVIOR));
+ }
+
+ /**
+ * Create a request to move a branch from one location into another.
+ *
+ * @param from the location of the top node in the existing branch that is to be
moved
+ * @param into the location of the existing node into which the branch should be
moved
+ * @param workspaceName the name of the workspace
+ * @param conflictBehavior the expected behavior if an equivalently-named child
already exists at the <code>into</code>
+ * location
+ * @return this builder for method chaining; never null
+ * @throws IllegalArgumentException if any of the parameters are null
+ */
+ public BatchRequestBuilder moveBranch( Location from,
+ Location into,
+ String workspaceName,
+ NodeConflictBehavior conflictBehavior ) {
+ if (conflictBehavior == null) conflictBehavior =
MoveBranchRequest.DEFAULT_CONFLICT_BEHAVIOR;
+ return add(new MoveBranchRequest(from, into, workspaceName, conflictBehavior));
+ }
+
+ /**
+ * Add a request to delete a branch.
+ *
+ * @param at the location of the top node in the existing branch that is to be
deleted
+ * @param workspaceName the name of the workspace containing the parent
+ * @return this builder for method chaining; never null
+ * @throws IllegalArgumentException if the location or workspace name is null
+ */
+ public BatchRequestBuilder deleteBranch( Location at,
+ String workspaceName ) {
+ return add(new DeleteBranchRequest(at, workspaceName));
+ }
+
+ protected class NodeChange {
+ protected final Location location;
+ protected final String workspaceName;
+ protected final Map<Name, Property> pendingProperties = new
HashMap<Name, Property>();
+
+ protected NodeChange( Location location,
+ String workspaceName ) {
+ this.location = location;
+ this.workspaceName = workspaceName;
+ }
+
+ protected Request toRequest() {
+ if (pendingProperties.size() == 1) {
+ Map.Entry<Name, Property> entry =
pendingProperties.entrySet().iterator().next();
+ Property property = entry.getValue();
+ if (property == null) {
+ return new RemovePropertyRequest(location, workspaceName,
entry.getKey());
+ }
+ return new SetPropertyRequest(location, workspaceName, property);
+ }
+ return new UpdatePropertiesRequest(location, workspaceName,
pendingProperties);
+ }
+ }
+
+}
Property changes on:
trunk/dna-graph/src/main/java/org/jboss/dna/graph/request/BatchRequestBuilder.java
___________________________________________________________________
Name: svn:mime-type
+ text/plain
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-04-06
15:55:23 UTC (rev 808)
+++
trunk/dna-graph/src/main/java/org/jboss/dna/graph/request/CloneWorkspaceRequest.java 2009-04-07
21:23:28 UTC (rev 809)
@@ -73,6 +73,7 @@
* @param desiredNameOfTargetWorkspace the desired name of the target workspace
* @param createConflictBehavior the behavior if a workspace already exists with the
same name
* @param cloneConflictBehavior the behavior if the workspace to be cloned does not
exist
+ * @throws IllegalArgumentException if the either workspace name is null
*/
public CloneWorkspaceRequest( String nameOfWorkspaceToBeCloned,
String desiredNameOfTargetWorkspace,
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-04-06
15:55:23 UTC (rev 808)
+++
trunk/dna-graph/src/main/java/org/jboss/dna/graph/request/DeleteBranchRequest.java 2009-04-07
21:23:28 UTC (rev 809)
@@ -46,7 +46,7 @@
*
* @param at the location of the top node in the existing branch that is to be
deleted
* @param workspaceName the name of the workspace containing the parent
- * @throws IllegalArgumentException if the location is null
+ * @throws IllegalArgumentException if the location or workspace name is null
*/
public DeleteBranchRequest( Location at,
String workspaceName ) {
Modified:
trunk/dna-graph/src/main/java/org/jboss/dna/graph/request/DestroyWorkspaceRequest.java
===================================================================
---
trunk/dna-graph/src/main/java/org/jboss/dna/graph/request/DestroyWorkspaceRequest.java 2009-04-06
15:55:23 UTC (rev 808)
+++
trunk/dna-graph/src/main/java/org/jboss/dna/graph/request/DestroyWorkspaceRequest.java 2009-04-07
21:23:28 UTC (rev 809)
@@ -38,6 +38,7 @@
* Create a request to destroy an existing workspace.
*
* @param workspaceName the name of the workspace that is to be destroyed
+ * @throws IllegalArgumentException if the workspace name is null
*/
public DestroyWorkspaceRequest( String workspaceName ) {
CheckArg.isNotNull(workspaceName, "workspaceName");
Deleted:
trunk/dna-graph/src/main/java/org/jboss/dna/graph/request/RemovePropertiesRequest.java
===================================================================
---
trunk/dna-graph/src/main/java/org/jboss/dna/graph/request/RemovePropertiesRequest.java 2009-04-06
15:55:23 UTC (rev 808)
+++
trunk/dna-graph/src/main/java/org/jboss/dna/graph/request/RemovePropertiesRequest.java 2009-04-07
21:23:28 UTC (rev 809)
@@ -1,248 +0,0 @@
-/*
- * 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.request;
-
-import java.util.Collection;
-import java.util.Collections;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.Set;
-import org.jboss.dna.common.util.CheckArg;
-import org.jboss.dna.graph.GraphI18n;
-import org.jboss.dna.graph.Location;
-import org.jboss.dna.graph.property.Name;
-import org.jboss.dna.graph.property.Path;
-
-/**
- * Instruction to remove properties from the node at the specified location.
- *
- * @author Randall Hauch
- */
-public class RemovePropertiesRequest extends Request implements Iterable<Name>,
ChangeRequest {
-
- private static final long serialVersionUID = 1L;
-
- private final Location from;
- private final String workspaceName;
- private final Set<Name> propertyNames;
- private Location actualLocation;
-
- /**
- * Create a request to remove the properties with the given names from the node at
the supplied location.
- *
- * @param from the location of the node to be read
- * @param workspaceName the name of the workspace containing the node
- * @param propertyNames the names of the properties to be removed from the node
- * @throws IllegalArgumentException if the location is null or if there are no
properties to remove
- */
- public RemovePropertiesRequest( Location from,
- String workspaceName,
- Name... propertyNames ) {
- CheckArg.isNotNull(from, "from");
- CheckArg.isNotEmpty(propertyNames, "propertyNames");
- CheckArg.isNotNull(workspaceName, "workspaceName");
- this.workspaceName = workspaceName;
- this.from = from;
- Set<Name> names = new HashSet<Name>();
- for (Name name : propertyNames) {
- if (name != null) names.add(name);
- }
- this.propertyNames = Collections.unmodifiableSet(names);
- }
-
- /**
- * Create a request to remove the properties with the given names from the node at
the supplied location.
- *
- * @param from the location of the node to be read
- * @param workspaceName the name of the workspace containing the node
- * @param propertyNames the names of the properties to be removed from the node
- * @throws IllegalArgumentException if the location is null or if there are no
properties to remove
- */
- public RemovePropertiesRequest( Location from,
- String workspaceName,
- Iterable<Name> propertyNames ) {
- CheckArg.isNotNull(from, "from");
- CheckArg.isNotNull(propertyNames, "propertyNames");
- CheckArg.isNotNull(workspaceName, "workspaceName");
- this.workspaceName = workspaceName;
- this.from = from;
- Set<Name> names = new HashSet<Name>();
- for (Name name : propertyNames) {
- if (name != null) names.add(name);
- }
- this.propertyNames = Collections.unmodifiableSet(names);
- CheckArg.isNotEmpty(this.propertyNames, "propertyNames");
- }
-
- /**
- * Create a request to remove the properties with the given names from the node at
the supplied location.
- *
- * @param from the location of the node to be read
- * @param workspaceName the name of the workspace containing the node
- * @param propertyNames the names of the properties to be removed from the node
- * @throws IllegalArgumentException if the location is null or if there are no
properties to remove
- */
- public RemovePropertiesRequest( Location from,
- String workspaceName,
- Iterator<Name> propertyNames ) {
- CheckArg.isNotNull(from, "from");
- CheckArg.isNotNull(propertyNames, "propertyNames");
- CheckArg.isNotNull(workspaceName, "workspaceName");
- this.workspaceName = workspaceName;
- this.from = from;
- Set<Name> names = new HashSet<Name>();
- while (propertyNames.hasNext()) {
- Name name = propertyNames.next();
- if (name != null) names.add(name);
- }
- this.propertyNames = Collections.unmodifiableSet(names);
- CheckArg.isNotEmpty(this.propertyNames, "propertyNames");
- }
-
- /**
- * {@inheritDoc}
- *
- * @see org.jboss.dna.graph.request.Request#isReadOnly()
- */
- @Override
- public boolean isReadOnly() {
- return false;
- }
-
- /**
- * Get the location defining the node from which the properties are to be removed.
- *
- * @return the location of the node; never null
- */
- public Location from() {
- return from;
- }
-
- /**
- * Get the name of the workspace in which the node exists.
- *
- * @return the name of the workspace; never null
- */
- public String inWorkspace() {
- return workspaceName;
- }
-
- /**
- * {@inheritDoc}
- *
- * @see java.lang.Iterable#iterator()
- */
- public Iterator<Name> iterator() {
- return this.propertyNames.iterator();
- }
-
- /**
- * Get the names of the properties that are to be removed from the node.
- *
- * @return the collection of property names; never null and never empty
- */
- public Collection<Name> propertyNames() {
- return propertyNames;
- }
-
- /**
- * Sets the actual and complete location of the node whose properties were removed.
This method must be called when processing
- * the request, and the actual location must have a {@link Location#getPath() path}.
- *
- * @param actual the actual location of the node being changed, or null if the {@link
#from() current location} should be used
- * @throws IllegalArgumentException if the actual location does not represent the
{@link Location#isSame(Location) same
- * location} as the {@link #from() current location}, or if the actual
location does not have a path.
- */
- public void setActualLocationOfNode( Location actual ) {
- if (!from.isSame(actual)) { // not same if actual is null
- throw new
IllegalArgumentException(GraphI18n.actualLocationIsNotSameAsInputLocation.text(actual,
from));
- }
- assert actual != null;
- if (!actual.hasPath()) {
- throw new
IllegalArgumentException(GraphI18n.actualLocationMustHavePath.text(actual));
- }
- this.actualLocation = actual;
- }
-
- /**
- * Get the actual location of the node whose properties were removed.
- *
- * @return the actual location, or null if the actual location was not set
- */
- public Location getActualLocationOfNode() {
- return actualLocation;
- }
-
- /**
- * {@inheritDoc}
- *
- * @see org.jboss.dna.graph.request.ChangeRequest#changes(java.lang.String,
org.jboss.dna.graph.property.Path)
- */
- public boolean changes( String workspace,
- Path path ) {
- return this.workspaceName.equals(workspace) && from.hasPath() &&
from.getPath().isAtOrBelow(path);
- }
-
- /**
- * {@inheritDoc}
- *
- * @see org.jboss.dna.graph.request.ChangeRequest#changedLocation()
- */
- public Location changedLocation() {
- return from;
- }
-
- /**
- * {@inheritDoc}
- *
- * @see java.lang.Object#equals(java.lang.Object)
- */
- @Override
- public boolean equals( Object obj ) {
- if (obj == this) return true;
- if (this.getClass().isInstance(obj)) {
- RemovePropertiesRequest that = (RemovePropertiesRequest)obj;
- if (!this.from().equals(that.from())) return false;
- if (!this.propertyNames().equals(that.propertyNames())) return false;
- if (!this.inWorkspace().equals(that.inWorkspace())) return false;
- return true;
- }
- return false;
- }
-
- /**
- * {@inheritDoc}
- *
- * @see java.lang.Object#toString()
- */
- @Override
- public String toString() {
- if (propertyNames.size() == 1) {
- return "remove from " + from() + " in the \"" +
workspaceName + "\" workspace the property named "
- + propertyNames.iterator().next();
- }
- return "remove from " + from() + " in the \"" +
workspaceName + "\" workspace the properties named " + propertyNames();
- }
-
-}
Added:
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
(rev 0)
+++
trunk/dna-graph/src/main/java/org/jboss/dna/graph/request/RemovePropertyRequest.java 2009-04-07
21:23:28 UTC (rev 809)
@@ -0,0 +1,177 @@
+/*
+ * 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.request;
+
+import org.jboss.dna.common.util.CheckArg;
+import org.jboss.dna.graph.GraphI18n;
+import org.jboss.dna.graph.Location;
+import org.jboss.dna.graph.property.Name;
+import org.jboss.dna.graph.property.Path;
+
+/**
+ * Instruction to remove the property with the supplied name from the node at the given
location. This request has no net effect
+ * if the node does not contain a property with the supplied name.
+ *
+ * @author Randall Hauch
+ */
+public class RemovePropertyRequest extends Request implements ChangeRequest {
+
+ private static final long serialVersionUID = 1L;
+
+ private final Location from;
+ private final String workspaceName;
+ private final Name propertyName;
+ private Location actualLocation;
+
+ /**
+ * Create a request to remove a named property from the node at the supplied
location.
+ *
+ * @param from the location of the node to be read
+ * @param workspaceName the name of the workspace containing the node
+ * @param propertyName the name of the property to be removed
+ * @throws IllegalArgumentException if the location, workspace name, or property name
is null
+ */
+ public RemovePropertyRequest( Location from,
+ String workspaceName,
+ Name propertyName ) {
+ CheckArg.isNotNull(from, "from");
+ CheckArg.isNotNull(propertyName, "propertyName");
+ CheckArg.isNotNull(workspaceName, "workspaceName");
+ this.workspaceName = workspaceName;
+ this.from = from;
+ this.propertyName = propertyName;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.jboss.dna.graph.request.Request#isReadOnly()
+ */
+ @Override
+ public boolean isReadOnly() {
+ return false;
+ }
+
+ /**
+ * Get the location defining the node from which the property is to be removed.
+ *
+ * @return the location of the node; never null
+ */
+ public Location from() {
+ return from;
+ }
+
+ /**
+ * Get the name of the workspace in which the node exists.
+ *
+ * @return the name of the workspace; never null
+ */
+ public String inWorkspace() {
+ return workspaceName;
+ }
+
+ /**
+ * Get the name of the property that is being removed.
+ *
+ * @return the property name; never null
+ */
+ public Name propertyName() {
+ return propertyName;
+ }
+
+ /**
+ * Sets the actual and complete location of the node being updated. This method must
be called when processing the request,
+ * and the actual location must have a {@link Location#getPath() path}.
+ *
+ * @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.
+ */
+ public void setActualLocationOfNode( Location actual ) {
+ if (!from.isSame(actual)) { // not same if actual is null
+ throw new
IllegalArgumentException(GraphI18n.actualLocationIsNotSameAsInputLocation.text(actual,
from));
+ }
+ assert actual != null;
+ if (!actual.hasPath()) {
+ throw new
IllegalArgumentException(GraphI18n.actualLocationMustHavePath.text(actual));
+ }
+ this.actualLocation = actual;
+ }
+
+ /**
+ * Get the actual location of the node that was updated.
+ *
+ * @return the actual location, or null if the actual location was not set
+ */
+ public Location getActualLocationOfNode() {
+ return actualLocation;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.jboss.dna.graph.request.ChangeRequest#changes(java.lang.String,
org.jboss.dna.graph.property.Path)
+ */
+ public boolean changes( String workspace,
+ Path path ) {
+ return this.workspaceName.equals(workspace) && from.hasPath() &&
from.getPath().isAtOrBelow(path);
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see java.lang.Object#equals(java.lang.Object)
+ */
+ @Override
+ public boolean equals( Object obj ) {
+ if (obj == this) return true;
+ if (this.getClass().isInstance(obj)) {
+ RemovePropertyRequest that = (RemovePropertyRequest)obj;
+ if (!this.from().equals(that.from())) return false;
+ if (!this.propertyName().equals(that.propertyName())) return false;
+ if (!this.inWorkspace().equals(that.inWorkspace())) return false;
+ return true;
+ }
+ return false;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.jboss.dna.graph.request.ChangeRequest#changedLocation()
+ */
+ public Location changedLocation() {
+ return from;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see java.lang.Object#toString()
+ */
+ @Override
+ public String toString() {
+ return "remove property " + propertyName() + " from " +
from() + " in the \"" + workspaceName + "\" workspace";
+ }
+}
Property changes on:
trunk/dna-graph/src/main/java/org/jboss/dna/graph/request/RemovePropertyRequest.java
___________________________________________________________________
Name: svn:mime-type
+ text/plain
Added: trunk/dna-graph/src/main/java/org/jboss/dna/graph/request/RequestBuilder.java
===================================================================
--- trunk/dna-graph/src/main/java/org/jboss/dna/graph/request/RequestBuilder.java
(rev 0)
+++
trunk/dna-graph/src/main/java/org/jboss/dna/graph/request/RequestBuilder.java 2009-04-07
21:23:28 UTC (rev 809)
@@ -0,0 +1,494 @@
+/*
+ * 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.
+ *
+ * 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.request;
+
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+import org.jboss.dna.graph.Location;
+import org.jboss.dna.graph.NodeConflictBehavior;
+import org.jboss.dna.graph.property.Name;
+import org.jboss.dna.graph.property.Path;
+import org.jboss.dna.graph.property.Property;
+import org.jboss.dna.graph.request.CloneWorkspaceRequest.CloneConflictBehavior;
+import org.jboss.dna.graph.request.CreateWorkspaceRequest.CreateConflictBehavior;
+
+/**
+ * A component that can be used to build requests while allowing different strategies for
how requests are handled. Subclasses can
+ * simply override the {@link #process(Request)} method to define what happens with each
request.
+ */
+public abstract class RequestBuilder {
+
+ /**
+ * Create a new builder.
+ */
+ protected RequestBuilder() {
+ }
+
+ protected abstract <T extends Request> T process( T request );
+
+ /**
+ * Add a request to obtain the information about the available workspaces.
+ *
+ * @return the request; never null
+ */
+ public GetWorkspacesRequest getWorkspaces() {
+ GetWorkspacesRequest request = new GetWorkspacesRequest();
+ process(request);
+ return request;
+ }
+
+ /**
+ * Add a request to verify the existance of the named workspace.
+ *
+ * @param workspaceName the desired name of the workspace, or null if the
source's default workspace should be used
+ * @return the request; never null
+ */
+ public VerifyWorkspaceRequest verifyWorkspace( String workspaceName ) {
+ return process(new VerifyWorkspaceRequest(workspaceName));
+ }
+
+ /**
+ * Add a request to create a new workspace, and specify the behavior should a
workspace already exists with a name that
+ * matches the desired name for the new workspace.
+ *
+ * @param desiredNameOfNewWorkspace the desired name of the new workspace
+ * @param createConflictBehavior the behavior if a workspace already exists with the
same name, or null if the default
+ * behavior should be used
+ * @return the request; never null
+ */
+ public CreateWorkspaceRequest createWorkspace( String desiredNameOfNewWorkspace,
+ CreateConflictBehavior
createConflictBehavior ) {
+ return process(new CreateWorkspaceRequest(desiredNameOfNewWorkspace,
createConflictBehavior));
+ }
+
+ /**
+ * Add a request to clone an existing workspace to create a new workspace, and
specify the behavior should a workspace already
+ * exists with a name that matches the desired name for the new workspace.
+ *
+ * @param nameOfWorkspaceToBeCloned the name of the existing workspace that is to be
cloned
+ * @param desiredNameOfTargetWorkspace the desired name of the target workspace
+ * @param createConflictBehavior the behavior if a workspace already exists with the
same name
+ * @param cloneConflictBehavior the behavior if the workspace to be cloned does not
exist
+ * @return the request; never null
+ * @throws IllegalArgumentException if the either workspace name is null
+ */
+ public CloneWorkspaceRequest cloneWorkspace( String nameOfWorkspaceToBeCloned,
+ String desiredNameOfTargetWorkspace,
+ CreateConflictBehavior
createConflictBehavior,
+ CloneConflictBehavior
cloneConflictBehavior ) {
+ return process(new CloneWorkspaceRequest(nameOfWorkspaceToBeCloned,
desiredNameOfTargetWorkspace, createConflictBehavior,
+ cloneConflictBehavior));
+ }
+
+ /**
+ * Add a request to destroy an existing workspace.
+ *
+ * @param workspaceName the name of the workspace that is to be destroyed
+ * @return the request; never null
+ * @throws IllegalArgumentException if the workspace name is null
+ */
+ public DestroyWorkspaceRequest destroyWorkspace( String workspaceName ) {
+ return process(new DestroyWorkspaceRequest(workspaceName));
+ }
+
+ /**
+ * Add a request to verify the existance and location of a node at the supplied
location.
+ *
+ * @param at the location of the node to be verified
+ * @param workspaceName the name of the workspace containing the node
+ * @return the request; never null
+ * @throws IllegalArgumentException if the location or workspace name is null
+ */
+ public VerifyNodeExistsRequest verifyNodeExists( Location at,
+ String workspaceName ) {
+ return process(new VerifyNodeExistsRequest(at, workspaceName));
+ }
+
+ /**
+ * Add a request to read the properties and number of children of a node at the
supplied location.
+ *
+ * @param at the location of the node to be read
+ * @param workspaceName the name of the workspace containing the node
+ * @return the request; never null
+ * @throws IllegalArgumentException if the location or workspace name is null
+ */
+ public ReadNodeRequest readNode( Location at,
+ String workspaceName ) {
+ return process(new ReadNodeRequest(at, workspaceName));
+ }
+
+ /**
+ * Add a request to read the children of a node at the supplied location in the
designated workspace.
+ *
+ * @param of the location of the node whose children are to be read
+ * @param workspaceName the name of the workspace
+ * @return the request; never null
+ * @throws IllegalArgumentException if the location or workspace name is null
+ */
+ public ReadAllChildrenRequest readAllChildren( Location of,
+ String workspaceName ) {
+ return process(new ReadAllChildrenRequest(of, workspaceName));
+ }
+
+ /**
+ * Add a request to read the properties and number of children of a node at the
supplied location.
+ *
+ * @param of the location of the node whose children are to be read
+ * @param workspaceName the name of the workspace
+ * @return the request; never null
+ * @throws IllegalArgumentException if the location or workspace name is null
+ */
+ public ReadAllPropertiesRequest readAllProperties( Location of,
+ String workspaceName ) {
+ return process(new ReadAllPropertiesRequest(of, workspaceName));
+ }
+
+ /**
+ * Add a request to read the properties and number of children of a node at the
supplied location.
+ *
+ * @param of the location of the node whose children are to be read
+ * @param workspaceName the name of the workspace
+ * @param propertyName the name of the property to read
+ * @return the request; never null
+ * @throws IllegalArgumentException if the location or workspace name is null
+ */
+ public ReadPropertyRequest readProperty( Location of,
+ String workspaceName,
+ Name propertyName ) {
+ return process(new ReadPropertyRequest(of, workspaceName, propertyName));
+ }
+
+ /**
+ * Add a request to read the branch at the supplied location, to a maximum depth of
2.
+ *
+ * @param at the location of the branch
+ * @param workspaceName the name of the workspace containing the branch
+ * @return the request; never null
+ * @throws IllegalArgumentException if the location or workspace name is null or if
the maximum depth is not positive
+ */
+ public ReadBranchRequest readBranch( Location at,
+ String workspaceName ) {
+ return process(new ReadBranchRequest(at, workspaceName));
+ }
+
+ /**
+ * Add a request to read the branch (of given depth) at the supplied location.
+ *
+ * @param at the location of the branch
+ * @param workspaceName the name of the workspace containing the branch
+ * @param maxDepth the maximum depth to read
+ * @return the request; never null
+ * @throws IllegalArgumentException if the location or workspace name is null or if
the maximum depth is not positive
+ */
+ public ReadBranchRequest readBranch( Location at,
+ String workspaceName,
+ int maxDepth ) {
+ return process(new ReadBranchRequest(at, workspaceName, maxDepth));
+ }
+
+ /**
+ * Add a request to read a block of the children of a node at the supplied location.
The block is defined by the starting
+ * index of the first child and the number of children to include. Note that this
index is <i>not</i> the
+ * {@link Path.Segment#getIndex() same-name-sibiling index}, but rather is the index
of the child as if the children were in
+ * an array.
+ *
+ * @param of the location of the node whose children are to be read
+ * @param workspaceName the name of the workspace containing the parent
+ * @param startingIndex the zero-based index of the first child to be included in the
block
+ * @param count the maximum number of children that should be included in the block
+ * @return the request; never null
+ * @throws IllegalArgumentException if the location or workspace name is null, if
<code>startingIndex</code> is negative, or
+ * if <code>count</count> is less than 1.
+ */
+ public ReadBlockOfChildrenRequest readBlockOfChildren( Location of,
+ String workspaceName,
+ int startingIndex,
+ int count ) {
+ return process(new ReadBlockOfChildrenRequest(of, workspaceName, startingIndex,
count));
+ }
+
+ /**
+ * Add a request to read those children of a node that are immediately after a
supplied sibling node.
+ *
+ * @param startingAfter the location of the previous sibling that was the last child
of the previous block of children read
+ * @param workspaceName the name of the workspace containing the node
+ * @param count the maximum number of children that should be included in the block
+ * @return the request; never null
+ * @throws IllegalArgumentException if the workspace name or
<code>startingAfter</code> location is null, or if
+ * <code>count</count> is less than 1.
+ */
+ public ReadNextBlockOfChildrenRequest readNextBlockOfChildren( Location
startingAfter,
+ String workspaceName,
+ int count ) {
+ return process(new ReadNextBlockOfChildrenRequest(startingAfter, workspaceName,
count));
+ }
+
+ /**
+ * Add a request to create a node with the given properties under the supplied
location.
+ *
+ * @param parentLocation the location of the existing parent node, under which the
new child should be created
+ * @param workspaceName the name of the workspace containing the parent
+ * @param childName the name of the new child to create under the existing parent
+ * @param properties the properties of the new node, which should include any {@link
Location#getIdProperties() identification
+ * properties} for the new node
+ * @return the request; never null
+ * @throws IllegalArgumentException if the location, workspace name, or child name is
null
+ */
+ public CreateNodeRequest createNode( Location parentLocation,
+ String workspaceName,
+ Name childName,
+ Iterator<Property> properties ) {
+ return process(new CreateNodeRequest(parentLocation, workspaceName, childName,
+ CreateNodeRequest.DEFAULT_CONFLICT_BEHAVIOR,
properties));
+ }
+
+ /**
+ * Add a request to create a node with the given properties under the supplied
location.
+ *
+ * @param parentLocation the location of the existing parent node, under which the
new child should be created
+ * @param workspaceName the name of the workspace containing the parent
+ * @param childName the name of the new child to create under the existing parent
+ * @param properties the properties of the new node, which should include any {@link
Location#getIdProperties() identification
+ * properties} for the new node
+ * @param conflictBehavior the expected behavior if an equivalently-named child
already exists under the <code>into</code>
+ * location
+ * @return the request; never null
+ * @throws IllegalArgumentException if the location, workspace name, or child name is
null
+ */
+ public CreateNodeRequest createNode( Location parentLocation,
+ String workspaceName,
+ Name childName,
+ Iterator<Property> properties,
+ NodeConflictBehavior conflictBehavior ) {
+ if (conflictBehavior == null) conflictBehavior =
CreateNodeRequest.DEFAULT_CONFLICT_BEHAVIOR;
+ return process(new CreateNodeRequest(parentLocation, workspaceName, childName,
conflictBehavior, properties));
+ }
+
+ /**
+ * Add a request to create a node with the given properties under the supplied
location.
+ *
+ * @param parentLocation the location of the existing parent node, under which the
new child should be created
+ * @param workspaceName the name of the workspace containing the parent
+ * @param childName the name of the new child to create under the existing parent
+ * @param properties the properties of the new node, which should include any {@link
Location#getIdProperties() identification
+ * properties} for the new node
+ * @return the request; never null
+ * @throws IllegalArgumentException if the location, workspace name, or child name is
null
+ */
+ public CreateNodeRequest createNode( Location parentLocation,
+ String workspaceName,
+ Name childName,
+ Property[] properties ) {
+ return process(new CreateNodeRequest(parentLocation, workspaceName, childName,
+ CreateNodeRequest.DEFAULT_CONFLICT_BEHAVIOR,
properties));
+ }
+
+ /**
+ * Add a request to create a node with the given properties under the supplied
location.
+ *
+ * @param parentLocation the location of the existing parent node, under which the
new child should be created
+ * @param workspaceName the name of the workspace containing the parent
+ * @param childName the name of the new child to create under the existing parent
+ * @param properties the properties of the new node, which should include any {@link
Location#getIdProperties() identification
+ * properties} for the new node
+ * @param conflictBehavior the expected behavior if an equivalently-named child
already exists under the <code>into</code>
+ * location
+ * @return the request; never null
+ * @throws IllegalArgumentException if the location, workspace name, or child name is
null
+ */
+ public CreateNodeRequest createNode( Location parentLocation,
+ String workspaceName,
+ Name childName,
+ Property[] properties,
+ NodeConflictBehavior conflictBehavior ) {
+ if (conflictBehavior == null) conflictBehavior =
CreateNodeRequest.DEFAULT_CONFLICT_BEHAVIOR;
+ return process(new CreateNodeRequest(parentLocation, workspaceName, childName,
conflictBehavior, properties));
+ }
+
+ /**
+ * Add a request to update the property on the node at the supplied location. This
request will create the property if it does
+ * not yet exist.
+ *
+ * @param on the location of the node to be read
+ * @param workspaceName the name of the workspace containing the node
+ * @param property the new property on the node
+ * @return the request; never null
+ * @throws IllegalArgumentException if the location or workspace name is null or if
there are no properties to update
+ */
+ public SetPropertyRequest setProperty( Location on,
+ String workspaceName,
+ Property property ) {
+ return process(new SetPropertyRequest(on, workspaceName, property));
+ }
+
+ /**
+ * Add a request to update the properties on the node at the supplied location.
+ *
+ * @param on the location of the node to be read
+ * @param workspaceName the name of the workspace containing the node
+ * @param properties the new properties on the node
+ * @return the {@link SetPropertyRequest} or {@link UpdatePropertiesRequest} request,
depending upon the number of properties
+ * being set; never null
+ * @throws IllegalArgumentException if the location or workspace name is null or if
there are no properties to update
+ */
+ public Request setProperties( Location on,
+ String workspaceName,
+ Property... properties ) {
+ if (properties.length == 1) {
+ return process(new SetPropertyRequest(on, workspaceName, properties[0]));
+ }
+ Map<Name, Property> propertyMap = new HashMap<Name, Property>();
+ for (Property property : properties) {
+ propertyMap.put(property.getName(), property);
+ }
+ return process(new UpdatePropertiesRequest(on, workspaceName, propertyMap));
+ }
+
+ /**
+ * Add a request to remove the property with the supplied name from the given node.
Supplying a name for a property that does
+ * not exist will not cause an error.
+ *
+ * @param on the location of the node to be read
+ * @param workspaceName the name of the workspace containing the node
+ * @param propertyName the name of the property that is to be removed
+ * @return the request; never null
+ * @throws IllegalArgumentException if the location or workspace name is null or if
there are no properties to remove
+ */
+ public RemovePropertyRequest removeProperty( Location on,
+ String workspaceName,
+ Name propertyName ) {
+ return process(new RemovePropertyRequest(on, workspaceName, propertyName));
+ }
+
+ /**
+ * Add a request to remove from the node the properties with the supplied names.
Supplying a name for a property that does not
+ * exist will not cause an error.
+ *
+ * @param on the location of the node to be read
+ * @param workspaceName the name of the workspace containing the node
+ * @param propertyNames the names of the properties that are to be removed
+ * @return the {@link RemovePropertyRequest} or {@link UpdatePropertiesRequest}
request, depending upon the number of
+ * properties being removed; never null
+ * @throws IllegalArgumentException if the location or workspace name is null or if
there are no properties to remove
+ */
+ public Request removeProperties( Location on,
+ String workspaceName,
+ Name... propertyNames ) {
+ if (propertyNames.length == 1) {
+ return process(new RemovePropertyRequest(on, workspaceName,
propertyNames[0]));
+ }
+ Map<Name, Property> properties = new HashMap<Name, Property>();
+ for (Name propertyName : propertyNames) {
+ properties.put(propertyName, null);
+ }
+ return process(new UpdatePropertiesRequest(on, workspaceName, properties));
+ }
+
+ /**
+ * Add a request to rename the node at the supplied location.
+ *
+ * @param at the location of the node to be read
+ * @param workspaceName the name of the workspace containing the node
+ * @param newName the new name for the node
+ * @return the request; never null
+ * @throws IllegalArgumentException if the location or workspace name is null
+ */
+ public RenameNodeRequest renameNode( Location at,
+ String workspaceName,
+ Name newName ) {
+ return process(new RenameNodeRequest(at, workspaceName, newName));
+ }
+
+ /**
+ * Add a request to copy a branch to another.
+ *
+ * @param from the location of the top node in the existing branch that is to be
copied
+ * @param fromWorkspace the name of the workspace where the
<code>from</code> node exists
+ * @param into the location of the existing node into which the copy should be
placed
+ * @param intoWorkspace the name of the workspace where the
<code>into</code> node is to be copied
+ * @param nameForCopy the desired name for the node that results from the copy, or
null if the name of the original should be
+ * used
+ * @param conflictBehavior the expected behavior if an equivalently-named child
already exists at the <code>into</code>
+ * location, or null if the default conflict behavior should be used
+ * @return the request; never null
+ * @throws IllegalArgumentException if either of the locations or workspace names are
null
+ */
+ public CopyBranchRequest copyBranch( Location from,
+ String fromWorkspace,
+ Location into,
+ String intoWorkspace,
+ Name nameForCopy,
+ NodeConflictBehavior conflictBehavior ) {
+ if (conflictBehavior == null) conflictBehavior =
CopyBranchRequest.DEFAULT_CONFLICT_BEHAVIOR;
+ return process(new CopyBranchRequest(from, fromWorkspace, into, intoWorkspace,
nameForCopy, conflictBehavior));
+ }
+
+ /**
+ * Create a request to move a branch from one location into another.
+ *
+ * @param from the location of the top node in the existing branch that is to be
moved
+ * @param into the location of the existing node into which the branch should be
moved
+ * @param workspaceName the name of the workspace
+ * @return the request; never null
+ * @throws IllegalArgumentException if any of the parameters are null
+ */
+ public MoveBranchRequest moveBranch( Location from,
+ Location into,
+ String workspaceName ) {
+ return process(new MoveBranchRequest(from, into, workspaceName,
MoveBranchRequest.DEFAULT_CONFLICT_BEHAVIOR));
+ }
+
+ /**
+ * Create a request to move a branch from one location into another.
+ *
+ * @param from the location of the top node in the existing branch that is to be
moved
+ * @param into the location of the existing node into which the branch should be
moved
+ * @param workspaceName the name of the workspace
+ * @param conflictBehavior the expected behavior if an equivalently-named child
already exists at the <code>into</code>
+ * location
+ * @return the request; never null
+ * @throws IllegalArgumentException if any of the parameters are null
+ */
+ public MoveBranchRequest moveBranch( Location from,
+ Location into,
+ String workspaceName,
+ NodeConflictBehavior conflictBehavior ) {
+ if (conflictBehavior == null) conflictBehavior =
MoveBranchRequest.DEFAULT_CONFLICT_BEHAVIOR;
+ return process(new MoveBranchRequest(from, into, workspaceName,
conflictBehavior));
+ }
+
+ /**
+ * Add a request to delete a branch.
+ *
+ * @param at the location of the top node in the existing branch that is to be
deleted
+ * @param workspaceName the name of the workspace containing the parent
+ * @return the request; never null
+ * @throws IllegalArgumentException if the location or workspace name is null
+ */
+ public DeleteBranchRequest deleteBranch( Location at,
+ String workspaceName ) {
+ return process(new DeleteBranchRequest(at, workspaceName));
+ }
+}
Property changes on:
trunk/dna-graph/src/main/java/org/jboss/dna/graph/request/RequestBuilder.java
___________________________________________________________________
Name: svn:mime-type
+ text/plain
Added: 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
(rev 0)
+++
trunk/dna-graph/src/main/java/org/jboss/dna/graph/request/SetPropertyRequest.java 2009-04-07
21:23:28 UTC (rev 809)
@@ -0,0 +1,178 @@
+/*
+ * 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.request;
+
+import org.jboss.dna.common.util.CheckArg;
+import org.jboss.dna.graph.GraphI18n;
+import org.jboss.dna.graph.Location;
+import org.jboss.dna.graph.property.Path;
+import org.jboss.dna.graph.property.Property;
+
+/**
+ * Instruction to set a particular property on the node at the specified location. This
request <i>never</i> removes the node,
+ * even if the property is empty.
+ *
+ * @author Randall Hauch
+ */
+public class SetPropertyRequest extends Request implements ChangeRequest {
+
+ private static final long serialVersionUID = 1L;
+
+ private final Location on;
+ private final String workspaceName;
+ private final Property property;
+ private Location actualLocation;
+
+ /**
+ * Create a request to set the property on the node at the supplied location.
+ *
+ * @param on the location of the node to be read
+ * @param workspaceName the name of the workspace containing the node
+ * @param property the new property on the node
+ * @throws IllegalArgumentException if the location, workspace name, or property is
null
+ */
+ public SetPropertyRequest( Location on,
+ String workspaceName,
+ Property property ) {
+ CheckArg.isNotNull(on, "on");
+ CheckArg.isNotNull(property, "property");
+ CheckArg.isNotNull(workspaceName, "workspaceName");
+ this.workspaceName = workspaceName;
+ this.on = on;
+ this.property = property;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.jboss.dna.graph.request.Request#isReadOnly()
+ */
+ @Override
+ public boolean isReadOnly() {
+ return false;
+ }
+
+ /**
+ * Get the location defining the node that is to be updated.
+ *
+ * @return the location of the node; never null
+ */
+ public Location on() {
+ return on;
+ }
+
+ /**
+ * Get the name of the workspace in which the node exists.
+ *
+ * @return the name of the workspace; never null
+ */
+ public String inWorkspace() {
+ return workspaceName;
+ }
+
+ /**
+ * Get the property that is being set.
+ *
+ * @return the new property; never null
+ */
+ public Property property() {
+ return property;
+ }
+
+ /**
+ * Sets the actual and complete location of the node being updated. This method must
be called when processing the request,
+ * and the actual location must have a {@link Location#getPath() path}.
+ *
+ * @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.
+ */
+ public void setActualLocationOfNode( Location actual ) {
+ if (!on.isSame(actual)) { // not same if actual is null
+ throw new
IllegalArgumentException(GraphI18n.actualLocationIsNotSameAsInputLocation.text(actual,
on));
+ }
+ assert actual != null;
+ if (!actual.hasPath()) {
+ throw new
IllegalArgumentException(GraphI18n.actualLocationMustHavePath.text(actual));
+ }
+ this.actualLocation = actual;
+ }
+
+ /**
+ * Get the actual location of the node that was updated.
+ *
+ * @return the actual location, or null if the actual location was not set
+ */
+ public Location getActualLocationOfNode() {
+ return actualLocation;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.jboss.dna.graph.request.ChangeRequest#changes(java.lang.String,
org.jboss.dna.graph.property.Path)
+ */
+ public boolean changes( String workspace,
+ Path path ) {
+ return this.workspaceName.equals(workspace) && on.hasPath() &&
on.getPath().isAtOrBelow(path);
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see java.lang.Object#equals(java.lang.Object)
+ */
+ @Override
+ public boolean equals( Object obj ) {
+ if (obj == this) return true;
+ if (this.getClass().isInstance(obj)) {
+ SetPropertyRequest that = (SetPropertyRequest)obj;
+ if (!this.on().equals(that.on())) return false;
+ if (!this.property().equals(that.property())) return false;
+ if (!this.inWorkspace().equals(that.inWorkspace())) return false;
+ return true;
+ }
+ return false;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.jboss.dna.graph.request.ChangeRequest#changedLocation()
+ */
+ public Location changedLocation() {
+ return on;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see java.lang.Object#toString()
+ */
+ @Override
+ public String toString() {
+ return "set property " + property().getName() + " on " + on()
+ " in the \"" + workspaceName + "\" workspace to "
+ + property().getValuesAsArray();
+ }
+}
Property changes on:
trunk/dna-graph/src/main/java/org/jboss/dna/graph/request/SetPropertyRequest.java
___________________________________________________________________
Name: svn:mime-type
+ text/plain
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-04-06
15:55:23 UTC (rev 808)
+++
trunk/dna-graph/src/main/java/org/jboss/dna/graph/request/UpdatePropertiesRequest.java 2009-04-07
21:23:28 UTC (rev 809)
@@ -23,14 +23,8 @@
*/
package org.jboss.dna.graph.request;
-import java.util.Arrays;
-import java.util.Collection;
import java.util.Collections;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.Set;
+import java.util.Map;
import org.jboss.dna.common.util.CheckArg;
import org.jboss.dna.graph.GraphI18n;
import org.jboss.dna.graph.Location;
@@ -39,17 +33,32 @@
import org.jboss.dna.graph.property.Property;
/**
- * Instruction to update the properties on the node at the specified location. Any
property with no values will be removed.
+ * Instruction to update the properties on the node at the specified location.
+ * <p>
+ * This request is capable of specifying that certain properties are to have new values
and that other properties are to be
+ * removed. The request has a single map of properties keyed by their name. If a property
is to be set with new values, the map
+ * will contain an entry with the property keyed by its name. However, if a property is
to be removed, the entry will contain the
+ * property name for the key but will have a null entry value.
+ * </p>
+ * <p>
+ * The use of the map also ensures that a single property appears only once in the
request (it either has new values or it is to
+ * be removed).
+ * </p>
+ * <p>
+ * Note that the number of values in a property (e.g., {@link Property#size()}, {@link
Property#isEmpty()},
+ * {@link Property#isSingle()}, and {@link Property#isMultiple()}) has no influence on
whether the property should be removed. It
+ * is possible for a property to have no values.
+ * </p>
*
* @author Randall Hauch
*/
-public class UpdatePropertiesRequest extends Request implements Iterable<Property>,
ChangeRequest {
+public class UpdatePropertiesRequest extends Request implements ChangeRequest {
private static final long serialVersionUID = 1L;
private final Location on;
private final String workspaceName;
- private final List<Property> properties;
+ private final Map<Name, Property> properties;
private Location actualLocation;
/**
@@ -57,90 +66,21 @@
*
* @param on the location of the node to be read
* @param workspaceName the name of the workspace containing the node
- * @param properties the new properties on the node
+ * @param properties the map of properties (keyed by their name), which is reused
without copying
* @throws IllegalArgumentException if the location or workspace name is null or if
there are no properties to update
*/
public UpdatePropertiesRequest( Location on,
String workspaceName,
- Property... properties ) {
+ Map<Name, Property> properties ) {
CheckArg.isNotNull(on, "on");
CheckArg.isNotEmpty(properties, "properties");
CheckArg.isNotNull(workspaceName, "workspaceName");
this.workspaceName = workspaceName;
this.on = on;
- this.properties = Collections.unmodifiableList(Arrays.asList(properties));
+ this.properties = Collections.unmodifiableMap(properties);
}
/**
- * Create a request to update the properties on the node at the supplied location.
- *
- * @param on the location of the node to be read
- * @param workspaceName the name of the workspace containing the node
- * @param properties the new properties on the node
- * @throws IllegalArgumentException if the location or workspace name is null or if
there are no properties to update
- */
- public UpdatePropertiesRequest( Location on,
- String workspaceName,
- Iterable<Property> properties ) {
- CheckArg.isNotNull(on, "on");
- CheckArg.isNotNull(properties, "properties");
- CheckArg.isNotNull(workspaceName, "workspaceName");
- this.workspaceName = workspaceName;
- this.on = on;
- List<Property> props = new LinkedList<Property>();
- for (Property property : properties) {
- if (property != null) props.add(property);
- }
- this.properties = Collections.unmodifiableList(props);
- CheckArg.isNotEmpty(this.properties, "properties");
- }
-
- /**
- * Create a request to update the properties on the node at the supplied location.
- *
- * @param on the location of the node to be read
- * @param workspaceName the name of the workspace containing the node
- * @param properties the new properties on the node
- * @throws IllegalArgumentException if the location or workspace name is null or if
there are no properties to update
- */
- public UpdatePropertiesRequest( Location on,
- String workspaceName,
- Iterator<Property> properties ) {
- CheckArg.isNotNull(on, "on");
- CheckArg.isNotNull(properties, "properties");
- CheckArg.isNotNull(workspaceName, "workspaceName");
- this.workspaceName = workspaceName;
- this.on = on;
- List<Property> props = new LinkedList<Property>();
- while (properties.hasNext()) {
- Property property = properties.next();
- if (property != null) props.add(property);
- }
- this.properties = Collections.unmodifiableList(props);
- CheckArg.isNotEmpty(this.properties, "properties");
- }
-
- /**
- * Create a request to update the properties on the node at the supplied location.
- *
- * @param on the location of the node to be read
- * @param workspaceName the name of the workspace containing the node
- * @param properties the new properties on the node
- * @throws IllegalArgumentException if the location or workspace name is null or if
there are no properties to update
- */
- private UpdatePropertiesRequest( Location on,
- String workspaceName,
- List<Property> properties ) {
- CheckArg.isNotNull(on, "on");
- CheckArg.isNotNull(properties, "properties");
- CheckArg.isNotNull(workspaceName, "workspaceName");
- this.workspaceName = workspaceName;
- this.on = on;
- this.properties = properties;
- CheckArg.isNotEmpty(this.properties, "properties");
- }
-
- /**
* {@inheritDoc}
*
* @see org.jboss.dna.graph.request.Request#isReadOnly()
@@ -169,20 +109,12 @@
}
/**
- * {@inheritDoc}
+ * Get the map of properties for the node, keyed by property name. Any property to be
removed will have a map entry with a
+ * null value.
*
- * @see java.lang.Iterable#iterator()
+ * @return the properties being updated; never null and never empty
*/
- public Iterator<Property> iterator() {
- return this.properties.iterator();
- }
-
- /**
- * Get the properties for the node.
- *
- * @return the collection of properties; never null and never empty
- */
- public Collection<Property> properties() {
+ public Map<Name, Property> properties() {
return properties;
}
@@ -261,39 +193,4 @@
return "update properties on " + on() + " in the \"" +
workspaceName + "\" workspace to " + properties();
}
- /**
- * Merge these updates with those in the supplied request, with the supplied changes
overwriting any similar changes on this
- * node.
- *
- * @param other the other updates that are to be merged with these
- * @return the merged request
- */
- public UpdatePropertiesRequest mergeWith( UpdatePropertiesRequest other ) {
- if (other == null) return this;
- if (other.properties().size() == 1) {
- Property newProp = other.properties.get(0);
- List<Property> newProps = new LinkedList<Property>();
- for (Property prop : this.properties) {
- if (!prop.getName().equals(newProp.getName())) {
- newProps.add(prop);
- }
- }
- newProps.add(newProp);
- return new UpdatePropertiesRequest(on, workspaceName,
Collections.unmodifiableList(newProps));
- }
- Set<Name> otherNames = new HashSet<Name>();
- for (Property prop : other.properties()) {
- otherNames.add(prop.getName());
- }
- List<Property> newProps = new LinkedList<Property>();
- for (Property prop : this.properties) {
- if (!otherNames.contains(prop.getName())) {
- newProps.add(prop);
- }
- }
- newProps.addAll(other.properties);
- return new UpdatePropertiesRequest(on, workspaceName,
Collections.unmodifiableList(newProps));
-
- }
-
}
Modified: trunk/dna-graph/src/main/java/org/jboss/dna/graph/request/package-info.java
===================================================================
--- trunk/dna-graph/src/main/java/org/jboss/dna/graph/request/package-info.java 2009-04-06
15:55:23 UTC (rev 808)
+++ trunk/dna-graph/src/main/java/org/jboss/dna/graph/request/package-info.java 2009-04-07
21:23:28 UTC (rev 809)
@@ -148,8 +148,10 @@
* <li>{@link UpdatePropertiesRequest} - A request to update one or more
properties on a node. Any property
* with no values will be removed, while properties with one or more values will be set
(replace any existing property
* with the same name, if they exist). </li>
- * <li>{@link RemovePropertiesRequest} - A request to remove one or more
properties on a node. No error is reported
+ * <li>{@link RemovePropertyRequest} - A request to remove one property from a
node. No error is reported
* if the node does not contain a property that is to be removed.</li>
+ * <li>{@link SetPropertyRequest} - A request to set one property on a node. No
error is reported
+ * if the node does not already have the property, since the property is just
created.</li>
* <li>{@link DeleteBranchRequest} - A request to delete a node and all nodes
located below it.</li>
* <li>{@link CompositeRequest} - A request that acts as a container for multiple
other requests (of various kinds),
* allowing you to batch together multiple for processing. Use the one of the {@link
CompositeRequest#with(Request...) CompositeRequest.with(...)}
Modified:
trunk/dna-graph/src/main/java/org/jboss/dna/graph/request/processor/LoggingRequestProcessor.java
===================================================================
---
trunk/dna-graph/src/main/java/org/jboss/dna/graph/request/processor/LoggingRequestProcessor.java 2009-04-06
15:55:23 UTC (rev 808)
+++
trunk/dna-graph/src/main/java/org/jboss/dna/graph/request/processor/LoggingRequestProcessor.java 2009-04-07
21:23:28 UTC (rev 809)
@@ -42,10 +42,12 @@
import org.jboss.dna.graph.request.ReadNextBlockOfChildrenRequest;
import org.jboss.dna.graph.request.ReadNodeRequest;
import org.jboss.dna.graph.request.ReadPropertyRequest;
-import org.jboss.dna.graph.request.RemovePropertiesRequest;
+import org.jboss.dna.graph.request.RemovePropertyRequest;
import org.jboss.dna.graph.request.RenameNodeRequest;
import org.jboss.dna.graph.request.Request;
+import org.jboss.dna.graph.request.SetPropertyRequest;
import org.jboss.dna.graph.request.UpdatePropertiesRequest;
+import org.jboss.dna.graph.request.VerifyNodeExistsRequest;
import org.jboss.dna.graph.request.VerifyWorkspaceRequest;
/**
@@ -185,6 +187,18 @@
/**
* {@inheritDoc}
*
+ * @see
org.jboss.dna.graph.request.processor.RequestProcessor#process(org.jboss.dna.graph.request.VerifyNodeExistsRequest)
+ */
+ @Override
+ public void process( VerifyNodeExistsRequest request ) {
+ logger.log(level, GraphI18n.executingRequest, request);
+ delegate.process(request);
+ logger.log(level, GraphI18n.executedRequest, request);
+ }
+
+ /**
+ * {@inheritDoc}
+ *
* @see
org.jboss.dna.graph.request.processor.RequestProcessor#process(org.jboss.dna.graph.request.ReadAllChildrenRequest)
*/
@Override
@@ -293,10 +307,10 @@
/**
* {@inheritDoc}
*
- * @see
org.jboss.dna.graph.request.processor.RequestProcessor#process(org.jboss.dna.graph.request.RemovePropertiesRequest)
+ * @see
org.jboss.dna.graph.request.processor.RequestProcessor#process(org.jboss.dna.graph.request.SetPropertyRequest)
*/
@Override
- public void process( RemovePropertiesRequest request ) {
+ public void process( SetPropertyRequest request ) {
logger.log(level, GraphI18n.executingRequest, request);
delegate.process(request);
logger.log(level, GraphI18n.executedRequest, request);
@@ -305,6 +319,18 @@
/**
* {@inheritDoc}
*
+ * @see
org.jboss.dna.graph.request.processor.RequestProcessor#process(org.jboss.dna.graph.request.RemovePropertyRequest)
+ */
+ @Override
+ public void process( RemovePropertyRequest request ) {
+ logger.log(level, GraphI18n.executingRequest, request);
+ delegate.process(request);
+ logger.log(level, GraphI18n.executedRequest, request);
+ }
+
+ /**
+ * {@inheritDoc}
+ *
* @see
org.jboss.dna.graph.request.processor.RequestProcessor#process(org.jboss.dna.graph.request.RenameNodeRequest)
*/
@Override
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-04-06
15:55:23 UTC (rev 808)
+++
trunk/dna-graph/src/main/java/org/jboss/dna/graph/request/processor/RequestProcessor.java 2009-04-07
21:23:28 UTC (rev 809)
@@ -23,10 +23,10 @@
*/
package org.jboss.dna.graph.request.processor;
-import java.util.ArrayList;
-import java.util.Collection;
+import java.util.Collections;
import java.util.LinkedList;
import java.util.List;
+import java.util.Map;
import java.util.Queue;
import net.jcip.annotations.Immutable;
import org.jboss.dna.common.util.CheckArg;
@@ -40,7 +40,6 @@
import org.jboss.dna.graph.property.Path;
import org.jboss.dna.graph.property.Property;
import org.jboss.dna.graph.property.ReferentialIntegrityException;
-import org.jboss.dna.graph.property.basic.BasicEmptyProperty;
import org.jboss.dna.graph.request.CacheableRequest;
import org.jboss.dna.graph.request.CloneWorkspaceRequest;
import org.jboss.dna.graph.request.CompositeRequest;
@@ -59,9 +58,10 @@
import org.jboss.dna.graph.request.ReadNextBlockOfChildrenRequest;
import org.jboss.dna.graph.request.ReadNodeRequest;
import org.jboss.dna.graph.request.ReadPropertyRequest;
-import org.jboss.dna.graph.request.RemovePropertiesRequest;
+import org.jboss.dna.graph.request.RemovePropertyRequest;
import org.jboss.dna.graph.request.RenameNodeRequest;
import org.jboss.dna.graph.request.Request;
+import org.jboss.dna.graph.request.SetPropertyRequest;
import org.jboss.dna.graph.request.UnsupportedRequestException;
import org.jboss.dna.graph.request.UpdatePropertiesRequest;
import org.jboss.dna.graph.request.VerifyNodeExistsRequest;
@@ -190,8 +190,10 @@
process((ReadAllPropertiesRequest)request);
} else if (request instanceof ReadPropertyRequest) {
process((ReadPropertyRequest)request);
- } else if (request instanceof RemovePropertiesRequest) {
- process((RemovePropertiesRequest)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) {
@@ -608,23 +610,18 @@
}
/**
- * Process a request to remove the specified properties from a node.
+ * Process a request to remove the specified property from a node.
* <p>
* This method does nothing if the request is null. Unless overridden, this method
converts this request into a
* {@link UpdatePropertiesRequest}.
* </p>
*
- * @param request the request to remove the properties with certain names
+ * @param request the request to remove the property
*/
- public void process( RemovePropertiesRequest request ) {
+ public void process( RemovePropertyRequest request ) {
if (request == null) return;
- Collection<Name> names = request.propertyNames();
- if (names.isEmpty()) return;
- List<Property> emptyProperties = new
ArrayList<Property>(names.size());
- for (Name propertyName : names) {
- emptyProperties.add(new BasicEmptyProperty(propertyName));
- }
- UpdatePropertiesRequest update = new UpdatePropertiesRequest(request.from(),
request.inWorkspace(), emptyProperties);
+ Map<Name, Property> properties =
Collections.singletonMap(request.propertyName(), null);
+ UpdatePropertiesRequest update = new UpdatePropertiesRequest(request.from(),
request.inWorkspace(), properties);
process(update);
if (update.hasError()) {
request.setError(update.getError());
@@ -634,6 +631,29 @@
}
/**
+ * Process a request to set the specified property on a node.
+ * <p>
+ * This method does nothing if the request is null. Unless overridden, this method
converts this request into a
+ * {@link UpdatePropertiesRequest}.
+ * </p>
+ *
+ * @param request the request to set the property
+ */
+ public void process( SetPropertyRequest request ) {
+ if (request == null) return;
+ Property property = request.property();
+ Map<Name, Property> properties =
Collections.singletonMap(property.getName(), property);
+ UpdatePropertiesRequest update = new UpdatePropertiesRequest(request.on(),
request.inWorkspace(), properties);
+ process(update);
+ if (update.hasError()) {
+ request.setError(update.getError());
+ } else {
+ // Set the actual location ...
+ request.setActualLocationOfNode(update.getActualLocationOfNode());
+ }
+ }
+
+ /**
* Process a request to remove the specified properties from a node.
* <p>
* This method does nothing if the request is null.
Modified: trunk/dna-graph/src/test/java/org/jboss/dna/graph/GraphTest.java
===================================================================
--- trunk/dna-graph/src/test/java/org/jboss/dna/graph/GraphTest.java 2009-04-06 15:55:23
UTC (rev 808)
+++ trunk/dna-graph/src/test/java/org/jboss/dna/graph/GraphTest.java 2009-04-07 21:23:28
UTC (rev 809)
@@ -70,6 +70,7 @@
import org.jboss.dna.graph.request.ReadNodeRequest;
import org.jboss.dna.graph.request.ReadPropertyRequest;
import org.jboss.dna.graph.request.Request;
+import org.jboss.dna.graph.request.SetPropertyRequest;
import org.jboss.dna.graph.request.UpdatePropertiesRequest;
import org.jboss.dna.graph.request.VerifyNodeExistsRequest;
import org.jboss.dna.graph.request.VerifyWorkspaceRequest;
@@ -319,9 +320,18 @@
assertThat(request, is(instanceOf(UpdatePropertiesRequest.class)));
UpdatePropertiesRequest read = (UpdatePropertiesRequest)request;
assertThat(read.on(), is(on));
- assertThat(read.properties(), hasItems(properties));
+ assertThat(read.properties().values(), hasItems(properties));
}
+ protected void assertNextRequestSetProperty( Location on,
+ Property property ) {
+ Request request = executedRequests.poll();
+ assertThat(request, is(instanceOf(SetPropertyRequest.class)));
+ SetPropertyRequest read = (SetPropertyRequest)request;
+ assertThat(read.on(), is(on));
+ assertThat(read.property(), is(property));
+ }
+
//
----------------------------------------------------------------------------------------------------------------
// Immediate requests
//
----------------------------------------------------------------------------------------------------------------
@@ -623,53 +633,80 @@
}
@Test
- public void shouldSetPropertiesWithEitherOnOrToMethodsCalledFirst() {
+ public void shouldSetPropertyWithEitherOnOrToMethodsCalledFirst() {
graph.set("propName").on(validPath).to(3.0f);
- assertNextRequestUpdateProperties(Location.create(validPath),
createProperty("propName", 3.0f));
+ assertNextRequestSetProperty(Location.create(validPath),
createProperty("propName", 3.0f));
graph.set("propName").to(3.0f).on(validPath);
- assertNextRequestUpdateProperties(Location.create(validPath),
createProperty("propName", 3.0f));
+ assertNextRequestSetProperty(Location.create(validPath),
createProperty("propName", 3.0f));
}
@Test
public void shouldSetPropertyValueToPrimitiveTypes() {
graph.set("propName").on(validPath).to(3.0F);
- assertNextRequestUpdateProperties(Location.create(validPath),
createProperty("propName", new Float(3.0f)));
+ assertNextRequestSetProperty(Location.create(validPath),
createProperty("propName", new Float(3.0f)));
graph.set("propName").on(validPath).to(1.0D);
- assertNextRequestUpdateProperties(Location.create(validPath),
createProperty("propName", new Double(1.0)));
+ assertNextRequestSetProperty(Location.create(validPath),
createProperty("propName", new Double(1.0)));
graph.set("propName").on(validPath).to(false);
- assertNextRequestUpdateProperties(Location.create(validPath),
createProperty("propName", Boolean.FALSE));
+ assertNextRequestSetProperty(Location.create(validPath),
createProperty("propName", Boolean.FALSE));
graph.set("propName").on(validPath).to(3);
- assertNextRequestUpdateProperties(Location.create(validPath),
createProperty("propName", new Integer(3)));
+ assertNextRequestSetProperty(Location.create(validPath),
createProperty("propName", new Integer(3)));
graph.set("propName").on(validPath).to(5L);
- assertNextRequestUpdateProperties(Location.create(validPath),
createProperty("propName", new Long(5)));
+ assertNextRequestSetProperty(Location.create(validPath),
createProperty("propName", new Long(5)));
graph.set("propName").on(validPath).to(validPath);
- assertNextRequestUpdateProperties(Location.create(validPath),
createProperty("propName", validPath));
+ assertNextRequestSetProperty(Location.create(validPath),
createProperty("propName", validPath));
graph.set("propName").on(validPath).to(validPath.getLastSegment().getName());
- assertNextRequestUpdateProperties(Location.create(validPath),
createProperty("propName", validPath.getLastSegment()
-
.getName()));
+ assertNextRequestSetProperty(Location.create(validPath),
createProperty("propName", validPath.getLastSegment().getName()));
Date now = new Date();
graph.set("propName").on(validPath).to(now);
- assertNextRequestUpdateProperties(Location.create(validPath),
createProperty("propName", now));
+ assertNextRequestSetProperty(Location.create(validPath),
createProperty("propName", now));
DateTime dtNow = context.getValueFactories().getDateFactory().create(now);
graph.set("propName").on(validPath).to(dtNow);
- assertNextRequestUpdateProperties(Location.create(validPath),
createProperty("propName", dtNow));
+ assertNextRequestSetProperty(Location.create(validPath),
createProperty("propName", dtNow));
Calendar calNow = Calendar.getInstance();
calNow.setTime(now);
graph.set("propName").on(validPath).to(calNow);
- assertNextRequestUpdateProperties(Location.create(validPath),
createProperty("propName", dtNow));
+ assertNextRequestSetProperty(Location.create(validPath),
createProperty("propName", dtNow));
+ }
+ @Test
+ public void shouldSetMultiplePropertiesAtOnce() {
+ Property p1 = createProperty("propName1", new Float(3.0f));
+ Property p2 = createProperty("propName2", new Double(1.0));
+ Property p3 = createProperty("propName3", "String value");
+ graph.batch().set(p1, p2, p3).on(validPath).execute();
+ assertNextRequestUpdateProperties(Location.create(validPath), p1, p2, p3);
}
@Test
+ public void shouldCombineAdjacentSetPropertyCalls() {
+ Property p1 = createProperty("propName1", new Float(3.0f));
+ Property p2 = createProperty("propName2", new Double(1.0));
+ Property p3 = createProperty("propName3", "String value");
+
graph.batch().set(p1).on(validPath).and().set(p2).on(validPath).and().set(p3).on(validPath).execute();
+ assertNextRequestUpdateProperties(Location.create(validPath), p1, p2, p3);
+ }
+
+ @Test
+ public void shouldNotCombineNonAdjacentSetPropertyCalls() {
+ Property p1 = createProperty("propName1", new Float(3.0f));
+ Property p2 = createProperty("propName2", new Double(1.0));
+ Property p3 = createProperty("propName3", "String value");
+
graph.batch().set(p1).on(validPath).and().set(p2).on(validPath).and().set(p3).on(validUuid).execute();
+ extractRequestsFromComposite();
+ assertNextRequestUpdateProperties(Location.create(validPath), p1, p2);
+ assertNextRequestSetProperty(Location.create(validUuid), p3);
+ }
+
+ @Test
public void shouldReadNode() {
Location child1 = Location.create(createPath(validPath, "x"));
Location child2 = Location.create(createPath(validPath, "y"));
Modified:
trunk/dna-graph/src/test/java/org/jboss/dna/graph/connector/test/AbstractConnectorTest.java
===================================================================
---
trunk/dna-graph/src/test/java/org/jboss/dna/graph/connector/test/AbstractConnectorTest.java 2009-04-06
15:55:23 UTC (rev 808)
+++
trunk/dna-graph/src/test/java/org/jboss/dna/graph/connector/test/AbstractConnectorTest.java 2009-04-07
21:23:28 UTC (rev 809)
@@ -494,7 +494,7 @@
if (stopwatch != null) {
stopwatch.stop();
if (output != null) {
- output.println(" " +
getTotalAndAverageDuration(stopwatch));
+ output.println(" " + getTotalAndAverageDuration(stopwatch,
totalNumberCreated));
}
// Perform second batch ...
@@ -504,20 +504,21 @@
sw.start();
batch.execute();
sw.stop();
- System.out.println(" final " +
getTotalAndAverageDuration(stopwatch));
+ System.out.println(" final " + getTotalAndAverageDuration(sw,
totalNumberCreated));
assertThat(totalNumberCreated, is(totalNumber +
calculateTotalNumberOfNodesInTree(2, 2, false)));
}
return (int)totalNumberCreated;
}
- protected String getTotalAndAverageDuration( Stopwatch stopwatch ) {
- long totalDurationInMicroseconds =
TimeUnit.NANOSECONDS.toMicros(stopwatch.getTotalDuration().longValue());
- long totalNumber = stopwatch.getCount();
- long avgDuration = totalDurationInMicroseconds / totalNumber / 1000L;
+ protected String getTotalAndAverageDuration( Stopwatch stopwatch,
+ long numNodes ) {
+ long totalDurationInMilliseconds =
TimeUnit.NANOSECONDS.toMillis(stopwatch.getTotalDuration().longValue());
+ long avgDuration = totalDurationInMilliseconds / numNodes;
String units = " millisecond(s)";
- if (avgDuration == 0L) {
- avgDuration = totalDurationInMicroseconds / totalNumber;
+ if (avgDuration < 1L) {
+ long totalDurationInMicroseconds =
TimeUnit.NANOSECONDS.toMicros(stopwatch.getTotalDuration().longValue());
+ avgDuration = totalDurationInMicroseconds / numNodes;
units = " microsecond(s)";
}
return "total = " + stopwatch.getTotalDuration() + "; avg = "
+ avgDuration + units;
Deleted:
trunk/dna-graph/src/test/java/org/jboss/dna/graph/request/RemovePropertiesRequestTest.java
===================================================================
---
trunk/dna-graph/src/test/java/org/jboss/dna/graph/request/RemovePropertiesRequestTest.java 2009-04-06
15:55:23 UTC (rev 808)
+++
trunk/dna-graph/src/test/java/org/jboss/dna/graph/request/RemovePropertiesRequestTest.java 2009-04-07
21:23:28 UTC (rev 809)
@@ -1,190 +0,0 @@
-/*
- * 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.request;
-
-import static org.hamcrest.core.Is.is;
-import static org.hamcrest.core.IsNull.nullValue;
-import static org.hamcrest.core.IsSame.sameInstance;
-import static org.junit.Assert.assertThat;
-import static org.junit.matchers.JUnitMatchers.hasItems;
-import java.util.ArrayList;
-import java.util.Iterator;
-import java.util.List;
-import org.jboss.dna.graph.property.Name;
-import org.junit.Before;
-import org.junit.Test;
-
-/**
- * @author Randall Hauch
- */
-public class RemovePropertiesRequestTest extends AbstractRequestTest {
-
- private RemovePropertiesRequest request;
- private Name validPropertyName1;
- private Name validPropertyName2;
- private Name validPropertyName3;
-
- @Override
- @Before
- public void beforeEach() {
- super.beforeEach();
- validPropertyName1 = createName("foo1");
- validPropertyName2 = createName("foo2");
- validPropertyName3 = createName("foo3");
- }
-
- @Override
- protected Request createRequest() {
- return new RemovePropertiesRequest(validPathLocation1, workspace1,
validPropertyName1);
- }
-
- @Test( expected = IllegalArgumentException.class )
- public void shouldNotAllowCreatingRequestWithNullFromLocation() {
- new RemovePropertiesRequest(null, workspace1, validPropertyName1);
- }
-
- @Test( expected = IllegalArgumentException.class )
- public void shouldNotAllowCreatingRequestWithNullFromWorkspaceName() {
- new RemovePropertiesRequest(validPathLocation1, null, validPropertyName1);
- }
-
- @Test( expected = IllegalArgumentException.class )
- public void shouldNotAllowCreatingRequestWithNullPropertyName() {
- new RemovePropertiesRequest(validPathLocation, workspace1, (Name[])null);
- }
-
- @Test( expected = IllegalArgumentException.class )
- public void shouldNotAllowCreatingRequestWithEmptyPropertyNameArray() {
- new RemovePropertiesRequest(validPathLocation, workspace1, new Name[] {});
- }
-
- @Test( expected = IllegalArgumentException.class )
- public void shouldNotAllowCreatingRequestWithNullPropertyNameIterator() {
- new RemovePropertiesRequest(validPathLocation, workspace1,
(Iterator<Name>)null);
- }
-
- @Test( expected = IllegalArgumentException.class )
- public void shouldNotAllowCreatingRequestWithEmptyPropertyNameIterator() {
- new RemovePropertiesRequest(validPathLocation, workspace1, new
ArrayList<Name>().iterator());
- }
-
- @Test( expected = IllegalArgumentException.class )
- public void shouldNotAllowCreatingRequestWithNullPropertyNameIterable() {
- new RemovePropertiesRequest(validPathLocation, workspace1,
(Iterable<Name>)null);
- }
-
- @Test( expected = IllegalArgumentException.class )
- public void shouldNotAllowCreatingRequestWithEmptyPropertyNameIterable() {
- new RemovePropertiesRequest(validPathLocation, workspace1, new
ArrayList<Name>());
- }
-
- @Test
- public void shouldCreateValidRequestWithValidLocationAndValidPropertyName() {
- request = new RemovePropertiesRequest(validPathLocation1, workspace1,
validPropertyName1);
- assertThat(request.from(), is(sameInstance(validPathLocation1)));
- assertThat(request.inWorkspace(), is(sameInstance(workspace1)));
- assertThat(request.hasError(), is(false));
- assertThat(request.getError(), is(nullValue()));
- assertThat(request.propertyNames(), hasItems(validPropertyName1));
- }
-
- @Test
- public void shouldCreateValidRequestWithValidLocationAndValidPropertyNames() {
- request = new RemovePropertiesRequest(validPathLocation1, workspace1,
validPropertyName1, validPropertyName2);
- assertThat(request.from(), is(sameInstance(validPathLocation1)));
- assertThat(request.hasError(), is(false));
- assertThat(request.getError(), is(nullValue()));
- assertThat(request.propertyNames(), hasItems(validPropertyName1,
validPropertyName2));
- }
-
- @Test
- public void
shouldCreateValidRequestWithValidLocationAndIteratorOverValidPropertyName() {
- List<Name> names = new ArrayList<Name>();
- names.add(validPropertyName1);
- request = new RemovePropertiesRequest(validPathLocation1, workspace1, names);
- assertThat(request.from(), is(sameInstance(validPathLocation1)));
- assertThat(request.hasError(), is(false));
- assertThat(request.getError(), is(nullValue()));
- assertThat(request.propertyNames(), hasItems(validPropertyName1));
- }
-
- @Test
- public void
shouldCreateValidRequestWithValidLocationAndIteratorOverValidPropertyNames() {
- List<Name> names = new ArrayList<Name>();
- names.add(validPropertyName1);
- names.add(validPropertyName2);
- names.add(validPropertyName3);
- request = new RemovePropertiesRequest(validPathLocation1, workspace1,
names.iterator());
- assertThat(request.from(), is(sameInstance(validPathLocation1)));
- assertThat(request.hasError(), is(false));
- assertThat(request.getError(), is(nullValue()));
- assertThat(request.propertyNames(), hasItems(validPropertyName1,
validPropertyName2, validPropertyName3));
- }
-
- @Test
- public void
shouldCreateValidRequestWithValidLocationAndIterableWithValidPropertyNames() {
- List<Name> names = new ArrayList<Name>();
- names.add(validPropertyName1);
- names.add(validPropertyName2);
- names.add(validPropertyName3);
- request = new RemovePropertiesRequest(validPathLocation1, workspace1, names);
- assertThat(request.from(), is(sameInstance(validPathLocation1)));
- assertThat(request.hasError(), is(false));
- assertThat(request.getError(), is(nullValue()));
- assertThat(request.propertyNames(), hasItems(validPropertyName1,
validPropertyName2, validPropertyName3));
- }
-
- @Test
- public void shouldConsiderEqualTwoRequestsWithSameLocationsAndSamePropertyNames() {
- request = new RemovePropertiesRequest(validPathLocation1, workspace1,
validPropertyName1, validPropertyName2);
- RemovePropertiesRequest request2 = new
RemovePropertiesRequest(validPathLocation1, workspace1, validPropertyName1,
-
validPropertyName2);
- assertThat(request, is(request2));
- }
-
- @Test
- public void shouldConsiderNotEqualTwoRequestsWithDifferentLocations() {
- request = new RemovePropertiesRequest(validPathLocation1, workspace1,
validPropertyName1, validPropertyName2);
- RemovePropertiesRequest request2 = new
RemovePropertiesRequest(validPathLocation2, workspace1, validPropertyName1,
-
validPropertyName2);
- assertThat(request.equals(request2), is(false));
- }
-
- @Test
- public void shouldConsiderNotEqualTwoRequestsWithDifferentWorkspaceNames() {
- request = new RemovePropertiesRequest(validPathLocation1, workspace1,
validPropertyName1, validPropertyName2);
- RemovePropertiesRequest request2 = new
RemovePropertiesRequest(validPathLocation1, workspace2, validPropertyName1,
-
validPropertyName2);
- assertThat(request.equals(request2), is(false));
- }
-
- @Test
- public void
shouldConsiderNotEqualTwoRequestsWithSameLocationButDifferentPropertyNames() {
- request = new RemovePropertiesRequest(validPathLocation1, workspace1,
validPropertyName1, validPropertyName2);
- RemovePropertiesRequest request2 = new
RemovePropertiesRequest(validPathLocation2, workspace1, validPropertyName2,
-
validPropertyName3);
- assertThat(request.equals(request2), is(false));
- }
-
-}
Modified:
trunk/dna-graph/src/test/java/org/jboss/dna/graph/request/UpdatePropertiesRequestTest.java
===================================================================
---
trunk/dna-graph/src/test/java/org/jboss/dna/graph/request/UpdatePropertiesRequestTest.java 2009-04-06
15:55:23 UTC (rev 808)
+++
trunk/dna-graph/src/test/java/org/jboss/dna/graph/request/UpdatePropertiesRequestTest.java 2009-04-07
21:23:28 UTC (rev 809)
@@ -28,9 +28,10 @@
import static org.hamcrest.core.IsSame.sameInstance;
import static org.junit.Assert.assertThat;
import static org.junit.matchers.JUnitMatchers.hasItems;
-import java.util.ArrayList;
-import java.util.Iterator;
-import java.util.List;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+import org.jboss.dna.graph.property.Name;
import org.jboss.dna.graph.property.Property;
import org.junit.Before;
import org.junit.Test;
@@ -41,151 +42,78 @@
public class UpdatePropertiesRequestTest extends AbstractRequestTest {
private UpdatePropertiesRequest request;
+ private Map<Name, Property> validProperties;
@Override
@Before
public void beforeEach() {
super.beforeEach();
+ validProperties = new HashMap<Name, Property>();
+ validProperties.put(validProperty1.getName(), validProperty1);
+ validProperties.put(validProperty2.getName(), validProperty2);
}
@Override
protected Request createRequest() {
- return new UpdatePropertiesRequest(validPathLocation1, workspace1,
validProperty1);
+ return new UpdatePropertiesRequest(validPathLocation1, workspace1,
validProperties);
}
@Test( expected = IllegalArgumentException.class )
public void shouldNotAllowCreatingRequestWithNullFromLocation() {
- new UpdatePropertiesRequest(null, workspace1, validProperty1);
+ new UpdatePropertiesRequest(null, workspace1, validProperties);
}
@Test( expected = IllegalArgumentException.class )
public void shouldNotAllowCreatingRequestWithNullWorkspaceName() {
- new UpdatePropertiesRequest(validPathLocation1, null, validProperty1);
+ new UpdatePropertiesRequest(validPathLocation1, null, validProperties);
}
@Test( expected = IllegalArgumentException.class )
public void shouldNotAllowCreatingRequestWithNullPropertyName() {
- new UpdatePropertiesRequest(validPathLocation, workspace1, (Property[])null);
+ new UpdatePropertiesRequest(validPathLocation, workspace1, null);
}
@Test( expected = IllegalArgumentException.class )
- public void shouldNotAllowCreatingRequestWithEmptyPropertyNameArray() {
- new UpdatePropertiesRequest(validPathLocation, workspace1, new Property[] {});
+ public void shouldNotAllowCreatingRequestWithEmptyPropertyMap() {
+ new UpdatePropertiesRequest(validPathLocation, workspace1, Collections.<Name,
Property>emptyMap());
}
- @Test( expected = IllegalArgumentException.class )
- public void shouldNotAllowCreatingRequestWithNullPropertyNameIterator() {
- new UpdatePropertiesRequest(validPathLocation, workspace1,
(Iterator<Property>)null);
- }
-
- @Test( expected = IllegalArgumentException.class )
- public void shouldNotAllowCreatingRequestWithEmptyPropertyNameIterator() {
- new UpdatePropertiesRequest(validPathLocation, workspace1, new
ArrayList<Property>().iterator());
- }
-
- @Test( expected = IllegalArgumentException.class )
- public void shouldNotAllowCreatingRequestWithNullPropertyNameIterable() {
- new UpdatePropertiesRequest(validPathLocation, workspace1,
(Iterable<Property>)null);
- }
-
- @Test( expected = IllegalArgumentException.class )
- public void shouldNotAllowCreatingRequestWithEmptyPropertyNameIterable() {
- new UpdatePropertiesRequest(validPathLocation, workspace1, new
ArrayList<Property>());
- }
-
@Test
public void shouldCreateValidRequestWithValidLocationAndValidProperty() {
- request = new UpdatePropertiesRequest(validPathLocation1, workspace1,
validProperty1);
+ request = new UpdatePropertiesRequest(validPathLocation1, workspace1,
validProperties);
assertThat(request.on(), is(sameInstance(validPathLocation1)));
assertThat(request.inWorkspace(), is(sameInstance(workspace1)));
assertThat(request.hasError(), is(false));
assertThat(request.getError(), is(nullValue()));
- assertThat(request.properties(), hasItems(validProperty1));
+ assertThat(request.properties().values(), hasItems(validProperty1,
validProperty2));
}
@Test
- public void shouldCreateValidRequestWithValidLocationAndValidPropertyNames() {
- request = new UpdatePropertiesRequest(validPathLocation1, workspace1,
validProperty1, validProperty2);
- assertThat(request.on(), is(sameInstance(validPathLocation1)));
- assertThat(request.hasError(), is(false));
- assertThat(request.getError(), is(nullValue()));
- assertThat(request.properties(), hasItems(validProperty1, validProperty2));
- }
-
- @Test
- public void
shouldCreateValidRequestWithValidLocationAndIteratorOverValidPropertyName() {
- List<Property> properties = new ArrayList<Property>();
- properties.add(validProperty1);
- request = new UpdatePropertiesRequest(validPathLocation1, workspace1,
properties.iterator());
- assertThat(request.on(), is(sameInstance(validPathLocation1)));
- assertThat(request.hasError(), is(false));
- assertThat(request.getError(), is(nullValue()));
- assertThat(request.properties(), hasItems(validProperty1));
- }
-
- @Test
- public void
shouldCreateValidRequestWithValidLocationAndIteratorOverValidPropertyNames() {
- List<Property> properties = new ArrayList<Property>();
- properties.add(validProperty1);
- properties.add(validProperty2);
- request = new UpdatePropertiesRequest(validPathLocation1, workspace1,
properties.iterator());
- assertThat(request.on(), is(sameInstance(validPathLocation1)));
- assertThat(request.hasError(), is(false));
- assertThat(request.getError(), is(nullValue()));
- assertThat(request.properties(), hasItems(validProperty1, validProperty2));
- }
-
- @Test
- public void
shouldCreateValidRequestWithValidLocationAndIterableWithValidPropertyName() {
- List<Property> properties = new ArrayList<Property>();
- properties.add(validProperty1);
- request = new UpdatePropertiesRequest(validPathLocation1, workspace1,
properties);
- assertThat(request.on(), is(sameInstance(validPathLocation1)));
- assertThat(request.hasError(), is(false));
- assertThat(request.getError(), is(nullValue()));
- assertThat(request.properties(), hasItems(validProperty1));
- }
-
- @Test
- public void
shouldCreateValidRequestWithValidLocationAndIterableWithValidPropertyNames() {
- List<Property> properties = new ArrayList<Property>();
- properties.add(validProperty1);
- properties.add(validProperty2);
- request = new UpdatePropertiesRequest(validPathLocation1, workspace1,
properties);
- assertThat(request.on(), is(sameInstance(validPathLocation1)));
- assertThat(request.hasError(), is(false));
- assertThat(request.getError(), is(nullValue()));
- assertThat(request.properties(), hasItems(validProperty1, validProperty2));
- }
-
- @Test
- public void shouldConsiderEqualTwoRequestsWithSameLocationsAndSamePropertyNames() {
- request = new UpdatePropertiesRequest(validPathLocation1, new String(workspace1),
validProperty1, validProperty2);
- UpdatePropertiesRequest request2 = new
UpdatePropertiesRequest(validPathLocation1, workspace1, validProperty1,
- validProperty2);
+ public void shouldConsiderEqualTwoRequestsWithSameLocationsAndSameProperties() {
+ request = new UpdatePropertiesRequest(validPathLocation1, new String(workspace1),
validProperties);
+ UpdatePropertiesRequest request2 = new
UpdatePropertiesRequest(validPathLocation1, workspace1, validProperties);
assertThat(request, is(request2));
}
@Test
public void shouldConsiderNotEqualTwoRequestsWithDifferentLocations() {
- request = new UpdatePropertiesRequest(validPathLocation1, workspace1,
validProperty1, validProperty2);
- UpdatePropertiesRequest request2 = new
UpdatePropertiesRequest(validPathLocation2, workspace1, validProperty1,
- validProperty2);
+ request = new UpdatePropertiesRequest(validPathLocation1, workspace1,
validProperties);
+ UpdatePropertiesRequest request2 = new
UpdatePropertiesRequest(validPathLocation2, workspace1, validProperties);
assertThat(request.equals(request2), is(false));
}
@Test
public void shouldConsiderNotEqualTwoRequestsWithDifferentWorkspaceNames() {
- request = new UpdatePropertiesRequest(validPathLocation1, workspace1,
validProperty1, validProperty2);
- UpdatePropertiesRequest request2 = new
UpdatePropertiesRequest(validPathLocation1, workspace2, validProperty1,
- validProperty2);
+ request = new UpdatePropertiesRequest(validPathLocation1, workspace1,
validProperties);
+ UpdatePropertiesRequest request2 = new
UpdatePropertiesRequest(validPathLocation1, workspace2, validProperties);
assertThat(request.equals(request2), is(false));
}
@Test
- public void
shouldConsiderNotEqualTwoRequestsWithSameLocationButDifferentPropertyNames() {
- request = new UpdatePropertiesRequest(validPathLocation1, workspace1,
validProperty1, validProperty2);
- UpdatePropertiesRequest request2 = new
UpdatePropertiesRequest(validPathLocation2, workspace1, validProperty1);
+ public void shouldConsiderNotEqualTwoRequestsWithSameLocationButDifferentProperties()
{
+ request = new UpdatePropertiesRequest(validPathLocation1, workspace1,
validProperties);
+ Map<Name, Property> otherValidProperties =
Collections.singletonMap(validProperty1.getName(), validProperty1);
+ UpdatePropertiesRequest request2 = new
UpdatePropertiesRequest(validPathLocation2, workspace1, otherValidProperties);
assertThat(request.equals(request2), is(false));
}
Modified: trunk/dna-jcr/src/main/java/org/jboss/dna/jcr/SessionCache.java
===================================================================
--- trunk/dna-jcr/src/main/java/org/jboss/dna/jcr/SessionCache.java 2009-04-06 15:55:23
UTC (rev 808)
+++ trunk/dna-jcr/src/main/java/org/jboss/dna/jcr/SessionCache.java 2009-04-07 21:23:28
UTC (rev 809)
@@ -66,6 +66,7 @@
import org.jboss.dna.graph.property.ValueFactories;
import org.jboss.dna.graph.property.ValueFactory;
import org.jboss.dna.graph.property.ValueFormatException;
+import org.jboss.dna.graph.request.BatchRequestBuilder;
import org.jboss.dna.graph.request.ChangeRequest;
import org.jboss.dna.graph.request.Request;
import org.jboss.dna.jcr.cache.ChangedNodeInfo;
@@ -148,6 +149,7 @@
protected final HashMap<UUID, NodeInfo> deletedNodes;
private LinkedList<Request> requests;
+ private BatchRequestBuilder requestBuilder;
protected Graph.Batch operations;
public SessionCache( JcrSession session,
@@ -183,6 +185,7 @@
// Create the batch operations ...
this.requests = new LinkedList<Request>();
+ this.requestBuilder = new BatchRequestBuilder(this.requests);
this.operations = this.store.batch();
}
@@ -233,7 +236,8 @@
// Create a new batch for future operations ...
// LinkedList<Request> oldRequests = this.requests;
this.requests = new LinkedList<Request>();
- operations = store.batch(this.requests);
+ this.requestBuilder = new BatchRequestBuilder(this.requests);
+ operations = store.batch(this.requestBuilder);
// Remove all the cached items that have been changed or deleted ...
for (UUID changedUuid : changedNodes.keySet()) {
@@ -273,6 +277,9 @@
// Find the path of the given node ...
Path path = getPathFor(nodeUuid);
+ // Make sure the builder has finished all the requests ...
+ this.requestBuilder.finishPendingRequest();
+
// Remove all of the enqueued requests for this branch ...
LinkedList<Request> branchRequests = new LinkedList<Request>();
LinkedList<Request> nonBranchRequests = new
LinkedList<Request>();
@@ -297,13 +304,14 @@
}
// Now execute the branch ...
- Graph.Batch branchBatch = store.batch(branchRequests);
+ Graph.Batch branchBatch = store.batch(new
BatchRequestBuilder(branchRequests));
try {
branchBatch.execute();
// Still have non-branch related requests that we haven't executed
...
this.requests = nonBranchRequests;
- this.operations = store.batch(nonBranchRequests);
+ this.requestBuilder = new BatchRequestBuilder(this.requests);
+ this.operations = store.batch(this.requestBuilder);
// Remove all the cached, changed or deleted items that were just saved
...
for (UUID changedUuid : branchUuids) {
Modified:
trunk/extensions/dna-connector-filesystem/src/main/java/org/jboss/dna/connector/filesystem/FileSystemRequestProcessor.java
===================================================================
---
trunk/extensions/dna-connector-filesystem/src/main/java/org/jboss/dna/connector/filesystem/FileSystemRequestProcessor.java 2009-04-06
15:55:23 UTC (rev 808)
+++
trunk/extensions/dna-connector-filesystem/src/main/java/org/jboss/dna/connector/filesystem/FileSystemRequestProcessor.java 2009-04-07
21:23:28 UTC (rev 809)
@@ -59,7 +59,6 @@
import org.jboss.dna.graph.request.MoveBranchRequest;
import org.jboss.dna.graph.request.ReadAllChildrenRequest;
import org.jboss.dna.graph.request.ReadAllPropertiesRequest;
-import org.jboss.dna.graph.request.RemovePropertiesRequest;
import org.jboss.dna.graph.request.RenameNodeRequest;
import org.jboss.dna.graph.request.Request;
import org.jboss.dna.graph.request.UpdatePropertiesRequest;
@@ -304,16 +303,6 @@
/**
* {@inheritDoc}
*
- * @see
org.jboss.dna.graph.request.processor.RequestProcessor#process(org.jboss.dna.graph.request.RemovePropertiesRequest)
- */
- @Override
- public void process( RemovePropertiesRequest request ) {
- if (updatesAllowed(request)) super.process(request);
- }
-
- /**
- * {@inheritDoc}
- *
* @see
org.jboss.dna.graph.request.processor.RequestProcessor#process(org.jboss.dna.graph.request.RenameNodeRequest)
*/
@Override
Modified:
trunk/extensions/dna-connector-jbosscache/src/main/java/org/jboss/dna/connector/jbosscache/JBossCacheRequestProcessor.java
===================================================================
---
trunk/extensions/dna-connector-jbosscache/src/main/java/org/jboss/dna/connector/jbosscache/JBossCacheRequestProcessor.java 2009-04-06
15:55:23 UTC (rev 808)
+++
trunk/extensions/dna-connector-jbosscache/src/main/java/org/jboss/dna/connector/jbosscache/JBossCacheRequestProcessor.java 2009-04-07
21:23:28 UTC (rev 809)
@@ -190,16 +190,18 @@
if (node == null) return;
// Now set (or remove) the properties to the supplied node ...
- for (Property property : request.properties()) {
- Name propName = property.getName();
+ for (Map.Entry<Name, Property> entry : request.properties().entrySet()) {
+ Name propName = entry.getKey();
// Don't allow the child list property to be removed or changed
if (propName.equals(JBossCacheLexicon.CHILD_PATH_SEGMENT_LIST)) continue;
- if (property.size() == 0) {
+
+ Property property = entry.getValue();
+ if (property == null) {
node.remove(propName);
continue;
}
Object value = null;
- if (property.size() == 1) {
+ if (property.isSingle()) {
value = property.iterator().next();
} else {
value = property.getValuesAsArray();
@@ -502,7 +504,8 @@
assert original != null;
assert newParent != null;
// Get or create the new node ...
- Path.Segment name = desiredName != null ?
context.getValueFactories().getPathFactory().createSegment(desiredName) :
(Path.Segment)original.getFqn().getLastElement();
+ Path.Segment name = desiredName != null ?
context.getValueFactories().getPathFactory().createSegment(desiredName) :
(Path.Segment)original.getFqn()
+
.getLastElement();
// Update the children to account for same-name siblings.
// This not only updates the FQN of the child nodes, but it also sets the
property that stores the
Modified:
trunk/extensions/dna-connector-store-jpa/src/main/java/org/jboss/dna/connector/store/jpa/model/basic/BasicRequestProcessor.java
===================================================================
---
trunk/extensions/dna-connector-store-jpa/src/main/java/org/jboss/dna/connector/store/jpa/model/basic/BasicRequestProcessor.java 2009-04-06
15:55:23 UTC (rev 808)
+++
trunk/extensions/dna-connector-store-jpa/src/main/java/org/jboss/dna/connector/store/jpa/model/basic/BasicRequestProcessor.java 2009-04-07
21:23:28 UTC (rev 809)
@@ -864,12 +864,12 @@
ObjectOutputStream oos = new ObjectOutputStream(os);
int numProps = 0;
LargeValueSerializer largeValues = null;
- Collection<Property> props = request.properties();
+ Map<Name, Property> props = request.properties();
References refs = enforceReferentialIntegrity ? new References() : null;
if (originalData == null) {
largeValues = new LargeValueSerializer(entity);
numProps = props.size();
- serializer.serializeProperties(oos, numProps, props, largeValues,
refs);
+ serializer.serializeProperties(oos, numProps, props.values(),
largeValues, refs);
} else {
boolean hadLargeValues = !entity.getLargeValues().isEmpty();
Set<String> largeValueHashesWritten = hadLargeValues ? new
HashSet<String>() : null;
@@ -940,7 +940,7 @@
}
} catch (NoResultException e) {
// there are no properties yet ...
- createProperties(workspaceId, actual.uuid, request.properties());
+ createProperties(workspaceId, actual.uuid,
request.properties().values());
}
} catch (Throwable e) { // Includes PathNotFoundException
Modified:
trunk/extensions/dna-connector-store-jpa/src/main/java/org/jboss/dna/connector/store/jpa/util/Serializer.java
===================================================================
---
trunk/extensions/dna-connector-store-jpa/src/main/java/org/jboss/dna/connector/store/jpa/util/Serializer.java 2009-04-06
15:55:23 UTC (rev 808)
+++
trunk/extensions/dna-connector-store-jpa/src/main/java/org/jboss/dna/connector/store/jpa/util/Serializer.java 2009-04-07
21:23:28 UTC (rev 809)
@@ -361,7 +361,7 @@
*/
public int reserializeProperties( ObjectInputStream input,
ObjectOutputStream output,
- Collection<Property> updatedProperties,
+ Map<Name, Property> updatedProperties,
LargeValues largeValues,
LargeValues removedLargeValues,
ReferenceValues references ) throws IOException,
ClassNotFoundException {
@@ -371,10 +371,6 @@
assert largeValues != null;
assert references != null;
// Assemble a set of property names to skip deserializing
- Set<Name> skipNames = new HashSet<Name>();
- for (Property property : updatedProperties) {
- skipNames.add(property.getName());
- }
Map<Name, Property> allProperties = new HashMap<Name, Property>();
// Read the number of properties ...
@@ -385,7 +381,7 @@
String nameStr = (String)input.readObject();
Name name = valueFactories.getNameFactory().create(nameStr);
assert name != null;
- if (skipNames.contains(name)) {
+ if (updatedProperties.containsKey(name)) {
// Deserialized, but don't materialize ...
deserializePropertyValues(input, name, true, largeValues,
removedLargeValues, references);
} else {
@@ -399,9 +395,10 @@
}
// Add all the updated properties ...
- for (Property updated : updatedProperties) {
- if (updated.isEmpty()) {
- allProperties.remove(updated.getName());
+ for (Map.Entry<Name, Property> entry : updatedProperties.entrySet()) {
+ Property updated = entry.getValue();
+ if (updated == null) {
+ allProperties.remove(entry.getKey());
} else {
allProperties.put(updated.getName(), updated);
}
Modified:
trunk/extensions/dna-connector-store-jpa/src/test/java/org/jboss/dna/connector/store/jpa/JpaConnectorReadingTest.java
===================================================================
---
trunk/extensions/dna-connector-store-jpa/src/test/java/org/jboss/dna/connector/store/jpa/JpaConnectorReadingTest.java 2009-04-06
15:55:23 UTC (rev 808)
+++
trunk/extensions/dna-connector-store-jpa/src/test/java/org/jboss/dna/connector/store/jpa/JpaConnectorReadingTest.java 2009-04-07
21:23:28 UTC (rev 809)
@@ -24,6 +24,7 @@
package org.jboss.dna.connector.store.jpa;
import org.jboss.dna.common.statistic.Stopwatch;
+import org.jboss.dna.common.util.Logger;
import org.jboss.dna.graph.Graph;
import org.jboss.dna.graph.connector.RepositorySource;
import org.jboss.dna.graph.connector.test.ReadableConnectorTest;
@@ -55,6 +56,17 @@
source.setMaximumConnectionIdleTimeInSeconds(0);
source.setLargeValueSizeInBytes(150);
+ // Create a graph and look up the root node. We do this to initialize the
connection pool and
+ // force the database to be setup at this point. By doing it now, we don't
include this overhead
+ // in our test timings.
+ try {
+ Graph graph = Graph.create(source, context);
+ graph.getNodeAt("/");
+ } catch (Throwable t) {
+ Logger.getLogger(getClass()).debug("Unable to read the root node while
setting up the \"" + source.getName()
+ + "\" JPA source");
+ }
+
return source;
}
Modified:
trunk/extensions/dna-connector-store-jpa/src/test/java/org/jboss/dna/connector/store/jpa/util/SerializerTest.java
===================================================================
---
trunk/extensions/dna-connector-store-jpa/src/test/java/org/jboss/dna/connector/store/jpa/util/SerializerTest.java 2009-04-06
15:55:23 UTC (rev 808)
+++
trunk/extensions/dna-connector-store-jpa/src/test/java/org/jboss/dna/connector/store/jpa/util/SerializerTest.java 2009-04-07
21:23:28 UTC (rev 809)
@@ -268,8 +268,9 @@
Property[] initial = new Property[] {prop1, prop2, prop3, prop4, prop5, prop6,
prop7, prop8};
Property[] updated = new Property[] {prop2b, prop3b, prop6b};
+ Name[] deleted = new Name[] {};
SkippedLargeValues removedLargeValues = new SkippedLargeValues();
- assertReserializable(serializer, removedLargeValues, initial, updated);
+ assertReserializable(serializer, removedLargeValues, initial, updated, deleted);
assertThat(largeValues.getCount(), is(3));
assertThat(removedLargeValues.getCount(), is(2)); // p2's value and p6's
original value
@@ -411,26 +412,29 @@
protected void assertReserializable( Serializer serializer,
Serializer.LargeValues removedLargeValues,
Property[] originalProperties,
- Property... updatedProperties ) throws
IOException, ClassNotFoundException {
+ Property[] updatedProperties,
+ Name[] removedProperties ) throws IOException,
ClassNotFoundException {
Collection<Name> propertiesThatStay = new HashSet<Name>();
Collection<Name> propertiesThatAreDeleted = new HashSet<Name>();
for (Property prop : originalProperties) {
propertiesThatStay.add(prop.getName());
}
for (Property prop : updatedProperties) {
- if (prop.isEmpty()) {
- propertiesThatAreDeleted.add(prop.getName());
- propertiesThatStay.remove(prop.getName());
- } else {
- propertiesThatStay.add(prop.getName());
- }
+ propertiesThatStay.add(prop.getName());
}
+ for (Name removedPropertyName : removedProperties) {
+ propertiesThatAreDeleted.add(removedPropertyName);
+ propertiesThatStay.remove(removedPropertyName);
+ }
// Serialize the properties one at a time ...
byte[] bytes = serialize(serializer, originalProperties);
// Now reserialize, updating the properties ...
- Collection<Property> updatedProps = Arrays.asList(updatedProperties);
+ Map<Name, Property> updatedProps = new HashMap<Name, Property>();
+ for (Property property : updatedProperties) {
+ updatedProps.put(property.getName(), property);
+ }
ByteArrayInputStream bais = new ByteArrayInputStream(bytes);
ObjectInputStream ois = new ObjectInputStream(bais);
ByteArrayOutputStream baos = new ByteArrayOutputStream();
Modified:
trunk/extensions/dna-connector-svn/src/main/java/org/jboss/dna/connector/svn/SVNRepositoryRequestProcessor.java
===================================================================
---
trunk/extensions/dna-connector-svn/src/main/java/org/jboss/dna/connector/svn/SVNRepositoryRequestProcessor.java 2009-04-06
15:55:23 UTC (rev 808)
+++
trunk/extensions/dna-connector-svn/src/main/java/org/jboss/dna/connector/svn/SVNRepositoryRequestProcessor.java 2009-04-07
21:23:28 UTC (rev 809)
@@ -61,7 +61,6 @@
import org.jboss.dna.graph.request.MoveBranchRequest;
import org.jboss.dna.graph.request.ReadAllChildrenRequest;
import org.jboss.dna.graph.request.ReadAllPropertiesRequest;
-import org.jboss.dna.graph.request.RemovePropertiesRequest;
import org.jboss.dna.graph.request.RenameNodeRequest;
import org.jboss.dna.graph.request.Request;
import org.jboss.dna.graph.request.UpdatePropertiesRequest;
@@ -347,18 +346,6 @@
/**
* {@inheritDoc}
*
- * @see
org.jboss.dna.graph.request.processor.RequestProcessor#process(org.jboss.dna.graph.request.RemovePropertiesRequest)
- */
- @Override
- public void process( RemovePropertiesRequest request ) {
- logger.trace(request.toString());
- verifyUpdatesAllowed();
- super.process(request);
- }
-
- /**
- * {@inheritDoc}
- *
* @see
org.jboss.dna.graph.request.processor.RequestProcessor#process(org.jboss.dna.graph.request.RenameNodeRequest)
*/
@Override
@@ -727,6 +714,7 @@
/**
* Create a file.
+ *
* @param path
* @param file
* @param content
@@ -735,14 +723,17 @@
*/
private void newFile( String path,
String file,
- byte[] content, String message ) throws SVNException {
+ byte[] content,
+ String message ) throws SVNException {
SVNNodeKind childKind = repository.checkPath(file, -1);
if (childKind == SVNNodeKind.NONE) {
ScmAction addFileNodeAction = addFile(path, file, content);
SVNActionExecutor executor = new SVNActionExecutor(repository);
- executor.execute(addFileNodeAction,message);
+ executor.execute(addFileNodeAction, message);
} else {
- SVNErrorMessage err = SVNErrorMessage.create(SVNErrorCode.UNKNOWN, "Item
with name '{0}' can't be created (already exist)", file);
+ SVNErrorMessage err = SVNErrorMessage.create(SVNErrorCode.UNKNOWN,
+ "Item with name
'{0}' can't be created (already exist)",
+ file);
throw new SVNException(err);
}
}
@@ -764,7 +755,7 @@
*/
public ScmAction addFile( String path,
String file,
- byte[] content) {
+ byte[] content ) {
return new AddFile(path, file, content);
}
@@ -858,16 +849,16 @@
}
-// private Date getCreatedOn( Object[] objs ) {
-// Date createdOn = null;
-// for (Object object : objs) {
-// if (object instanceof Date) {
-// createdOn = (Date)object;
-//
-// }
-// }
-// return createdOn;
-// }
+ // private Date getCreatedOn( Object[] objs ) {
+ // Date createdOn = null;
+ // for (Object object : objs) {
+ // if (object instanceof Date) {
+ // createdOn = (Date)object;
+ //
+ // }
+ // }
+ // return createdOn;
+ // }
private byte[] getContent( Object[] objs ) {
byte[] content = null;