Author: rhauch
Date: 2009-04-22 04:49:23 -0400 (Wed, 22 Apr 2009)
New Revision: 842
Added:
trunk/extensions/dna-connector-jbosscache/src/test/java/org/jboss/dna/connector/jbosscache/JBossCacheConnectorWritableTest.java
Modified:
trunk/dna-graph/src/main/java/org/jboss/dna/graph/Graph.java
trunk/dna-graph/src/main/java/org/jboss/dna/graph/connector/RepositorySourceCapabilities.java
trunk/dna-graph/src/main/java/org/jboss/dna/graph/connector/inmemory/InMemoryRepository.java
trunk/dna-graph/src/main/java/org/jboss/dna/graph/connector/inmemory/InMemoryRepositorySource.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/BatchRequestBuilder.java
trunk/dna-graph/src/main/java/org/jboss/dna/graph/request/MoveBranchRequest.java
trunk/dna-graph/src/main/java/org/jboss/dna/graph/request/RequestBuilder.java
trunk/dna-graph/src/test/java/org/jboss/dna/graph/GraphTest.java
trunk/dna-graph/src/test/java/org/jboss/dna/graph/connector/inmemory/InMemoryRepositoryWorkspaceTest.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/connector/test/WritableConnectorTest.java
trunk/extensions/dna-connector-filesystem/src/main/java/org/jboss/dna/connector/filesystem/FileSystemSource.java
trunk/extensions/dna-connector-jbosscache/src/main/java/org/jboss/dna/connector/jbosscache/JBossCacheConnectorI18n.java
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/JBossCacheSource.java
trunk/extensions/dna-connector-jbosscache/src/main/java/org/jboss/dna/connector/jbosscache/JBossCacheWorkspaces.java
trunk/extensions/dna-connector-jbosscache/src/main/resources/org/jboss/dna/connector/jbosscache/JBossCacheConnectorI18n.properties
trunk/extensions/dna-connector-store-jpa/src/main/java/org/jboss/dna/connector/store/jpa/JpaSource.java
trunk/extensions/dna-connector-store-jpa/src/main/java/org/jboss/dna/connector/store/jpa/model/basic/BasicRequestProcessor.java
trunk/extensions/dna-connector-svn/src/main/java/org/jboss/dna/connector/svn/SVNRepositorySource.java
Log:
DNA-375 Enhance MoveBranchRequest to take a new name, analogous to how CopyBranchRequest
works
Changed the connector API's MoveBranchRequest to have a new desiredName() field, and
changed the writable connectors to implement these new semantics. Also expose this
through the Graph API. Added several tests to the connector unit test framework to test
for these additional move behaviors.
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-20 20:21:21 UTC
(rev 841)
+++ trunk/dna-graph/src/main/java/org/jboss/dna/graph/Graph.java 2009-04-22 08:49:23 UTC
(rev 842)
@@ -436,10 +436,11 @@
return new MoveAction<Conjunction<Graph>>(this.nextGraph, from) {
@Override
protected Conjunction<Graph> submit( Locations from,
- Location into ) {
+ Location into,
+ Name newName ) {
String workspaceName = getCurrentWorkspaceName();
do {
- requests.moveBranch(from.getLocation(), into, workspaceName);
+ requests.moveBranch(from.getLocation(), into, workspaceName,
newName);
} while ((from = from.next()) != null);
return and();
}
@@ -1066,7 +1067,10 @@
public SetValuesTo<Conjunction<Graph>> on( final Location
location ) {
return new SetValuesTo<Conjunction<Graph>>() {
public Conjunction<Graph> to( Node value ) {
- return to(value.getLocation());
+ Reference ref = (Reference)convertReferenceValue(value);
+ Property property =
getContext().getPropertyFactory().create(propertyName, ref);
+ requests.setProperty(location, getCurrentWorkspaceName(),
property);
+ return nextGraph;
}
public Conjunction<Graph> to( Location value ) {
@@ -2023,10 +2027,11 @@
return new MoveAction<BatchConjunction>(this.nextRequests, from) {
@Override
protected BatchConjunction submit( Locations from,
- Location into ) {
+ Location into,
+ Name newName ) {
String workspaceName = getCurrentWorkspaceName();
do {
- requestQueue.moveBranch(from.getLocation(), into,
workspaceName);
+ requestQueue.moveBranch(from.getLocation(), into, workspaceName,
newName);
} while ((from = from.next()) != null);
return and();
}
@@ -3343,6 +3348,18 @@
Node node = (Node)value;
UUID uuid = node.getLocation().getUuid();
if (uuid == null) {
+ // Look for a property ...
+ Property uuidProperty = node.getProperty(DnaLexicon.UUID);
+ if (uuidProperty != null) {
+ uuid =
context.getValueFactories().getUuidFactory().create(uuidProperty.getFirstValue());
+ } else {
+ uuidProperty = node.getProperty(JcrLexicon.UUID);
+ if (uuidProperty != null) {
+ uuid =
context.getValueFactories().getUuidFactory().create(uuidProperty.getFirstValue());
+ }
+ }
+ }
+ if (uuid == null) {
String nodeString =
node.getLocation().getString(getContext().getNamespaceRegistry());
String msg =
GraphI18n.unableToCreateReferenceToNodeWithoutUuid.text(nodeString);
throw new IllegalArgumentException(msg);
@@ -3559,6 +3576,30 @@
}
/**
+ * A component that defines a new name for a node.
+ *
+ * @param <Next> The interface that is to be returned when this request is
completed
+ * @author Randall Hauch
+ */
+ public interface AsName<Next> {
+ /**
+ * Finish the request by specifying the new name.
+ *
+ * @param newName the new name
+ * @return the interface for additional requests or actions
+ */
+ Next as( String newName );
+
+ /**
+ * Finish the request by specifying the new name.
+ *
+ * @param newName the new name
+ * @return the interface for additional requests or actions
+ */
+ Next as( Name newName );
+ }
+
+ /**
* A interface that is used to add more locations that are to be copied/moved.
*
* @param <Next> The interface that is to be returned when this request is
completed
@@ -3632,7 +3673,7 @@
* @param <Next> The interface that is to be returned when this request is
completed
* @author Randall Hauch
*/
- public interface Move<Next> extends Into<Next>,
And<Move<Next>> {
+ public interface Move<Next> extends AsName<Into<Next>>,
Into<Next>, And<Move<Next>> {
}
/**
@@ -5190,11 +5231,16 @@
/*package*/Path createPath( String path ) {
return
Graph.this.getContext().getValueFactories().getPathFactory().create(path);
}
+
+ /*package*/Name createName( String name ) {
+ return
Graph.this.getContext().getValueFactories().getNameFactory().create(name);
+ }
}
@NotThreadSafe
protected abstract class MoveAction<T> extends AbstractAction<T>
implements Move<T> {
private final Locations from;
+ private Name newName;
/*package*/MoveAction( T afterConjunction,
Location from ) {
@@ -5238,39 +5284,55 @@
return this;
}
+ public Into<T> as( Name newName ) {
+ this.newName = newName;
+ return this;
+ }
+
/**
+ * {@inheritDoc}
+ *
+ * @see org.jboss.dna.graph.Graph.AsName#as(java.lang.String)
+ */
+ public Into<T> as( String newName ) {
+ return as(createName(newName));
+ }
+
+ /**
* 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
+ * @param newName the new name for the node being moved; may be null
* @return this object, for method chaining
*/
protected abstract T submit( Locations from,
- Location into );
+ Location into,
+ Name newName );
public T into( Location into ) {
- return submit(from, into);
+ return submit(from, into, newName);
}
public T into( Path into ) {
- return submit(from, Location.create(into));
+ return submit(from, Location.create(into), newName);
}
public T into( UUID into ) {
- return submit(from, Location.create(into));
+ return submit(from, Location.create(into), newName);
}
public T into( Property firstIdProperty,
Property... additionalIdProperties ) {
- return submit(from, Location.create(firstIdProperty,
additionalIdProperties));
+ return submit(from, Location.create(firstIdProperty, additionalIdProperties),
newName);
}
public T into( Property into ) {
- return submit(from, Location.create(into));
+ return submit(from, Location.create(into), newName);
}
public T into( String into ) {
- return submit(from, Location.create(createPath(into)));
+ return submit(from, Location.create(createPath(into)), newName);
}
}
Modified:
trunk/dna-graph/src/main/java/org/jboss/dna/graph/connector/RepositorySourceCapabilities.java
===================================================================
---
trunk/dna-graph/src/main/java/org/jboss/dna/graph/connector/RepositorySourceCapabilities.java 2009-04-20
20:21:21 UTC (rev 841)
+++
trunk/dna-graph/src/main/java/org/jboss/dna/graph/connector/RepositorySourceCapabilities.java 2009-04-22
08:49:23 UTC (rev 842)
@@ -55,32 +55,41 @@
*/
public static final boolean DEFAULT_SUPPORT_CREATING_WORKSPACES = false;
+ /**
+ * The default support for creating workspaces is {@value} .
+ */
+ public static final boolean DEFAULT_SUPPORT_REFERENCES = true;
+
private boolean sameNameSiblings;
private boolean updates;
private boolean events;
private boolean creatingWorkspaces;
+ private boolean references;
/**
* Create a capabilities object using the defaults, .
*/
public RepositorySourceCapabilities() {
this(DEFAULT_SUPPORT_SAME_NAME_SIBLINGS, DEFAULT_SUPPORT_UPDATES,
DEFAULT_SUPPORT_EVENTS,
- DEFAULT_SUPPORT_CREATING_WORKSPACES);
+ DEFAULT_SUPPORT_CREATING_WORKSPACES, DEFAULT_SUPPORT_REFERENCES);
}
public RepositorySourceCapabilities( boolean supportsSameNameSiblings,
boolean supportsUpdates ) {
- this(supportsSameNameSiblings, supportsUpdates, DEFAULT_SUPPORT_EVENTS,
DEFAULT_SUPPORT_CREATING_WORKSPACES);
+ this(supportsSameNameSiblings, supportsUpdates, DEFAULT_SUPPORT_EVENTS,
DEFAULT_SUPPORT_CREATING_WORKSPACES,
+ DEFAULT_SUPPORT_REFERENCES);
}
public RepositorySourceCapabilities( boolean supportsSameNameSiblings,
boolean supportsUpdates,
boolean supportsEvents,
- boolean supportsCreatingWorkspaces ) {
+ boolean supportsCreatingWorkspaces,
+ boolean supportsReferences ) {
this.sameNameSiblings = supportsSameNameSiblings;
this.updates = supportsUpdates;
this.events = supportsEvents;
this.creatingWorkspaces = supportsCreatingWorkspaces;
+ this.references = supportsReferences;
}
/**
@@ -104,6 +113,15 @@
}
/**
+ * Return whether the source supports references by identifiers.
+ *
+ * @return true if references are supported, or false otherwise
+ */
+ public boolean supportsReferences() {
+ return references;
+ }
+
+ /**
* Return whether the source supports events through {@link
RepositorySourceListener}s.
*
* @return true if events are supported, or false if the source is not capable of
generating events
Modified:
trunk/dna-graph/src/main/java/org/jboss/dna/graph/connector/inmemory/InMemoryRepository.java
===================================================================
---
trunk/dna-graph/src/main/java/org/jboss/dna/graph/connector/inmemory/InMemoryRepository.java 2009-04-20
20:21:21 UTC (rev 841)
+++
trunk/dna-graph/src/main/java/org/jboss/dna/graph/connector/inmemory/InMemoryRepository.java 2009-04-22
08:49:23 UTC (rev 842)
@@ -342,11 +342,13 @@
*
* @param context
* @param node the node to be moved; may not be the {@link Workspace#getRoot()
root}
+ * @param desiredNewName the new name for the node, if it is to be changed; may
be null
* @param newWorkspace the workspace containing the new parent node
* @param newParent the new parent; may not be the {@link Workspace#getRoot()
root}
*/
public void moveNode( ExecutionContext context,
InMemoryNode node,
+ Name desiredNewName,
Workspace newWorkspace,
InMemoryNode newParent ) {
assert context != null;
@@ -355,16 +357,22 @@
assert newWorkspace.getRoot().equals(newParent) != true;
assert this.getRoot().equals(node) != true;
InMemoryNode oldParent = node.getParent();
+ Name oldName = node.getName().getName();
if (oldParent != null) {
if (oldParent.equals(newParent)) return;
boolean removed = oldParent.getChildren().remove(node);
assert removed == true;
node.setParent(null);
- correctSameNameSiblingIndexes(context, oldParent,
node.getName().getName());
+ correctSameNameSiblingIndexes(context, oldParent, oldName);
}
node.setParent(newParent);
+ Name newName = oldName;
+ if (desiredNewName != null) {
+ newName = desiredNewName;
+
node.setName(context.getValueFactories().getPathFactory().createSegment(desiredNewName,
1));
+ }
newParent.getChildren().add(node);
- correctSameNameSiblingIndexes(context, newParent, node.getName().getName());
+ correctSameNameSiblingIndexes(context, newParent, newName);
// If the node was moved to a new workspace...
if (!this.equals(newWorkspace)) {
Modified:
trunk/dna-graph/src/main/java/org/jboss/dna/graph/connector/inmemory/InMemoryRepositorySource.java
===================================================================
---
trunk/dna-graph/src/main/java/org/jboss/dna/graph/connector/inmemory/InMemoryRepositorySource.java 2009-04-20
20:21:21 UTC (rev 841)
+++
trunk/dna-graph/src/main/java/org/jboss/dna/graph/connector/inmemory/InMemoryRepositorySource.java 2009-04-22
08:49:23 UTC (rev 842)
@@ -71,7 +71,8 @@
*/
public static final int DEFAULT_RETRY_LIMIT = 0;
- protected static final RepositorySourceCapabilities CAPABILITIES = new
RepositorySourceCapabilities(true, true, false, true);
+ protected static final RepositorySourceCapabilities CAPABILITIES = new
RepositorySourceCapabilities(true, true, false, true,
+
true);
protected static final String ROOT_NODE_UUID = "rootNodeUuid";
protected static final String SOURCE_NAME = "sourceName";
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-20
20:21:21 UTC (rev 841)
+++
trunk/dna-graph/src/main/java/org/jboss/dna/graph/connector/inmemory/InMemoryRequestProcessor.java 2009-04-22
08:49:23 UTC (rev 842)
@@ -192,11 +192,11 @@
InMemoryNode node = getTargetNode(workspace, request, request.from());
if (node == null) return;
// Look up the new parent, which must exist ...
- Path newPath = request.into().getPath();
- Path newParentPath = newPath.getParent();
+ Path newParentPath = request.into().getPath();
InMemoryNode newParent = workspace.getNode(newParentPath);
- node.setParent(newParent);
- newPath =
getExecutionContext().getValueFactories().getPathFactory().create(newParentPath,
node.getName());
+ workspace.moveNode(getExecutionContext(), node, request.desiredName(), workspace,
newParent);
+ assert node.getParent() == newParent;
+ Path newPath =
getExecutionContext().getValueFactories().getPathFactory().create(newParentPath,
node.getName().getName());
Location oldLocation = getActualLocation(request.from().getPath(), node);
Location newLocation = Location.create(newPath, node.getUuid());
request.setActualLocations(oldLocation, newLocation);
Modified:
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 2009-04-20
20:21:21 UTC (rev 841)
+++
trunk/dna-graph/src/main/java/org/jboss/dna/graph/request/BatchRequestBuilder.java 2009-04-22
08:49:23 UTC (rev 842)
@@ -619,6 +619,23 @@
* @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 newNameForNode the new name for the node being moved, or null if the name
of the original should be used
+ * @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,
+ Name newNameForNode ) {
+ return add(new MoveBranchRequest(from, into, workspaceName, newNameForNode,
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
Modified:
trunk/dna-graph/src/main/java/org/jboss/dna/graph/request/MoveBranchRequest.java
===================================================================
---
trunk/dna-graph/src/main/java/org/jboss/dna/graph/request/MoveBranchRequest.java 2009-04-20
20:21:21 UTC (rev 841)
+++
trunk/dna-graph/src/main/java/org/jboss/dna/graph/request/MoveBranchRequest.java 2009-04-22
08:49:23 UTC (rev 842)
@@ -27,6 +27,7 @@
import org.jboss.dna.graph.GraphI18n;
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;
/**
@@ -43,6 +44,7 @@
private final Location from;
private final Location into;
private final String workspaceName;
+ private final Name desiredNameForNode;
private final NodeConflictBehavior conflictBehavior;
private Location actualOldLocation;
private Location actualNewLocation;
@@ -58,7 +60,7 @@
public MoveBranchRequest( Location from,
Location into,
String workspaceName ) {
- this(from, into, workspaceName, DEFAULT_CONFLICT_BEHAVIOR);
+ this(from, into, workspaceName, null, DEFAULT_CONFLICT_BEHAVIOR);
}
/**
@@ -67,6 +69,22 @@
* @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 newNameForMovedNode the new name for the node being moved, or null if the
name of the original should be used
+ * @throws IllegalArgumentException if any of the parameters are null
+ */
+ public MoveBranchRequest( Location from,
+ Location into,
+ String workspaceName,
+ Name newNameForMovedNode ) {
+ this(from, into, workspaceName, newNameForMovedNode, 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
* @throws IllegalArgumentException if any of the parameters are null
@@ -75,6 +93,25 @@
Location into,
String workspaceName,
NodeConflictBehavior conflictBehavior ) {
+ this(from, into, workspaceName, null, 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
+ * @param newNameForMovedNode the new name for the node being moved, 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
+ * @throws IllegalArgumentException if any of the parameters are null
+ */
+ public MoveBranchRequest( Location from,
+ Location into,
+ String workspaceName,
+ Name newNameForMovedNode,
+ NodeConflictBehavior conflictBehavior ) {
CheckArg.isNotNull(from, "from");
CheckArg.isNotNull(into, "into");
CheckArg.isNotNull(workspaceName, "workspaceName");
@@ -82,6 +119,7 @@
this.from = from;
this.into = into;
this.workspaceName = workspaceName;
+ this.desiredNameForNode = newNameForMovedNode;
this.conflictBehavior = conflictBehavior;
}
@@ -113,6 +151,15 @@
}
/**
+ * Get the name of the copy if it is to be different than that of the original.
+ *
+ * @return the desired name of the copy, or null if the name of the original is to be
used
+ */
+ public Name desiredName() {
+ return desiredNameForNode;
+ }
+
+ /**
* Get the expected behavior when copying the branch and the {@link #into()
destination} already has a node with the same
* name.
*
@@ -150,7 +197,9 @@
*/
public boolean hasNoEffect() {
if (into.hasPath() && into.hasIdProperties() == false &&
from.hasPath()) {
- return from.getPath().getParent().equals(into.getPath());
+ if (!from.getPath().getParent().equals(into.getPath())) return false;
+ if (desiredName() != null &&
!desiredName().equals(from.getPath().getLastSegment().getName())) return false;
+ return true;
}
// Can't be determined for certain
return false;
@@ -160,8 +209,8 @@
* Sets the actual and complete location of the node being renamed and its new
location. This method must be called when
* processing the request, and the actual location must have a {@link
Location#getPath() path}.
*
- * @param oldLocation the actual location of the node before being renamed
- * @param newLocation the actual location of the new copy of the node
+ * @param oldLocation the actual location of the node before being moved
+ * @param newLocation the actual new location of the node
* @throws IllegalArgumentException if the either location is null, if the old
location does not represent the
* {@link Location#isSame(Location) same location} as the {@link #from() from
location}, if the new location does not
* represent the {@link Location#isSame(Location) same location} as the
{@link #into() into location}, or if the
@@ -169,20 +218,25 @@
*/
public void setActualLocations( Location oldLocation,
Location newLocation ) {
+ CheckArg.isNotNull(oldLocation, "oldLocation");
+ CheckArg.isNotNull(newLocation, "newLocation");
if (!from.isSame(oldLocation)) { // not same if actual is null
throw new
IllegalArgumentException(GraphI18n.actualLocationIsNotSameAsInputLocation.text(oldLocation,
from));
}
- if (!into.isSame(newLocation, false)) { // not same if actual is null
- throw new
IllegalArgumentException(GraphI18n.actualLocationIsNotSameAsInputLocation.text(newLocation,
into));
- }
- assert oldLocation != null;
- assert newLocation != null;
if (!oldLocation.hasPath()) {
throw new
IllegalArgumentException(GraphI18n.actualOldLocationMustHavePath.text(oldLocation));
}
if (!newLocation.hasPath()) {
throw new
IllegalArgumentException(GraphI18n.actualNewLocationMustHavePath.text(newLocation));
}
+ if (into().hasPath() &&
!newLocation.getPath().getParent().isSameAs(into.getPath())) {
+ throw new
IllegalArgumentException(GraphI18n.actualLocationIsNotSameAsInputLocation.text(newLocation,
into));
+ }
+ Name actualNewName = newLocation.getPath().getLastSegment().getName();
+ Name expectedNewName = desiredName() != null ? desiredName() :
oldLocation.getPath().getLastSegment().getName();
+ if (!actualNewName.equals(expectedNewName)) {
+ throw new
IllegalArgumentException(GraphI18n.actualLocationIsNotSameAsInputLocation.text(newLocation,
into));
+ }
this.actualNewLocation = newLocation;
}
@@ -249,6 +303,10 @@
*/
@Override
public String toString() {
- return "move branch " + from() + " in the \"" +
workspaceName + "\" workspace into " + into();
+ if (desiredName() != null) {
+ return "move branch " + from() + " in the \"" +
inWorkspace() + "\" workspace into " + into() + " with name "
+ + desiredName();
+ }
+ return "move branch " + from() + " in the \"" +
inWorkspace() + "\" workspace into " + into();
}
}
Modified: 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 2009-04-20
20:21:21 UTC (rev 841)
+++
trunk/dna-graph/src/main/java/org/jboss/dna/graph/request/RequestBuilder.java 2009-04-22
08:49:23 UTC (rev 842)
@@ -466,6 +466,23 @@
* @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 newNameForNode the new name for the node being moved, or null if the name
of the original should be used
+ * @return the request; never null
+ * @throws IllegalArgumentException if any of the parameters are null
+ */
+ public MoveBranchRequest moveBranch( Location from,
+ Location into,
+ String workspaceName,
+ Name newNameForNode ) {
+ return process(new MoveBranchRequest(from, into, workspaceName, newNameForNode,
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 newNameForNode the new name for the node being moved, 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
* @return the request; never null
@@ -474,8 +491,28 @@
public MoveBranchRequest moveBranch( Location from,
Location into,
String workspaceName,
+ Name newNameForNode,
NodeConflictBehavior conflictBehavior ) {
if (conflictBehavior == null) conflictBehavior =
MoveBranchRequest.DEFAULT_CONFLICT_BEHAVIOR;
+ return process(new MoveBranchRequest(from, into, workspaceName, newNameForNode,
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
+ * @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));
}
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-20 20:21:21
UTC (rev 841)
+++ trunk/dna-graph/src/test/java/org/jboss/dna/graph/GraphTest.java 2009-04-22 08:49:23
UTC (rev 842)
@@ -93,6 +93,8 @@
private ExecutionContext context;
private Path validPath;
private String validPathString;
+ private Name validName;
+ private String validNameString;
private UUID validUuid;
private Property validIdProperty1;
private Property validIdProperty2;
@@ -120,6 +122,8 @@
validPathString = "/a/b/c";
validUuid = UUID.randomUUID();
validPath = createPath(validPathString);
+ validNameString = "theName";
+ validName = createName(validNameString);
Name idProperty1Name = createName("id1");
Name idProperty2Name = createName("id2");
validIdProperty1 = context.getPropertyFactory().create(idProperty1Name,
"1");
@@ -978,6 +982,15 @@
}
@Test
+ public void shouldMoveAndRenameNodesThroughMultipleMoveRequests() {
+ graph.move(validPath).as(validName).into(validIdProperty1,
validIdProperty2).and().move(validUuid).into(validPathString);
+ assertThat(numberOfExecutions, is(2));
+ assertNextRequestIsMove(Location.create(validPath),
Location.create(validIdProperty1, validIdProperty2));
+ assertNextRequestIsMove(Location.create(validUuid),
Location.create(createPath(validPathString)));
+ assertNoMoreRequests();
+ }
+
+ @Test
public void shouldIgnoreIncompleteRequests() {
graph.move(validPath); // missing 'into(...)'
assertNoMoreRequests();
@@ -1081,8 +1094,33 @@
@Override
public void process( MoveBranchRequest request ) {
- // Just update the actual location
- request.setActualLocations(actualLocationOf(request.from()),
actualLocationOf(request.into()));
+ // Just update the actual location ...
+ Name newName = request.desiredName();
+ if (newName == null && request.from().hasPath()) newName =
request.from().getPath().getLastSegment().getName();
+ if (newName == null) newName =
context.getValueFactories().getNameFactory().create("d");
+ // Figure out the new name and path (if needed)...
+ Path newPath = null;
+ if (request.into().hasPath()) {
+ newPath =
context.getValueFactories().getPathFactory().create(request.into().getPath(), newName);
+ } else if (request.from().hasPath()) {
+ newPath =
context.getValueFactories().getPathFactory().create("/a/b/c");
+ newPath = context.getValueFactories().getPathFactory().create(newPath,
newName);
+ } else {
+ newPath =
context.getValueFactories().getPathFactory().create("/a/b/c");
+ newPath = context.getValueFactories().getPathFactory().create(newPath,
newName);
+ }
+ // Figure out the old name and path ...
+ Path oldPath = null;
+ if (request.from().hasPath()) {
+ oldPath = request.from().getPath();
+ } else {
+ oldPath =
context.getValueFactories().getPathFactory().create("/x/y/z");
+ oldPath = context.getValueFactories().getPathFactory().create(oldPath,
newName);
+ }
+ Location fromLocation = request.from().hasIdProperties() ?
Location.create(oldPath, request.from().getIdProperties()) : Location.create(oldPath);
+ Location intoLocation = request.into().hasIdProperties() ?
Location.create(newPath, request.into().getIdProperties()) : Location.create(newPath);
+
+ request.setActualLocations(fromLocation, intoLocation);
}
@Override
Modified:
trunk/dna-graph/src/test/java/org/jboss/dna/graph/connector/inmemory/InMemoryRepositoryWorkspaceTest.java
===================================================================
---
trunk/dna-graph/src/test/java/org/jboss/dna/graph/connector/inmemory/InMemoryRepositoryWorkspaceTest.java 2009-04-20
20:21:21 UTC (rev 841)
+++
trunk/dna-graph/src/test/java/org/jboss/dna/graph/connector/inmemory/InMemoryRepositoryWorkspaceTest.java 2009-04-22
08:49:23 UTC (rev 842)
@@ -239,7 +239,7 @@
assertThat(workspace.getNode(pathFactory.create("/d/e")),
is(sameInstance(node_e)));
assertThat(workspace.getNode(pathFactory.create("/d/b")),
is(sameInstance(node_b2)));
- workspace.moveNode(context, node_b, workspace, node_d);
+ workspace.moveNode(context, node_b, null, workspace, node_d);
assertThat(workspace.getNode(pathFactory.create("/")),
is(sameInstance(workspace.getRoot())));
assertThat(workspace.getNode(pathFactory.create("/a")),
is(sameInstance(node_a)));
@@ -249,7 +249,7 @@
assertThat(workspace.getNode(pathFactory.create("/d/b[2]")),
is(sameInstance(node_b)));
assertThat(workspace.getNode(pathFactory.create("/d/b[2]/c")),
is(sameInstance(node_c)));
- workspace.moveNode(context, node_b, workspace, node_e);
+ workspace.moveNode(context, node_b, null, workspace, node_e);
assertThat(workspace.getNode(pathFactory.create("/")),
is(sameInstance(workspace.getRoot())));
assertThat(workspace.getNode(pathFactory.create("/a")),
is(sameInstance(node_a)));
@@ -302,7 +302,7 @@
assertThat(new_workspace.getNode(pathFactory.create("/d/b")),
is(sameInstance(new_node_b2)));
// Move 'workspace::/a/b' into 'newWorkspace::/d'
- workspace.moveNode(context, node_b, new_workspace, new_node_d);
+ workspace.moveNode(context, node_b, null, new_workspace, new_node_d);
assertThat(workspace.getNodesByUuid().size(), is(5));
assertThat(workspace.getNode(pathFactory.create("/")),
is(sameInstance(workspace.getRoot())));
@@ -579,7 +579,9 @@
@Test
public void shouldCreateRepositoryStructure() {
- workspace.createNode(context, "/a").setProperty(context,
"name", "value").setProperty(context, "desc", "Some
description");
+ workspace.createNode(context, "/a")
+ .setProperty(context, "name", "value")
+ .setProperty(context, "desc", "Some description");
workspace.createNode(context, "/a/b").setProperty(context,
"name", "value2").setProperty(context,
"desc",
"Some description 2");
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-20
20:21:21 UTC (rev 841)
+++
trunk/dna-graph/src/test/java/org/jboss/dna/graph/connector/test/AbstractConnectorTest.java 2009-04-22
08:49:23 UTC (rev 842)
@@ -38,8 +38,10 @@
import java.util.UUID;
import java.util.concurrent.TimeUnit;
import org.jboss.dna.common.statistic.Stopwatch;
+import org.jboss.dna.graph.DnaLexicon;
import org.jboss.dna.graph.ExecutionContext;
import org.jboss.dna.graph.Graph;
+import org.jboss.dna.graph.JcrLexicon;
import org.jboss.dna.graph.Location;
import org.jboss.dna.graph.Node;
import org.jboss.dna.graph.Subgraph;
@@ -84,6 +86,7 @@
private static List<RepositoryConnection> openConnections;
private static boolean running;
private static Location rootLocation;
+ private static UUID rootUuid;
public void startRepository() throws Exception {
if (!running) {
@@ -141,6 +144,7 @@
} finally {
running = false;
rootLocation = null;
+ rootUuid = null;
}
}
}
@@ -292,11 +296,24 @@
}
protected UUID getRootNodeUuid() {
- if (rootLocation == null) {
+ if (rootUuid == null) {
Node root = graph.getNodeAt("/");
rootLocation = root.getLocation();
+ rootUuid = rootLocation.getUuid();
+ if (rootUuid == null) {
+ Property uuid = root.getProperty(DnaLexicon.UUID);
+ if (uuid != null) {
+ rootUuid =
context.getValueFactories().getUuidFactory().create(uuid.getFirstValue());
+ }
+ }
+ if (rootUuid == null) {
+ Property uuid = root.getProperty(JcrLexicon.UUID);
+ if (uuid != null) {
+ rootUuid =
context.getValueFactories().getUuidFactory().create(uuid.getFirstValue());
+ }
+ }
}
- return rootLocation.getUuid();
+ return rootUuid;
}
protected String string( Object value ) {
Modified:
trunk/dna-graph/src/test/java/org/jboss/dna/graph/connector/test/WritableConnectorTest.java
===================================================================
---
trunk/dna-graph/src/test/java/org/jboss/dna/graph/connector/test/WritableConnectorTest.java 2009-04-20
20:21:21 UTC (rev 841)
+++
trunk/dna-graph/src/test/java/org/jboss/dna/graph/connector/test/WritableConnectorTest.java 2009-04-22
08:49:23 UTC (rev 842)
@@ -105,9 +105,19 @@
@Test
public void shouldAddChildrenAndSettingProperties() {
-
graph.batch().set("propA").to("valueA").on("/").and().create("/a").with("propB",
"valueB").and("propC",
"valueC").and().create("/b").with("propD",
-
"valueD").and("propE",
-
"valueE").execute();
+ graph.batch()
+ .set("propA")
+ .to("valueA")
+ .on("/")
+ .and()
+ .create("/a")
+ .with("propB", "valueB")
+ .and("propC", "valueC")
+ .and()
+ .create("/b")
+ .with("propD", "valueD")
+ .and("propE", "valueE")
+ .execute();
// Now look up the root node ...
Node root = graph.getNodeAt("/");
assertThat(root, is(notNullValue()));
@@ -608,50 +618,54 @@
boolean batch = true;
createSubgraph(graph, initialPath, depth, numChildrenPerNode,
numPropertiesPerNode, batch, sw, System.out, null);
- // Create some references between nodes that aren't involved with the copy
...
-
graph.set("refProp").on("/node1").to(graph.getNodeAt("/node1/node3"));
-
graph.set("refProp").on("/node1/node1").to(graph.getNodeAt("/node3/node2"));
// will soon be /node3/node2[1]
+ if (source.getCapabilities().supportsReferences()) {
+ // Create some references between nodes that aren't involved with the
copy ...
+
graph.set("refProp").on("/node1").to(graph.getNodeAt("/node1/node3"));
+
graph.set("refProp").on("/node1/node1").to(graph.getNodeAt("/node3/node2"));
// will soon be /node3/node2[1]
- // Create some "inward" references from nodes that are NOT being copied
to nodes that are being copied ...
-
graph.set("refProp").on("/node1/node2").to(graph.getNodeAt("/node2/node2"));
-
graph.set("refProp").on("/node1/node3").to(graph.getNodeAt("/node2/node2"));
+ // Create some "inward" references from nodes that are NOT being
copied to nodes that are being copied ...
+
graph.set("refProp").on("/node1/node2").to(graph.getNodeAt("/node2/node2"));
+
graph.set("refProp").on("/node1/node3").to(graph.getNodeAt("/node2/node2"));
- // Create some "outward" references from nodes that are being copied to
nodes that are NOT being copied ...
-
graph.set("refProp").on("/node2/node1").to(graph.getNodeAt("/node1/node1"));
-
graph.set("refProp").on("/node2/node3").to(graph.getNodeAt("/node1/node2"));
+ // Create some "outward" references from nodes that are being
copied to nodes that are NOT being copied ...
+
graph.set("refProp").on("/node2/node1").to(graph.getNodeAt("/node1/node1"));
+
graph.set("refProp").on("/node2/node3").to(graph.getNodeAt("/node1/node2"));
- // Create some "internal" references between nodes that are being
copied ...
-
graph.set("refProp").on("/node2/node2").to(graph.getNodeAt("/node2/node2/node1"));
-
graph.set("refProp").on("/node2/node3/node1").to(graph.getNodeAt("/node2/node2/node1"));
+ // Create some "internal" references between nodes that are being
copied ...
+
graph.set("refProp").on("/node2/node2").to(graph.getNodeAt("/node2/node2/node1"));
+
graph.set("refProp").on("/node2/node3/node1").to(graph.getNodeAt("/node2/node2/node1"));
- // Verify the references are there ...
- assertReference("/node1", "refProp",
"/node1/node3");
- assertReference("/node1/node1", "refProp",
"/node3/node2");
- assertReference("/node1/node2", "refProp",
"/node2/node2");
- assertReference("/node1/node3", "refProp",
"/node2/node2");
- assertReference("/node2/node1", "refProp",
"/node1/node1");
- assertReference("/node2/node3", "refProp",
"/node1/node2");
- assertReference("/node2/node2", "refProp",
"/node2/node2/node1");
- assertReference("/node2/node3/node1", "refProp",
"/node2/node2/node1");
+ // Verify the references are there ...
+ assertReference("/node1", "refProp",
"/node1/node3");
+ assertReference("/node1/node1", "refProp",
"/node3/node2");
+ assertReference("/node1/node2", "refProp",
"/node2/node2");
+ assertReference("/node1/node3", "refProp",
"/node2/node2");
+ assertReference("/node2/node1", "refProp",
"/node1/node1");
+ assertReference("/node2/node3", "refProp",
"/node1/node2");
+ assertReference("/node2/node2", "refProp",
"/node2/node2/node1");
+ assertReference("/node2/node3/node1", "refProp",
"/node2/node2/node1");
+ }
// Copy a branches ...
graph.copy("/node2").into("/node3");
- // Verify the references are still there ...
- assertReference("/node1", "refProp",
"/node1/node3");
- assertReference("/node1/node1", "refProp",
"/node3/node2[1]");
- assertReference("/node1/node2", "refProp",
"/node2/node2");
- assertReference("/node1/node3", "refProp",
"/node2/node2");
- assertReference("/node2/node1", "refProp",
"/node1/node1");
- assertReference("/node2/node3", "refProp",
"/node1/node2");
- assertReference("/node2/node2", "refProp",
"/node2/node2/node1");
- assertReference("/node2/node3/node1", "refProp",
"/node2/node2/node1");
+ if (source.getCapabilities().supportsReferences()) {
+ // Verify the references are still there ...
+ assertReference("/node1", "refProp",
"/node1/node3");
+ assertReference("/node1/node1", "refProp",
"/node3/node2[1]");
+ assertReference("/node1/node2", "refProp",
"/node2/node2");
+ assertReference("/node1/node3", "refProp",
"/node2/node2");
+ assertReference("/node2/node1", "refProp",
"/node1/node1");
+ assertReference("/node2/node3", "refProp",
"/node1/node2");
+ assertReference("/node2/node2", "refProp",
"/node2/node2/node1");
+ assertReference("/node2/node3/node1", "refProp",
"/node2/node2/node1");
- // And verify that we have a few new (outward and internal) references in the
copy ...
- assertReference("/node3/node2[2]/node1", "refProp",
"/node1/node1"); // outward
- assertReference("/node3/node2[2]/node3", "refProp",
"/node1/node2"); // outward
- assertReference("/node3/node2[2]/node2", "refProp",
"/node3/node2[2]/node2/node1"); // internal
- assertReference("/node3/node2[2]/node3/node1", "refProp",
"/node3/node2[2]/node2/node1"); // internal
+ // And verify that we have a few new (outward and internal) references in the
copy ...
+ assertReference("/node3/node2[2]/node1", "refProp",
"/node1/node1"); // outward
+ assertReference("/node3/node2[2]/node3", "refProp",
"/node1/node2"); // outward
+ assertReference("/node3/node2[2]/node2", "refProp",
"/node3/node2[2]/node2/node1"); // internal
+ assertReference("/node3/node2[2]/node3/node1", "refProp",
"/node3/node2[2]/node2/node1"); // internal
+ }
// Now assert the structure ...
assertThat(graph.getChildren().of("/node1"),
hasChildren(segment("node1"), segment("node2"),
segment("node3")));
@@ -730,9 +744,11 @@
"The quick
brown fox jumped over the moon. What? "));
assertThat(subgraph.getNode("node2[2]/node1/node3"),
hasProperty("property3",
"The quick
brown fox jumped over the moon. What? "));
- assertThat(subgraph.getNode("node2[2]/node2").getChildren(),
hasChildren(segment("node1"),
-
segment("node2"),
-
segment("node3")));
+ if (source.getCapabilities().supportsReferences()) {
+ assertThat(subgraph.getNode("node2[2]/node2").getChildren(),
hasChildren(segment("node1"),
+
segment("node2"),
+
segment("node3")));
+ }
assertThat(subgraph.getNode("node2[2]/node2"),
hasProperty("property1",
"The quick brown
fox jumped over the moon. What? "));
assertThat(subgraph.getNode("node2[2]/node2"),
hasProperty("property2",
@@ -760,9 +776,11 @@
"The quick
brown fox jumped over the moon. What? "));
assertThat(subgraph.getNode("node2[2]/node2/node3"),
hasProperty("property3",
"The quick
brown fox jumped over the moon. What? "));
- assertThat(subgraph.getNode("node2[2]/node3").getChildren(),
hasChildren(segment("node1"),
-
segment("node2"),
-
segment("node3")));
+ if (source.getCapabilities().supportsReferences()) {
+ assertThat(subgraph.getNode("node2[2]/node3").getChildren(),
hasChildren(segment("node1"),
+
segment("node2"),
+
segment("node3")));
+ }
assertThat(subgraph.getNode("node2[2]/node3"),
hasProperty("property1",
"The quick brown
fox jumped over the moon. What? "));
assertThat(subgraph.getNode("node2[2]/node3"),
hasProperty("property2",
@@ -805,4 +823,567 @@
}
}
+ @Test
+ public void shouldMoveNodes() {
+ // Create the tree (at total of 40 nodes, plus the extra 6 added later)...
+ // /
+ // /node1
+ // /node1/node1
+ // /node1/node1/node1
+ // /node1/node1/node2
+ // /node1/node1/node3
+ // /node1/node2
+ // /node1/node2/node1
+ // /node1/node2/node2
+ // /node1/node2/node3
+ // /node1/node3
+ // /node1/node3/node1
+ // /node1/node3/node2
+ // /node1/node3/node3
+ // /node2
+ // /node2/node1
+ // /node2/node1/node1
+ // /node2/node1/node2
+ // /node2/node1/node3
+ // /node2/node2
+ // /node2/node2/node1
+ // /node2/node2/node2
+ // /node2/node2/node3
+ // /node2/node3
+ // /node2/node3/node1
+ // /node2/node3/node2
+ // /node2/node3/node3
+ // /node3
+ // /node3/node1
+ // /node3/node1/node1
+ // /node3/node1/node2
+ // /node3/node1/node3
+ // /node3/node2
+ // /node3/node2/node1
+ // /node3/node2/node2
+ // /node3/node2/node3
+ // /node3/node3
+ // /node3/node3/node1
+ // /node3/node3/node2
+ // /node3/node3/node3
+ // /secondBranch1
+ // /secondBranch1/secondBranch1
+ // /secondBranch1/secondBranch2
+ // /secondBranch2
+ // /secondBranch2/secondBranch1
+ // /secondBranch2/secondBranch2
+
+ String initialPath = "";
+ int depth = 3;
+ int numChildrenPerNode = 3;
+ int numPropertiesPerNode = 3;
+ Stopwatch sw = new Stopwatch();
+ boolean batch = true;
+ createSubgraph(graph, initialPath, depth, numChildrenPerNode,
numPropertiesPerNode, batch, sw, System.out, null);
+
+ // Delete two branches ...
+ graph.move("/node2").into("/node3");
+
+ // Now assert the structure ...
+ assertThat(graph.getChildren().of("/node1"),
hasChildren(segment("node1"), segment("node2"),
segment("node3")));
+ assertThat(graph.getChildren().of("/node1/node1"),
hasChildren(segment("node1"), segment("node2"),
segment("node3")));
+ assertThat(graph.getChildren().of("/node1/node2"),
hasChildren(segment("node1"), segment("node2"),
segment("node3")));
+ assertThat(graph.getChildren().of("/node1/node3"),
hasChildren(segment("node1"), segment("node2"),
segment("node3")));
+ assertThat(graph.getChildren().of("/node1/node3/node1"),
hasChildren());
+
+ assertThat(graph.getChildren().of("/node3"),
hasChildren(segment("node1"),
+
segment("node2"),
+
segment("node3"),
+
segment("node2[2]")));
+ assertThat(graph.getChildren().of("/node3/node2"),
hasChildren(segment("node1"), segment("node2"),
segment("node3")));
+ assertThat(graph.getChildren().of("/node3/node3"),
hasChildren(segment("node1"), segment("node2"),
segment("node3")));
+ assertThat(graph.getChildren().of("/node3/node3/node1"),
hasChildren());
+ assertThat(graph.getChildren().of("/node3/node2[2]"),
hasChildren(segment("node1"), segment("node2"),
segment("node3")));
+ assertThat(graph.getChildren().of("/node3/node2[2]/node1"),
hasChildren(segment("node1"),
+
segment("node2"),
+
segment("node3")));
+ assertThat(graph.getChildren().of("/node3/node2[2]/node2"),
hasChildren(segment("node1"),
+
segment("node2"),
+
segment("node3")));
+ assertThat(graph.getChildren().of("/node3/node2[2]/node3"),
hasChildren(segment("node1"),
+
segment("node2"),
+
segment("node3")));
+ assertThat(graph.getChildren().of("/node3/node2[2]/node1/node1"),
hasChildren());
+
+ Subgraph subgraph = graph.getSubgraphOfDepth(4).at("/node3");
+ assertThat(subgraph, is(notNullValue()));
+ assertThat(subgraph.getNode(".").getChildren(),
hasChildren(segment("node2"), segment("node3")));
+ assertThat(subgraph.getNode("."), hasProperty("property1",
"The quick brown fox jumped over the moon. What? "));
+ assertThat(subgraph.getNode("."), hasProperty("property2",
"The quick brown fox jumped over the moon. What? "));
+ assertThat(subgraph.getNode("."), hasProperty("property3",
"The quick brown fox jumped over the moon. What? "));
+ assertThat(subgraph.getNode("node2[1]").getChildren(),
hasChildren(segment("node1"), segment("node2"),
segment("node3")));
+ assertThat(subgraph.getNode("node2[1]"),
hasProperty("property1", "The quick brown fox jumped over the moon. What?
"));
+ assertThat(subgraph.getNode("node2[1]"),
hasProperty("property2", "The quick brown fox jumped over the moon. What?
"));
+ assertThat(subgraph.getNode("node2[1]"),
hasProperty("property3", "The quick brown fox jumped over the moon. What?
"));
+ assertThat(subgraph.getNode("node3").getChildren(), isEmpty());
+ assertThat(subgraph.getNode("node3"),
hasProperty("property1", "The quick brown fox jumped over the moon. What?
"));
+ assertThat(subgraph.getNode("node3"),
hasProperty("property2", "The quick brown fox jumped over the moon. What?
"));
+ assertThat(subgraph.getNode("node3"),
hasProperty("property3", "The quick brown fox jumped over the moon. What?
"));
+ assertThat(subgraph.getNode("node2[2]").getChildren(),
hasChildren(segment("node1"), segment("node2"),
segment("node3")));
+ assertThat(subgraph.getNode("node2[2]"),
hasProperty("property1", "The quick brown fox jumped over the moon. What?
"));
+ assertThat(subgraph.getNode("node2[2]"),
hasProperty("property2", "The quick brown fox jumped over the moon. What?
"));
+ assertThat(subgraph.getNode("node2[2]"),
hasProperty("property3", "The quick brown fox jumped over the moon. What?
"));
+ assertThat(subgraph.getNode("node2[2]/node1").getChildren(),
hasChildren(segment("node1"),
+
segment("node2"),
+
segment("node3")));
+ assertThat(subgraph.getNode("node2[2]/node1"),
hasProperty("property1",
+ "The quick brown
fox jumped over the moon. What? "));
+ assertThat(subgraph.getNode("node2[2]/node1"),
hasProperty("property2",
+ "The quick brown
fox jumped over the moon. What? "));
+ assertThat(subgraph.getNode("node2[2]/node1"),
hasProperty("property3",
+ "The quick brown
fox jumped over the moon. What? "));
+ assertThat(subgraph.getNode("node2[2]/node1/node1").getChildren(),
isEmpty());
+ assertThat(subgraph.getNode("node2[2]/node1/node1"),
hasProperty("property1",
+ "The quick
brown fox jumped over the moon. What? "));
+ assertThat(subgraph.getNode("node2[2]/node1/node1"),
hasProperty("property2",
+ "The quick
brown fox jumped over the moon. What? "));
+ assertThat(subgraph.getNode("node2[2]/node1/node1"),
hasProperty("property3",
+ "The quick
brown fox jumped over the moon. What? "));
+ assertThat(subgraph.getNode("node2[2]/node1/node2").getChildren(),
isEmpty());
+ assertThat(subgraph.getNode("node2[2]/node1/node2"),
hasProperty("property1",
+ "The quick
brown fox jumped over the moon. What? "));
+ assertThat(subgraph.getNode("node2[2]/node1/node2"),
hasProperty("property2",
+ "The quick
brown fox jumped over the moon. What? "));
+ assertThat(subgraph.getNode("node2[2]/node1/node2"),
hasProperty("property3",
+ "The quick
brown fox jumped over the moon. What? "));
+ assertThat(subgraph.getNode("node2[2]/node1/node3").getChildren(),
isEmpty());
+ assertThat(subgraph.getNode("node2[2]/node1/node3"),
hasProperty("property1",
+ "The quick
brown fox jumped over the moon. What? "));
+ assertThat(subgraph.getNode("node2[2]/node1/node3"),
hasProperty("property2",
+ "The quick
brown fox jumped over the moon. What? "));
+ assertThat(subgraph.getNode("node2[2]/node1/node3"),
hasProperty("property3",
+ "The quick
brown fox jumped over the moon. What? "));
+ assertThat(subgraph.getNode("node2[2]/node2"),
hasProperty("property1",
+ "The quick brown
fox jumped over the moon. What? "));
+ assertThat(subgraph.getNode("node2[2]/node2"),
hasProperty("property2",
+ "The quick brown
fox jumped over the moon. What? "));
+ assertThat(subgraph.getNode("node2[2]/node2"),
hasProperty("property3",
+ "The quick brown
fox jumped over the moon. What? "));
+ assertThat(subgraph.getNode("node2[2]/node2/node1").getChildren(),
isEmpty());
+ assertThat(subgraph.getNode("node2[2]/node2/node1"),
hasProperty("property1",
+ "The quick
brown fox jumped over the moon. What? "));
+ assertThat(subgraph.getNode("node2[2]/node2/node1"),
hasProperty("property2",
+ "The quick
brown fox jumped over the moon. What? "));
+ assertThat(subgraph.getNode("node2[2]/node2/node1"),
hasProperty("property3",
+ "The quick
brown fox jumped over the moon. What? "));
+ assertThat(subgraph.getNode("node2[2]/node2/node2").getChildren(),
isEmpty());
+ assertThat(subgraph.getNode("node2[2]/node2/node2"),
hasProperty("property1",
+ "The quick
brown fox jumped over the moon. What? "));
+ assertThat(subgraph.getNode("node2[2]/node2/node2"),
hasProperty("property2",
+ "The quick
brown fox jumped over the moon. What? "));
+ assertThat(subgraph.getNode("node2[2]/node2/node2"),
hasProperty("property3",
+ "The quick
brown fox jumped over the moon. What? "));
+ assertThat(subgraph.getNode("node2[2]/node2/node3").getChildren(),
isEmpty());
+ assertThat(subgraph.getNode("node2[2]/node2/node3"),
hasProperty("property1",
+ "The quick
brown fox jumped over the moon. What? "));
+ assertThat(subgraph.getNode("node2[2]/node2/node3"),
hasProperty("property2",
+ "The quick
brown fox jumped over the moon. What? "));
+ assertThat(subgraph.getNode("node2[2]/node2/node3"),
hasProperty("property3",
+ "The quick
brown fox jumped over the moon. What? "));
+ assertThat(subgraph.getNode("node2[2]/node3"),
hasProperty("property1",
+ "The quick brown
fox jumped over the moon. What? "));
+ assertThat(subgraph.getNode("node2[2]/node3"),
hasProperty("property2",
+ "The quick brown
fox jumped over the moon. What? "));
+ assertThat(subgraph.getNode("node2[2]/node3"),
hasProperty("property3",
+ "The quick brown
fox jumped over the moon. What? "));
+ assertThat(subgraph.getNode("node2[2]/node3/node1").getChildren(),
isEmpty());
+ assertThat(subgraph.getNode("node2[2]/node3/node1"),
hasProperty("property1",
+ "The quick
brown fox jumped over the moon. What? "));
+ assertThat(subgraph.getNode("node2[2]/node3/node1"),
hasProperty("property2",
+ "The quick
brown fox jumped over the moon. What? "));
+ assertThat(subgraph.getNode("node2[2]/node3/node1"),
hasProperty("property3",
+ "The quick
brown fox jumped over the moon. What? "));
+ assertThat(subgraph.getNode("node2[2]/node3/node2").getChildren(),
isEmpty());
+ assertThat(subgraph.getNode("node2[2]/node3/node2"),
hasProperty("property1",
+ "The quick
brown fox jumped over the moon. What? "));
+ assertThat(subgraph.getNode("node2[2]/node3/node2"),
hasProperty("property2",
+ "The quick
brown fox jumped over the moon. What? "));
+ assertThat(subgraph.getNode("node2[2]/node3/node2"),
hasProperty("property3",
+ "The quick
brown fox jumped over the moon. What? "));
+ assertThat(subgraph.getNode("node2[2]/node3/node3").getChildren(),
isEmpty());
+ assertThat(subgraph.getNode("node2[2]/node3/node3"),
hasProperty("property1",
+ "The quick
brown fox jumped over the moon. What? "));
+ assertThat(subgraph.getNode("node2[2]/node3/node3"),
hasProperty("property2",
+ "The quick
brown fox jumped over the moon. What? "));
+ assertThat(subgraph.getNode("node2[2]/node3/node3"),
hasProperty("property3",
+ "The quick
brown fox jumped over the moon. What? "));
+ }
+
+ @Test
+ public void shouldMoveAndRenameNodes() {
+ // Create the tree (at total of 40 nodes, plus the extra 6 added later)...
+ // /
+ // /node1
+ // /node1/node1
+ // /node1/node1/node1
+ // /node1/node1/node2
+ // /node1/node1/node3
+ // /node1/node2
+ // /node1/node2/node1
+ // /node1/node2/node2
+ // /node1/node2/node3
+ // /node1/node3
+ // /node1/node3/node1
+ // /node1/node3/node2
+ // /node1/node3/node3
+ // /node2
+ // /node2/node1
+ // /node2/node1/node1
+ // /node2/node1/node2
+ // /node2/node1/node3
+ // /node2/node2
+ // /node2/node2/node1
+ // /node2/node2/node2
+ // /node2/node2/node3
+ // /node2/node3
+ // /node2/node3/node1
+ // /node2/node3/node2
+ // /node2/node3/node3
+ // /node3
+ // /node3/node1
+ // /node3/node1/node1
+ // /node3/node1/node2
+ // /node3/node1/node3
+ // /node3/node2
+ // /node3/node2/node1
+ // /node3/node2/node2
+ // /node3/node2/node3
+ // /node3/node3
+ // /node3/node3/node1
+ // /node3/node3/node2
+ // /node3/node3/node3
+ // /secondBranch1
+ // /secondBranch1/secondBranch1
+ // /secondBranch1/secondBranch2
+ // /secondBranch2
+ // /secondBranch2/secondBranch1
+ // /secondBranch2/secondBranch2
+
+ String initialPath = "";
+ int depth = 3;
+ int numChildrenPerNode = 3;
+ int numPropertiesPerNode = 3;
+ Stopwatch sw = new Stopwatch();
+ boolean batch = true;
+ createSubgraph(graph, initialPath, depth, numChildrenPerNode,
numPropertiesPerNode, batch, sw, System.out, null);
+
+ // Delete two branches ...
+ graph.move("/node2").as("node3").into("/node3");
+
+ // Now assert the structure ...
+ assertThat(graph.getChildren().of("/"),
hasChildren(segment("node1"), segment("node3")));
+ assertThat(graph.getChildren().of("/node1"),
hasChildren(segment("node1"), segment("node2"),
segment("node3")));
+ assertThat(graph.getChildren().of("/node1/node1"),
hasChildren(segment("node1"), segment("node2"),
segment("node3")));
+ assertThat(graph.getChildren().of("/node1/node2"),
hasChildren(segment("node1"), segment("node2"),
segment("node3")));
+ assertThat(graph.getChildren().of("/node1/node3"),
hasChildren(segment("node1"), segment("node2"),
segment("node3")));
+ assertThat(graph.getChildren().of("/node1/node3/node1"),
hasChildren());
+
+ assertThat(graph.getChildren().of("/node3"),
hasChildren(segment("node1"),
+
segment("node2"),
+
segment("node3"),
+
segment("node3[2]")));
+ assertThat(graph.getChildren().of("/node3/node2"),
hasChildren(segment("node1"), segment("node2"),
segment("node3")));
+ assertThat(graph.getChildren().of("/node3/node3"),
hasChildren(segment("node1"), segment("node2"),
segment("node3")));
+ assertThat(graph.getChildren().of("/node3/node3/node1"),
hasChildren());
+ assertThat(graph.getChildren().of("/node3/node3[2]"),
hasChildren(segment("node1"), segment("node2"),
segment("node3")));
+ assertThat(graph.getChildren().of("/node3/node3[2]/node1"),
hasChildren(segment("node1"),
+
segment("node2"),
+
segment("node3")));
+ assertThat(graph.getChildren().of("/node3/node3[2]/node2"),
hasChildren(segment("node1"),
+
segment("node2"),
+
segment("node3")));
+ assertThat(graph.getChildren().of("/node3/node3[2]/node3"),
hasChildren(segment("node1"),
+
segment("node2"),
+
segment("node3")));
+ assertThat(graph.getChildren().of("/node3/node3[2]/node1/node1"),
hasChildren());
+
+ Subgraph subgraph = graph.getSubgraphOfDepth(4).at("/node3");
+ assertThat(subgraph, is(notNullValue()));
+ assertThat(subgraph.getNode(".").getChildren(),
hasChildren(segment("node2"), segment("node3")));
+ assertThat(subgraph.getNode("."), hasProperty("property1",
"The quick brown fox jumped over the moon. What? "));
+ assertThat(subgraph.getNode("."), hasProperty("property2",
"The quick brown fox jumped over the moon. What? "));
+ assertThat(subgraph.getNode("."), hasProperty("property3",
"The quick brown fox jumped over the moon. What? "));
+ assertThat(subgraph.getNode("node2[1]").getChildren(),
hasChildren(segment("node1"), segment("node2"),
segment("node3")));
+ assertThat(subgraph.getNode("node2[1]"),
hasProperty("property1", "The quick brown fox jumped over the moon. What?
"));
+ assertThat(subgraph.getNode("node2[1]"),
hasProperty("property2", "The quick brown fox jumped over the moon. What?
"));
+ assertThat(subgraph.getNode("node2[1]"),
hasProperty("property3", "The quick brown fox jumped over the moon. What?
"));
+ assertThat(subgraph.getNode("node3").getChildren(), isEmpty());
+ assertThat(subgraph.getNode("node3"),
hasProperty("property1", "The quick brown fox jumped over the moon. What?
"));
+ assertThat(subgraph.getNode("node3"),
hasProperty("property2", "The quick brown fox jumped over the moon. What?
"));
+ assertThat(subgraph.getNode("node3"),
hasProperty("property3", "The quick brown fox jumped over the moon. What?
"));
+ assertThat(subgraph.getNode("node3[2]").getChildren(),
hasChildren(segment("node1"), segment("node2"),
segment("node3")));
+ assertThat(subgraph.getNode("node3[2]"),
hasProperty("property1", "The quick brown fox jumped over the moon. What?
"));
+ assertThat(subgraph.getNode("node3[2]"),
hasProperty("property2", "The quick brown fox jumped over the moon. What?
"));
+ assertThat(subgraph.getNode("node3[2]"),
hasProperty("property3", "The quick brown fox jumped over the moon. What?
"));
+ assertThat(subgraph.getNode("node3[2]/node1").getChildren(),
hasChildren(segment("node1"),
+
segment("node2"),
+
segment("node3")));
+ assertThat(subgraph.getNode("node3[2]/node1"),
hasProperty("property1",
+ "The quick brown
fox jumped over the moon. What? "));
+ assertThat(subgraph.getNode("node3[2]/node1"),
hasProperty("property2",
+ "The quick brown
fox jumped over the moon. What? "));
+ assertThat(subgraph.getNode("node3[2]/node1"),
hasProperty("property3",
+ "The quick brown
fox jumped over the moon. What? "));
+ assertThat(subgraph.getNode("node3[2]/node1/node1").getChildren(),
isEmpty());
+ assertThat(subgraph.getNode("node3[2]/node1/node1"),
hasProperty("property1",
+ "The quick
brown fox jumped over the moon. What? "));
+ assertThat(subgraph.getNode("node3[2]/node1/node1"),
hasProperty("property2",
+ "The quick
brown fox jumped over the moon. What? "));
+ assertThat(subgraph.getNode("node3[2]/node1/node1"),
hasProperty("property3",
+ "The quick
brown fox jumped over the moon. What? "));
+ assertThat(subgraph.getNode("node3[2]/node1/node2").getChildren(),
isEmpty());
+ assertThat(subgraph.getNode("node3[2]/node1/node2"),
hasProperty("property1",
+ "The quick
brown fox jumped over the moon. What? "));
+ assertThat(subgraph.getNode("node3[2]/node1/node2"),
hasProperty("property2",
+ "The quick
brown fox jumped over the moon. What? "));
+ assertThat(subgraph.getNode("node3[2]/node1/node2"),
hasProperty("property3",
+ "The quick
brown fox jumped over the moon. What? "));
+ assertThat(subgraph.getNode("node3[2]/node1/node3").getChildren(),
isEmpty());
+ assertThat(subgraph.getNode("node3[2]/node1/node3"),
hasProperty("property1",
+ "The quick
brown fox jumped over the moon. What? "));
+ assertThat(subgraph.getNode("node3[2]/node1/node3"),
hasProperty("property2",
+ "The quick
brown fox jumped over the moon. What? "));
+ assertThat(subgraph.getNode("node3[2]/node1/node3"),
hasProperty("property3",
+ "The quick
brown fox jumped over the moon. What? "));
+ assertThat(subgraph.getNode("node3[2]/node2"),
hasProperty("property1",
+ "The quick brown
fox jumped over the moon. What? "));
+ assertThat(subgraph.getNode("node3[2]/node2"),
hasProperty("property2",
+ "The quick brown
fox jumped over the moon. What? "));
+ assertThat(subgraph.getNode("node3[2]/node2"),
hasProperty("property3",
+ "The quick brown
fox jumped over the moon. What? "));
+ assertThat(subgraph.getNode("node3[2]/node2/node1").getChildren(),
isEmpty());
+ assertThat(subgraph.getNode("node3[2]/node2/node1"),
hasProperty("property1",
+ "The quick
brown fox jumped over the moon. What? "));
+ assertThat(subgraph.getNode("node3[2]/node2/node1"),
hasProperty("property2",
+ "The quick
brown fox jumped over the moon. What? "));
+ assertThat(subgraph.getNode("node3[2]/node2/node1"),
hasProperty("property3",
+ "The quick
brown fox jumped over the moon. What? "));
+ assertThat(subgraph.getNode("node3[2]/node2/node2").getChildren(),
isEmpty());
+ assertThat(subgraph.getNode("node3[2]/node2/node2"),
hasProperty("property1",
+ "The quick
brown fox jumped over the moon. What? "));
+ assertThat(subgraph.getNode("node3[2]/node2/node2"),
hasProperty("property2",
+ "The quick
brown fox jumped over the moon. What? "));
+ assertThat(subgraph.getNode("node3[2]/node2/node2"),
hasProperty("property3",
+ "The quick
brown fox jumped over the moon. What? "));
+ assertThat(subgraph.getNode("node3[2]/node2/node3").getChildren(),
isEmpty());
+ assertThat(subgraph.getNode("node3[2]/node2/node3"),
hasProperty("property1",
+ "The quick
brown fox jumped over the moon. What? "));
+ assertThat(subgraph.getNode("node3[2]/node2/node3"),
hasProperty("property2",
+ "The quick
brown fox jumped over the moon. What? "));
+ assertThat(subgraph.getNode("node3[2]/node2/node3"),
hasProperty("property3",
+ "The quick
brown fox jumped over the moon. What? "));
+ assertThat(subgraph.getNode("node3[2]/node3"),
hasProperty("property1",
+ "The quick brown
fox jumped over the moon. What? "));
+ assertThat(subgraph.getNode("node3[2]/node3"),
hasProperty("property2",
+ "The quick brown
fox jumped over the moon. What? "));
+ assertThat(subgraph.getNode("node3[2]/node3"),
hasProperty("property3",
+ "The quick brown
fox jumped over the moon. What? "));
+ assertThat(subgraph.getNode("node3[2]/node3/node1").getChildren(),
isEmpty());
+ assertThat(subgraph.getNode("node3[2]/node3/node1"),
hasProperty("property1",
+ "The quick
brown fox jumped over the moon. What? "));
+ assertThat(subgraph.getNode("node3[2]/node3/node1"),
hasProperty("property2",
+ "The quick
brown fox jumped over the moon. What? "));
+ assertThat(subgraph.getNode("node3[2]/node3/node1"),
hasProperty("property3",
+ "The quick
brown fox jumped over the moon. What? "));
+ assertThat(subgraph.getNode("node3[2]/node3/node2").getChildren(),
isEmpty());
+ assertThat(subgraph.getNode("node3[2]/node3/node2"),
hasProperty("property1",
+ "The quick
brown fox jumped over the moon. What? "));
+ assertThat(subgraph.getNode("node3[2]/node3/node2"),
hasProperty("property2",
+ "The quick
brown fox jumped over the moon. What? "));
+ assertThat(subgraph.getNode("node3[2]/node3/node2"),
hasProperty("property3",
+ "The quick
brown fox jumped over the moon. What? "));
+ assertThat(subgraph.getNode("node3[2]/node3/node3").getChildren(),
isEmpty());
+ assertThat(subgraph.getNode("node3[2]/node3/node3"),
hasProperty("property1",
+ "The quick
brown fox jumped over the moon. What? "));
+ assertThat(subgraph.getNode("node3[2]/node3/node3"),
hasProperty("property2",
+ "The quick
brown fox jumped over the moon. What? "));
+ assertThat(subgraph.getNode("node3[2]/node3/node3"),
hasProperty("property3",
+ "The quick
brown fox jumped over the moon. What? "));
+ }
+
+ @Test
+ public void shouldMoveAndRenameNodesToNameWithoutSameNameSibling() {
+ // Create the tree (at total of 40 nodes, plus the extra 6 added later)...
+ // /
+ // /node1
+ // /node1/node1
+ // /node1/node1/node1
+ // /node1/node1/node2
+ // /node1/node1/node3
+ // /node1/node2
+ // /node1/node2/node1
+ // /node1/node2/node2
+ // /node1/node2/node3
+ // /node1/node3
+ // /node1/node3/node1
+ // /node1/node3/node2
+ // /node1/node3/node3
+ // /node2
+ // /node2/node1
+ // /node2/node1/node1
+ // /node2/node1/node2
+ // /node2/node1/node3
+ // /node2/node2
+ // /node2/node2/node1
+ // /node2/node2/node2
+ // /node2/node2/node3
+ // /node2/node3
+ // /node2/node3/node1
+ // /node2/node3/node2
+ // /node2/node3/node3
+ // /node3
+ // /node3/node1
+ // /node3/node1/node1
+ // /node3/node1/node2
+ // /node3/node1/node3
+ // /node3/node2
+ // /node3/node2/node1
+ // /node3/node2/node2
+ // /node3/node2/node3
+ // /node3/node3
+ // /node3/node3/node1
+ // /node3/node3/node2
+ // /node3/node3/node3
+ // /secondBranch1
+ // /secondBranch1/secondBranch1
+ // /secondBranch1/secondBranch2
+ // /secondBranch2
+ // /secondBranch2/secondBranch1
+ // /secondBranch2/secondBranch2
+
+ String initialPath = "";
+ int depth = 3;
+ int numChildrenPerNode = 3;
+ int numPropertiesPerNode = 3;
+ Stopwatch sw = new Stopwatch();
+ boolean batch = true;
+ createSubgraph(graph, initialPath, depth, numChildrenPerNode,
numPropertiesPerNode, batch, sw, System.out, null);
+
+ // Delete two branches ...
+ graph.move("/node2").as("nodeX").into("/node3");
+
+ // Now assert the structure ...
+ assertThat(graph.getChildren().of("/"),
hasChildren(segment("node1"), segment("node3")));
+ assertThat(graph.getChildren().of("/node1"),
hasChildren(segment("node1"), segment("node2"),
segment("node3")));
+ assertThat(graph.getChildren().of("/node1/node1"),
hasChildren(segment("node1"), segment("node2"),
segment("node3")));
+ assertThat(graph.getChildren().of("/node1/node2"),
hasChildren(segment("node1"), segment("node2"),
segment("node3")));
+ assertThat(graph.getChildren().of("/node1/node3"),
hasChildren(segment("node1"), segment("node2"),
segment("node3")));
+ assertThat(graph.getChildren().of("/node1/node3/node1"),
hasChildren());
+
+ assertThat(graph.getChildren().of("/node3"),
hasChildren(segment("node1"),
+
segment("node2"),
+
segment("node3"),
+
segment("nodeX")));
+ assertThat(graph.getChildren().of("/node3/node2"),
hasChildren(segment("node1"), segment("node2"),
segment("node3")));
+ assertThat(graph.getChildren().of("/node3/node3"),
hasChildren(segment("node1"), segment("node2"),
segment("node3")));
+ assertThat(graph.getChildren().of("/node3/node3/node1"),
hasChildren());
+ assertThat(graph.getChildren().of("/node3/nodeX"),
hasChildren(segment("node1"), segment("node2"),
segment("node3")));
+ assertThat(graph.getChildren().of("/node3/nodeX/node1"),
+ hasChildren(segment("node1"), segment("node2"),
segment("node3")));
+ assertThat(graph.getChildren().of("/node3/nodeX/node2"),
+ hasChildren(segment("node1"), segment("node2"),
segment("node3")));
+ assertThat(graph.getChildren().of("/node3/nodeX/node3"),
+ hasChildren(segment("node1"), segment("node2"),
segment("node3")));
+ assertThat(graph.getChildren().of("/node3/nodeX/node1/node1"),
hasChildren());
+
+ Subgraph subgraph = graph.getSubgraphOfDepth(4).at("/node3");
+ assertThat(subgraph, is(notNullValue()));
+ assertThat(subgraph.getNode(".").getChildren(),
hasChildren(segment("node2"), segment("node3")));
+ assertThat(subgraph.getNode("."), hasProperty("property1",
"The quick brown fox jumped over the moon. What? "));
+ assertThat(subgraph.getNode("."), hasProperty("property2",
"The quick brown fox jumped over the moon. What? "));
+ assertThat(subgraph.getNode("."), hasProperty("property3",
"The quick brown fox jumped over the moon. What? "));
+ assertThat(subgraph.getNode("node2[1]").getChildren(),
hasChildren(segment("node1"), segment("node2"),
segment("node3")));
+ assertThat(subgraph.getNode("node2[1]"),
hasProperty("property1", "The quick brown fox jumped over the moon. What?
"));
+ assertThat(subgraph.getNode("node2[1]"),
hasProperty("property2", "The quick brown fox jumped over the moon. What?
"));
+ assertThat(subgraph.getNode("node2[1]"),
hasProperty("property3", "The quick brown fox jumped over the moon. What?
"));
+ assertThat(subgraph.getNode("node3").getChildren(), isEmpty());
+ assertThat(subgraph.getNode("node3"),
hasProperty("property1", "The quick brown fox jumped over the moon. What?
"));
+ assertThat(subgraph.getNode("node3"),
hasProperty("property2", "The quick brown fox jumped over the moon. What?
"));
+ assertThat(subgraph.getNode("node3"),
hasProperty("property3", "The quick brown fox jumped over the moon. What?
"));
+ assertThat(subgraph.getNode("nodeX").getChildren(),
hasChildren(segment("node1"), segment("node2"),
segment("node3")));
+ assertThat(subgraph.getNode("nodeX"),
hasProperty("property1", "The quick brown fox jumped over the moon. What?
"));
+ assertThat(subgraph.getNode("nodeX"),
hasProperty("property2", "The quick brown fox jumped over the moon. What?
"));
+ assertThat(subgraph.getNode("nodeX"),
hasProperty("property3", "The quick brown fox jumped over the moon. What?
"));
+ assertThat(subgraph.getNode("nodeX/node1").getChildren(),
hasChildren(segment("node1"),
+
segment("node2"),
+
segment("node3")));
+ assertThat(subgraph.getNode("nodeX/node1"),
hasProperty("property1", "The quick brown fox jumped over the moon. What?
"));
+ assertThat(subgraph.getNode("nodeX/node1"),
hasProperty("property2", "The quick brown fox jumped over the moon. What?
"));
+ assertThat(subgraph.getNode("nodeX/node1"),
hasProperty("property3", "The quick brown fox jumped over the moon. What?
"));
+ assertThat(subgraph.getNode("nodeX/node1/node1").getChildren(),
isEmpty());
+ assertThat(subgraph.getNode("nodeX/node1/node1"),
hasProperty("property1",
+ "The quick
brown fox jumped over the moon. What? "));
+ assertThat(subgraph.getNode("nodeX/node1/node1"),
hasProperty("property2",
+ "The quick
brown fox jumped over the moon. What? "));
+ assertThat(subgraph.getNode("nodeX/node1/node1"),
hasProperty("property3",
+ "The quick
brown fox jumped over the moon. What? "));
+ assertThat(subgraph.getNode("nodeX/node1/node2").getChildren(),
isEmpty());
+ assertThat(subgraph.getNode("nodeX/node1/node2"),
hasProperty("property1",
+ "The quick
brown fox jumped over the moon. What? "));
+ assertThat(subgraph.getNode("nodeX/node1/node2"),
hasProperty("property2",
+ "The quick
brown fox jumped over the moon. What? "));
+ assertThat(subgraph.getNode("nodeX/node1/node2"),
hasProperty("property3",
+ "The quick
brown fox jumped over the moon. What? "));
+ assertThat(subgraph.getNode("nodeX/node1/node3").getChildren(),
isEmpty());
+ assertThat(subgraph.getNode("nodeX/node1/node3"),
hasProperty("property1",
+ "The quick
brown fox jumped over the moon. What? "));
+ assertThat(subgraph.getNode("nodeX/node1/node3"),
hasProperty("property2",
+ "The quick
brown fox jumped over the moon. What? "));
+ assertThat(subgraph.getNode("nodeX/node1/node3"),
hasProperty("property3",
+ "The quick
brown fox jumped over the moon. What? "));
+ assertThat(subgraph.getNode("nodeX/node2"),
hasProperty("property1", "The quick brown fox jumped over the moon. What?
"));
+ assertThat(subgraph.getNode("nodeX/node2"),
hasProperty("property2", "The quick brown fox jumped over the moon. What?
"));
+ assertThat(subgraph.getNode("nodeX/node2"),
hasProperty("property3", "The quick brown fox jumped over the moon. What?
"));
+ assertThat(subgraph.getNode("nodeX/node2/node1").getChildren(),
isEmpty());
+ assertThat(subgraph.getNode("nodeX/node2/node1"),
hasProperty("property1",
+ "The quick
brown fox jumped over the moon. What? "));
+ assertThat(subgraph.getNode("nodeX/node2/node1"),
hasProperty("property2",
+ "The quick
brown fox jumped over the moon. What? "));
+ assertThat(subgraph.getNode("nodeX/node2/node1"),
hasProperty("property3",
+ "The quick
brown fox jumped over the moon. What? "));
+ assertThat(subgraph.getNode("nodeX/node2/node2").getChildren(),
isEmpty());
+ assertThat(subgraph.getNode("nodeX/node2/node2"),
hasProperty("property1",
+ "The quick
brown fox jumped over the moon. What? "));
+ assertThat(subgraph.getNode("nodeX/node2/node2"),
hasProperty("property2",
+ "The quick
brown fox jumped over the moon. What? "));
+ assertThat(subgraph.getNode("nodeX/node2/node2"),
hasProperty("property3",
+ "The quick
brown fox jumped over the moon. What? "));
+ assertThat(subgraph.getNode("nodeX/node2/node3").getChildren(),
isEmpty());
+ assertThat(subgraph.getNode("nodeX/node2/node3"),
hasProperty("property1",
+ "The quick
brown fox jumped over the moon. What? "));
+ assertThat(subgraph.getNode("nodeX/node2/node3"),
hasProperty("property2",
+ "The quick
brown fox jumped over the moon. What? "));
+ assertThat(subgraph.getNode("nodeX/node2/node3"),
hasProperty("property3",
+ "The quick
brown fox jumped over the moon. What? "));
+ assertThat(subgraph.getNode("nodeX/node3"),
hasProperty("property1", "The quick brown fox jumped over the moon. What?
"));
+ assertThat(subgraph.getNode("nodeX/node3"),
hasProperty("property2", "The quick brown fox jumped over the moon. What?
"));
+ assertThat(subgraph.getNode("nodeX/node3"),
hasProperty("property3", "The quick brown fox jumped over the moon. What?
"));
+ assertThat(subgraph.getNode("nodeX/node3/node1").getChildren(),
isEmpty());
+ assertThat(subgraph.getNode("nodeX/node3/node1"),
hasProperty("property1",
+ "The quick
brown fox jumped over the moon. What? "));
+ assertThat(subgraph.getNode("nodeX/node3/node1"),
hasProperty("property2",
+ "The quick
brown fox jumped over the moon. What? "));
+ assertThat(subgraph.getNode("nodeX/node3/node1"),
hasProperty("property3",
+ "The quick
brown fox jumped over the moon. What? "));
+ assertThat(subgraph.getNode("nodeX/node3/node2").getChildren(),
isEmpty());
+ assertThat(subgraph.getNode("nodeX/node3/node2"),
hasProperty("property1",
+ "The quick
brown fox jumped over the moon. What? "));
+ assertThat(subgraph.getNode("nodeX/node3/node2"),
hasProperty("property2",
+ "The quick
brown fox jumped over the moon. What? "));
+ assertThat(subgraph.getNode("nodeX/node3/node2"),
hasProperty("property3",
+ "The quick
brown fox jumped over the moon. What? "));
+ assertThat(subgraph.getNode("nodeX/node3/node3").getChildren(),
isEmpty());
+ assertThat(subgraph.getNode("nodeX/node3/node3"),
hasProperty("property1",
+ "The quick
brown fox jumped over the moon. What? "));
+ assertThat(subgraph.getNode("nodeX/node3/node3"),
hasProperty("property2",
+ "The quick
brown fox jumped over the moon. What? "));
+ assertThat(subgraph.getNode("nodeX/node3/node3"),
hasProperty("property3",
+ "The quick
brown fox jumped over the moon. What? "));
+ }
+
}
Modified:
trunk/extensions/dna-connector-filesystem/src/main/java/org/jboss/dna/connector/filesystem/FileSystemSource.java
===================================================================
---
trunk/extensions/dna-connector-filesystem/src/main/java/org/jboss/dna/connector/filesystem/FileSystemSource.java 2009-04-20
20:21:21 UTC (rev 841)
+++
trunk/extensions/dna-connector-filesystem/src/main/java/org/jboss/dna/connector/filesystem/FileSystemSource.java 2009-04-22
08:49:23 UTC (rev 842)
@@ -88,6 +88,11 @@
*/
public static final boolean DEFAULT_SUPPORTS_UPDATES = false;
+ /**
+ * This source supports creating references.
+ */
+ protected static final boolean SUPPORTS_REFERENCES = false;
+
public static final int DEFAULT_RETRY_LIMIT = 0;
public static final int DEFAULT_CACHE_TIME_TO_LIVE_IN_SECONDS = 60 * 5; // 5 minutes
@@ -96,10 +101,12 @@
private volatile int cacheTimeToLiveInMilliseconds =
DEFAULT_CACHE_TIME_TO_LIVE_IN_SECONDS * 1000;
private volatile String defaultWorkspace;
private volatile String[] predefinedWorkspaces = new String[] {};
- private volatile RepositorySourceCapabilities capabilities = new
RepositorySourceCapabilities(SUPPORTS_SAME_NAME_SIBLINGS,
+ private volatile RepositorySourceCapabilities capabilities = new
RepositorySourceCapabilities(
+
SUPPORTS_SAME_NAME_SIBLINGS,
DEFAULT_SUPPORTS_UPDATES,
SUPPORTS_EVENTS,
-
DEFAULT_SUPPORTS_CREATING_WORKSPACES);
+
DEFAULT_SUPPORTS_CREATING_WORKSPACES,
+
SUPPORTS_REFERENCES);
private transient CachePolicy cachePolicy;
private transient CopyOnWriteArraySet<String> availableWorkspaceNames;
@@ -236,7 +243,8 @@
*/
public synchronized void setCreatingWorkspacesAllowed( boolean allowWorkspaceCreation
) {
capabilities = new
RepositorySourceCapabilities(capabilities.supportsSameNameSiblings(),
capabilities.supportsUpdates(),
- capabilities.supportsEvents(),
allowWorkspaceCreation);
+ capabilities.supportsEvents(),
allowWorkspaceCreation,
+
capabilities.supportsReferences());
}
/**
Modified:
trunk/extensions/dna-connector-jbosscache/src/main/java/org/jboss/dna/connector/jbosscache/JBossCacheConnectorI18n.java
===================================================================
---
trunk/extensions/dna-connector-jbosscache/src/main/java/org/jboss/dna/connector/jbosscache/JBossCacheConnectorI18n.java 2009-04-20
20:21:21 UTC (rev 841)
+++
trunk/extensions/dna-connector-jbosscache/src/main/java/org/jboss/dna/connector/jbosscache/JBossCacheConnectorI18n.java 2009-04-22
08:49:23 UTC (rev 842)
@@ -39,6 +39,7 @@
public static I18n errorSerializingCachePolicyInSource;
public static I18n objectFoundInJndiWasNotCache;
public static I18n objectFoundInJndiWasNotCacheFactory;
+ public static I18n unableToDeleteBranch;
public static I18n unableToCloneWorkspaces;
public static I18n unableToCreateWorkspaces;
public static I18n unableToCreateWorkspace;
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-20
20:21:21 UTC (rev 841)
+++
trunk/extensions/dna-connector-jbosscache/src/main/java/org/jboss/dna/connector/jbosscache/JBossCacheRequestProcessor.java 2009-04-22
08:49:23 UTC (rev 842)
@@ -35,9 +35,11 @@
import org.jboss.cache.Cache;
import org.jboss.cache.Fqn;
import org.jboss.cache.Node;
+import org.jboss.dna.common.util.Logger;
import org.jboss.dna.graph.DnaLexicon;
import org.jboss.dna.graph.ExecutionContext;
import org.jboss.dna.graph.Location;
+import org.jboss.dna.graph.connector.RepositorySourceException;
import org.jboss.dna.graph.property.Name;
import org.jboss.dna.graph.property.Path;
import org.jboss.dna.graph.property.PathFactory;
@@ -256,8 +258,15 @@
Node<Name, Object> node = getNode(request, cache, nodePath);
if (node == null) return;
- node.getParent().removeChild(node.getFqn().getLastElement());
- request.setActualLocationOfNode(Location.create(nodePath));
+ Path.Segment nameOfRemovedNode = nodePath.getLastSegment();
+ Node<Name, Object> parent = node.getParent();
+ if (cache.removeNode(node.getFqn())) {
+ removeFromChildList(cache, parent, nameOfRemovedNode,
getExecutionContext());
+ request.setActualLocationOfNode(Location.create(nodePath));
+ } else {
+ String msg =
JBossCacheConnectorI18n.unableToDeleteBranch.text(getSourceName(), request.inWorkspace(),
nodePath);
+ request.setError(new RepositorySourceException(msg));
+ }
}
@Override
@@ -275,12 +284,15 @@
if (newParent == null) return;
// Copy the branch and use the same UUIDs ...
- Path.Segment newSegment = copyNode(cache, node, newParent, null, true, true,
null, null, getExecutionContext());
+ Name desiredName = request.desiredName();
+ Path.Segment newSegment = copyNode(cache, node, newParent, desiredName, true,
true, null, null, getExecutionContext());
// Now delete the old node ...
Node<Name, Object> oldParent = node.getParent();
boolean removed = oldParent.removeChild(node.getFqn().getLastElement());
assert removed;
+ Path.Segment nameOfRemovedNode = nodePath.getLastSegment();
+ removeFromChildList(cache, oldParent, nameOfRemovedNode, getExecutionContext());
Path newPath = pathFactory.create(newParentPath, newSegment);
request.setActualLocations(Location.create(nodePath), Location.create(newPath));
@@ -516,6 +528,7 @@
// Copy the properties ...
copy.clearData();
copy.putAll(original.getData());
+ copy.remove(JBossCacheLexicon.CHILD_PATH_SEGMENT_LIST); // will be reset later
...
// Generate a new UUID for the new node, overwriting any existing value from the
original ...
if (reuseOriginalUuids) uuidForCopyOfOriginal =
uuidFactory.create(original.get(DnaLexicon.UUID));
@@ -635,6 +648,63 @@
return null;
}
+ /**
+ * Update the array of {@link Path.Segment path segments} for the children of the
supplied node, based upon a node being
+ * removed. This array maintains the ordered list of children (since the {@link
Cache} does not maintain the order). Invoking
+ * this method will change any existing children that a {@link Path.Segment#getName()
name part} that matches the supplied
+ * <code>changedName</code> to have the appropriate {@link
Path.Segment#getIndex() same-name sibling index}.
+ *
+ * @param cache the cache in which the parent exists ...
+ * @param parent the parent node; may not be null
+ * @param removedNode the segment of the node that was removed, which signals to look
for node with the same name; may not be
+ * null
+ * @param context the execution context; may not be null
+ */
+ protected void removeFromChildList( Cache<Name, Object> cache,
+ Node<Name, Object> parent,
+ Path.Segment removedNode,
+ ExecutionContext context ) {
+ assert parent != null;
+ assert context != null;
+ Set<Node<Name, Object>> children = parent.getChildren();
+ if (children.isEmpty()) {
+ parent.put(JBossCacheLexicon.CHILD_PATH_SEGMENT_LIST, null); // replaces any
existing value
+ return;
+ }
+
+ // Go through the children, looking for any children with the same name as the
'changedName'
+ Path.Segment[] childNames =
(Path.Segment[])parent.get(JBossCacheLexicon.CHILD_PATH_SEGMENT_LIST);
+ assert childNames != null;
+ int snsIndex = removedNode.getIndex();
+ int index = 0;
+ Path.Segment[] newChildNames = new Path.Segment[childNames.length - 1];
+ for (Path.Segment childName : childNames) {
+ if (!childName.getName().equals(removedNode.getName())) {
+ newChildNames[index] = childName;
+ index++;
+ } else {
+ // The name matches ...
+ if (childName.getIndex() < snsIndex) {
+ // Just copy ...
+ newChildNames[index] = childName;
+ index++;
+ } else if (childName.getIndex() == snsIndex) {
+ // don't copy ...
+ } else {
+ // Append an updated segment ...
+ Path.Segment newSegment = context.getValueFactories()
+ .getPathFactory()
+ .createSegment(childName.getName(),
childName.getIndex() - 1);
+ newChildNames[index] = newSegment;
+ // Replace the child with the correct FQN ...
+ changeNodeName(cache, parent, childName, newSegment, context);
+ index++;
+ }
+ }
+ }
+ parent.put(JBossCacheLexicon.CHILD_PATH_SEGMENT_LIST, newChildNames); // replaces
any existing value
+ }
+
protected boolean checkChildren( Node<Name, Object> parent ) {
Path.Segment[] childNamesProperty =
(Path.Segment[])parent.get(JBossCacheLexicon.CHILD_PATH_SEGMENT_LIST);
Set<Object> childNames = parent.getChildrenNames();
@@ -649,10 +719,8 @@
names.add((Path.Segment)name);
}
Collections.sort(names);
- // Logger.getLogger(getClass()).trace("Child list on {0} is: {1}",
- // parent.getFqn(),
- // StringUtil.readableString(childNamesProperty));
- // Logger.getLogger(getClass()).trace("Children of {0} is: {1}",
parent.getFqn(), StringUtil.readableString(names));
+ Logger.getLogger(getClass()).trace("Child list on {0} is: {1}",
parent.getFqn(), childNamesProperty);
+ Logger.getLogger(getClass()).trace("Children of {0} is: {1}",
parent.getFqn(), names);
}
return result;
}
Modified:
trunk/extensions/dna-connector-jbosscache/src/main/java/org/jboss/dna/connector/jbosscache/JBossCacheSource.java
===================================================================
---
trunk/extensions/dna-connector-jbosscache/src/main/java/org/jboss/dna/connector/jbosscache/JBossCacheSource.java 2009-04-20
20:21:21 UTC (rev 841)
+++
trunk/extensions/dna-connector-jbosscache/src/main/java/org/jboss/dna/connector/jbosscache/JBossCacheSource.java 2009-04-22
08:49:23 UTC (rev 842)
@@ -112,7 +112,7 @@
private volatile int retryLimit = DEFAULT_RETRY_LIMIT;
private volatile String defaultWorkspace;
private volatile String[] predefinedWorkspaces = new String[] {};
- private volatile RepositorySourceCapabilities capabilities = new
RepositorySourceCapabilities(true, true, false, true);
+ private volatile RepositorySourceCapabilities capabilities = new
RepositorySourceCapabilities(true, true, false, true, false);
private transient JBossCacheWorkspaces workspaces;
private transient Context jndiContext;
@@ -417,7 +417,8 @@
* @see #isCreatingWorkspacesAllowed()
*/
public synchronized void setCreatingWorkspacesAllowed( boolean allowWorkspaceCreation
) {
- capabilities = new RepositorySourceCapabilities(true,
capabilities.supportsUpdates(), false, allowWorkspaceCreation);
+ capabilities = new RepositorySourceCapabilities(true,
capabilities.supportsUpdates(), false, allowWorkspaceCreation,
+
capabilities.supportsReferences());
}
/**
Modified:
trunk/extensions/dna-connector-jbosscache/src/main/java/org/jboss/dna/connector/jbosscache/JBossCacheWorkspaces.java
===================================================================
---
trunk/extensions/dna-connector-jbosscache/src/main/java/org/jboss/dna/connector/jbosscache/JBossCacheWorkspaces.java 2009-04-20
20:21:21 UTC (rev 841)
+++
trunk/extensions/dna-connector-jbosscache/src/main/java/org/jboss/dna/connector/jbosscache/JBossCacheWorkspaces.java 2009-04-22
08:49:23 UTC (rev 842)
@@ -241,7 +241,7 @@
} catch (ConfigurationException error) {
// The workspace name is probably not the name of a configuration ...
I18n msg = JBossCacheConnectorI18n.workspaceNameWasNotValidConfiguration;
- Logger.getLogger(getClass()).info(msg, workspaceName, error.getMessage());
+ Logger.getLogger(getClass()).debug(msg.text(workspaceName,
error.getMessage()));
}
if (this.defaultCacheFactoryConfigurationName != null) {
@@ -253,7 +253,7 @@
if (this.workspaceNamesForConfigurationNameProblems.add(workspaceName))
{
// Log this problem only the first time ...
I18n msg =
JBossCacheConnectorI18n.defaultCacheFactoryConfigurationNameWasNotValidConfiguration;
- Logger.getLogger(getClass()).warn(msg, workspaceName);
+ Logger.getLogger(getClass()).debug(msg.text(workspaceName));
}
}
}
Modified:
trunk/extensions/dna-connector-jbosscache/src/main/resources/org/jboss/dna/connector/jbosscache/JBossCacheConnectorI18n.properties
===================================================================
---
trunk/extensions/dna-connector-jbosscache/src/main/resources/org/jboss/dna/connector/jbosscache/JBossCacheConnectorI18n.properties 2009-04-20
20:21:21 UTC (rev 841)
+++
trunk/extensions/dna-connector-jbosscache/src/main/resources/org/jboss/dna/connector/jbosscache/JBossCacheConnectorI18n.properties 2009-04-22
08:49:23 UTC (rev 842)
@@ -29,6 +29,7 @@
errorSerializingCachePolicyInSource = Error serializing a {0} instance owned by the {1}
JBossCacheSource
objectFoundInJndiWasNotCache = Object in JNDI at {0} found by JBossCacheSource {1} was
expected to be a org.jboss.cache.Cache<org.jboss.dna.graph.property.Name,Object> but
instead was {2}
objectFoundInJndiWasNotCacheFactory = Object in JNDI at {0} found by JBossCacheSource {1}
was expected to be a
org.jboss.cache.CacheFactory<org.jboss.dna.graph.property.Name,Object> but instead
was {2}
+unableToDeleteBranch = Error while deleting branch "{2}" from workspace
"{1}" in the JBossCacheSource {0}
unableToCloneWorkspaces = The JBossCacheSource {0} does not allow creating workspaces, so
unable to clone workspace "{1}" into "{2}"
unableToCreateWorkspaces = The JBossCacheSource {0} does not allow creating workspaces,
so unable to create workspace "{1}"
unableToCreateWorkspace = Unable to create new workspace "{1}" in the
JBossCacheSource {0}
Added:
trunk/extensions/dna-connector-jbosscache/src/test/java/org/jboss/dna/connector/jbosscache/JBossCacheConnectorWritableTest.java
===================================================================
---
trunk/extensions/dna-connector-jbosscache/src/test/java/org/jboss/dna/connector/jbosscache/JBossCacheConnectorWritableTest.java
(rev 0)
+++
trunk/extensions/dna-connector-jbosscache/src/test/java/org/jboss/dna/connector/jbosscache/JBossCacheConnectorWritableTest.java 2009-04-22
08:49:23 UTC (rev 842)
@@ -0,0 +1,79 @@
+/*
+ * 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.connector.jbosscache;
+
+import static org.mockito.Matchers.anyString;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.stub;
+import java.io.IOException;
+import javax.naming.Context;
+import javax.naming.NamingException;
+import org.jboss.dna.graph.Graph;
+import org.jboss.dna.graph.connector.RepositorySource;
+import org.jboss.dna.graph.connector.test.WritableConnectorTest;
+import org.xml.sax.SAXException;
+
+/**
+ * @author Randall Hauch
+ */
+public class JBossCacheConnectorWritableTest extends WritableConnectorTest {
+
+ private Context mockJndi;
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.jboss.dna.graph.connector.test.AbstractConnectorTest#setUpSource()
+ */
+ @Override
+ protected RepositorySource setUpSource() throws NamingException {
+ String[] predefinedWorkspaceNames = new String[] {"default"};
+ JBossCacheSource source = new JBossCacheSource();
+ source.setName("Test Repository");
+ source.setPredefinedWorkspaceNames(predefinedWorkspaceNames);
+ source.setNameOfDefaultWorkspace(predefinedWorkspaceNames[0]);
+ source.setCreatingWorkspacesAllowed(true);
+
+ // Set up the mock JNDI ...
+ mockJndi = mock(Context.class);
+ stub(mockJndi.lookup(anyString())).toReturn(null);
+ source.setContext(mockJndi);
+
+ Graph graph = Graph.create(source, context);
+ graph.useWorkspace("default");
+
+ return source;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @throws SAXException
+ * @throws IOException
+ * @see
org.jboss.dna.graph.connector.test.AbstractConnectorTest#initializeContent(org.jboss.dna.graph.Graph)
+ */
+ @Override
+ protected void initializeContent( Graph graph ) throws IOException, SAXException {
+ }
+}
Property changes on:
trunk/extensions/dna-connector-jbosscache/src/test/java/org/jboss/dna/connector/jbosscache/JBossCacheConnectorWritableTest.java
___________________________________________________________________
Name: svn:mime-type
+ text/plain
Modified:
trunk/extensions/dna-connector-store-jpa/src/main/java/org/jboss/dna/connector/store/jpa/JpaSource.java
===================================================================
---
trunk/extensions/dna-connector-store-jpa/src/main/java/org/jboss/dna/connector/store/jpa/JpaSource.java 2009-04-20
20:21:21 UTC (rev 841)
+++
trunk/extensions/dna-connector-store-jpa/src/main/java/org/jboss/dna/connector/store/jpa/JpaSource.java 2009-04-22
08:49:23 UTC (rev 842)
@@ -132,6 +132,10 @@
*/
protected static final boolean SUPPORTS_SAME_NAME_SIBLINGS = true;
/**
+ * This source supports creating references.
+ */
+ protected static final boolean SUPPORTS_REFERENCES = true;
+ /**
* This source supports udpates by default, but each instance may be configured to
{@link #setSupportsUpdates(boolean) be
* read-only or updateable}.
*/
@@ -191,10 +195,12 @@
private volatile boolean referentialIntegrityEnforced =
DEFAULT_ENFORCE_REFERENTIAL_INTEGRITY;
private volatile String defaultWorkspace = DEFAULT_NAME_OF_DEFAULT_WORKSPACE;
private volatile String[] predefinedWorkspaces = new String[] {};
- private volatile RepositorySourceCapabilities capabilities = new
RepositorySourceCapabilities(SUPPORTS_SAME_NAME_SIBLINGS,
+ private volatile RepositorySourceCapabilities capabilities = new
RepositorySourceCapabilities(
+
SUPPORTS_SAME_NAME_SIBLINGS,
DEFAULT_SUPPORTS_UPDATES,
SUPPORTS_EVENTS,
-
DEFAULT_SUPPORTS_CREATING_WORKSPACES);
+
DEFAULT_SUPPORTS_CREATING_WORKSPACES,
+
SUPPORTS_REFERENCES);
private volatile String modelName;
private transient Model model;
private transient DataSource dataSource;
@@ -251,7 +257,8 @@
*/
public synchronized void setSupportsUpdates( boolean supportsUpdates ) {
capabilities = new
RepositorySourceCapabilities(capabilities.supportsSameNameSiblings(), supportsUpdates,
- capabilities.supportsEvents(),
capabilities.supportsCreatingWorkspaces());
+ capabilities.supportsEvents(),
capabilities.supportsCreatingWorkspaces(),
+
capabilities.supportsReferences());
}
/**
@@ -379,7 +386,8 @@
*/
public synchronized void setCreatingWorkspacesAllowed( boolean allowWorkspaceCreation
) {
capabilities = new
RepositorySourceCapabilities(capabilities.supportsSameNameSiblings(),
capabilities.supportsUpdates(),
- capabilities.supportsEvents(),
allowWorkspaceCreation);
+ capabilities.supportsEvents(),
allowWorkspaceCreation,
+
capabilities.supportsReferences());
}
/**
@@ -848,7 +856,8 @@
Context context = new InitialContext();
dataSource = (DataSource)context.lookup(this.dataSourceJndiName);
} catch (Throwable t) {
- Logger.getLogger(getClass()).error(t,
JpaConnectorI18n.errorFindingDataSourceInJndi, name, dataSourceJndiName);
+ Logger.getLogger(getClass())
+ .error(t, JpaConnectorI18n.errorFindingDataSourceInJndi, name,
dataSourceJndiName);
}
}
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-20
20:21:21 UTC (rev 841)
+++
trunk/extensions/dna-connector-store-jpa/src/main/java/org/jboss/dna/connector/store/jpa/model/basic/BasicRequestProcessor.java 2009-04-22
08:49:23 UTC (rev 842)
@@ -1368,41 +1368,67 @@
// Now we know that the new parent is not the existing parent ...
final int oldIndex = fromEntity.getIndexInParent();
+ // Make sure the child name is set correctly ...
+ String childOldLocalName = fromEntity.getChildName();
+ String childLocalName = null;
+ NamespaceEntity ns = null;
+ Name childName = request.desiredName();
+ if (childName != null) {
+ childLocalName = request.desiredName().getLocalName();
+ String childNsUri = childName.getNamespaceUri();
+ ns = namespaces.get(childNsUri, true);
+ } else {
+ childName = oldPath.getLastSegment().getName();
+ childLocalName = fromEntity.getChildName();
+ ns = fromEntity.getChildNamespace();
+ }
+
// Find the largest SNS index in the existing ChildEntity objects
with the same name ...
- String childLocalName = fromEntity.getChildName();
- NamespaceEntity ns = fromEntity.getChildNamespace();
Query query =
entities.createNamedQuery("ChildEntity.findMaximumSnsIndex");
query.setParameter("workspaceId", workspaceId);
- query.setParameter("parentUuidString", toUuidString);
+ query.setParameter("parentUuid", toUuidString);
query.setParameter("ns", ns.getId());
query.setParameter("childName", childLocalName);
int nextSnsIndex = 1;
try {
- nextSnsIndex = (Integer)query.getSingleResult();
+ Integer index = (Integer)query.getSingleResult();
+ if (index != null) nextSnsIndex = index.intValue() + 1;
} catch (NoResultException e) {
}
// Find the largest child index in the existing ChildEntity objects
...
query =
entities.createNamedQuery("ChildEntity.findMaximumChildIndex");
query.setParameter("workspaceId", workspaceId);
- query.setParameter("parentUuidString", toUuidString);
+ query.setParameter("parentUuid", toUuidString);
int nextIndexInParent = 1;
try {
- nextIndexInParent = (Integer)query.getSingleResult() + 1;
+ Integer index = (Integer)query.getSingleResult();
+ if (index != null) nextIndexInParent = index + 1;
} catch (NoResultException e) {
}
- // Move the child entity to be under the new parent ...
- fromEntity.setId(new ChildId(workspaceId, toUuidString,
fromUuidString));
- fromEntity.setIndexInParent(nextIndexInParent);
- fromEntity.setSameNameSiblingIndex(nextSnsIndex);
+ ChildId movedId = new ChildId(workspaceId, toUuidString,
fromUuidString);
+ if (fromEntity.getId().equals(movedId)) {
+ // The node is being renamed, but not moved ...
+ fromEntity.setChildName(childLocalName);
+ fromEntity.setChildNamespace(ns);
+ fromEntity.setIndexInParent(nextIndexInParent);
+ fromEntity.setSameNameSiblingIndex(nextSnsIndex);
+ } else {
+ // We won't be able to move the entity to a different parent,
because that would involve
+ // changing the PK for the entity, which is not possible.
Instead, we have to create a
+ // new entity with the same identity information, then delete
'fromEntity'
+ ChildEntity movedEntity = new ChildEntity(movedId,
nextIndexInParent, ns, childLocalName, nextSnsIndex);
+
movedEntity.setAllowsSameNameChildren(fromEntity.getAllowsSameNameChildren());
+ entities.persist(movedEntity);
+ entities.remove(fromEntity);
+ }
// Flush the entities to the database ...
entities.flush();
// Determine the new location ...
Path newParentPath = actualIntoLocation.location.getPath();
- Name childName = oldPath.getLastSegment().getName();
Path newPath = pathFactory.create(newParentPath, childName,
nextSnsIndex);
actualNewLocation = actualOldLocation.with(newPath);
@@ -1410,7 +1436,7 @@
ChildEntity.adjustSnsIndexesAndIndexesAfterRemoving(entities,
workspaceId,
oldParentUuid,
- childLocalName,
+
childOldLocalName,
ns.getId(),
oldIndex);
Modified:
trunk/extensions/dna-connector-svn/src/main/java/org/jboss/dna/connector/svn/SVNRepositorySource.java
===================================================================
---
trunk/extensions/dna-connector-svn/src/main/java/org/jboss/dna/connector/svn/SVNRepositorySource.java 2009-04-20
20:21:21 UTC (rev 841)
+++
trunk/extensions/dna-connector-svn/src/main/java/org/jboss/dna/connector/svn/SVNRepositorySource.java 2009-04-22
08:49:23 UTC (rev 842)
@@ -89,6 +89,10 @@
*/
protected static final boolean SUPPORTS_CREATING_WORKSPACES = false;
/**
+ * This source supports creating references.
+ */
+ protected static final boolean SUPPORTS_REFERENCES = false;
+ /**
* This source supports udpates by default, but each instance may be configured to
{@link #setSupportsUpdates(boolean) be
* read-only or updateable}.
*/
@@ -115,7 +119,8 @@
private RepositorySourceCapabilities capabilities = new
RepositorySourceCapabilities(SUPPORTS_SAME_NAME_SIBLINGS,
DEFAULT_SUPPORTS_UPDATES,
SUPPORTS_EVENTS,
-
SUPPORTS_CREATING_WORKSPACES);
+
SUPPORTS_CREATING_WORKSPACES,
+
SUPPORTS_REFERENCES);
private transient Context jndiContext;
private transient RepositoryContext repositoryContext;
@@ -259,7 +264,8 @@
*/
public synchronized void setSupportsUpdates( boolean supportsUpdates ) {
capabilities = new
RepositorySourceCapabilities(capabilities.supportsSameNameSiblings(), supportsUpdates,
- capabilities.supportsEvents(),
capabilities.supportsCreatingWorkspaces());
+ capabilities.supportsEvents(),
capabilities.supportsCreatingWorkspaces(),
+
capabilities.supportsReferences());
}
/**