Author: rhauch
Date: 2009-05-15 15:28:48 -0400 (Fri, 15 May 2009)
New Revision: 910
Added:
trunk/dna-graph/src/main/java/org/jboss/dna/graph/request/DeleteChildrenRequest.java
Modified:
trunk/dna-graph/src/main/java/org/jboss/dna/graph/request/processor/RequestProcessor.java
trunk/extensions/dna-connector-store-jpa/src/main/java/org/jboss/dna/connector/store/jpa/model/basic/BasicRequestProcessor.java
Log:
DNA-409 Add to connector API ability to delete all nodes below a node
Added the DeleteChildrenRequest class and provided a default
process(DeleteChildrenRequest) method in RequestProcessor. Therefore, all connectors
immediately inherit this functionality. The JPA connector can implement this much more
efficiently than if it inherits the default implementation, so this connector was changed
to provide its own implementation.
Added:
trunk/dna-graph/src/main/java/org/jboss/dna/graph/request/DeleteChildrenRequest.java
===================================================================
--- trunk/dna-graph/src/main/java/org/jboss/dna/graph/request/DeleteChildrenRequest.java
(rev 0)
+++
trunk/dna-graph/src/main/java/org/jboss/dna/graph/request/DeleteChildrenRequest.java 2009-05-15
19:28:48 UTC (rev 910)
@@ -0,0 +1,159 @@
+/*
+ * JBoss DNA (
http://www.jboss.org/dna)
+ * See the COPYRIGHT.txt file distributed with this work for information
+ * regarding copyright ownership. Some portions may be licensed
+ * to Red Hat, Inc. under one or more contributor license agreements.
+ * See the AUTHORS.txt file in the distribution for a full listing of
+ * individual contributors.
+ *
+ * JBoss DNA is free software. Unless otherwise indicated, all code in JBoss DNA
+ * is licensed to you under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * JBoss DNA is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site:
http://www.fsf.org.
+ */
+package org.jboss.dna.graph.request;
+
+import org.jboss.dna.common.util.CheckArg;
+import org.jboss.dna.graph.GraphI18n;
+import org.jboss.dna.graph.Location;
+import org.jboss.dna.graph.property.Path;
+
+/**
+ * Instruction that all nodes below a supplied node be deleted. This is similar to {@link
DeleteBranchRequest}, except that the
+ * parent node (top node in the branch) is not deleted.
+ */
+public class DeleteChildrenRequest extends Request implements ChangeRequest {
+
+ private static final long serialVersionUID = 1L;
+
+ private final Location at;
+ private final String workspaceName;
+ private Location actualLocation;
+
+ /**
+ * Create a request to delete all children of the supplied node. The supplied parent
node will not be deleted.
+ *
+ * @param at the location of the parent node
+ * @param workspaceName the name of the workspace containing the parent
+ * @throws IllegalArgumentException if the location or workspace name is null
+ */
+ public DeleteChildrenRequest( Location at,
+ String workspaceName ) {
+ CheckArg.isNotNull(at, "at");
+ CheckArg.isNotNull(workspaceName, "workspaceName");
+ this.workspaceName = workspaceName;
+ this.at = at;
+ }
+
+ /**
+ * Get the location defining the top of the branch to be deleted
+ *
+ * @return the location of the branch; never null
+ */
+ public Location at() {
+ return at;
+ }
+
+ /**
+ * Get the name of the workspace in which the branch exists.
+ *
+ * @return the name of the workspace; never null
+ */
+ public String inWorkspace() {
+ return workspaceName;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.jboss.dna.graph.request.Request#isReadOnly()
+ */
+ @Override
+ public boolean isReadOnly() {
+ return false;
+ }
+
+ /**
+ * Sets the actual and complete location of the node being deleted. This method must
be called when processing the request,
+ * and the actual location must have a {@link Location#getPath() path}.
+ *
+ * @param actual the actual location of the node being deleted, or null if the {@link
#at() current location} should be used
+ * @throws IllegalArgumentException if the actual location does not represent the
{@link Location#isSame(Location) same
+ * location} as the {@link #at() current location}, or if the actual location
does not have a path.
+ */
+ public void setActualLocationOfNode( Location actual ) {
+ if (!at.isSame(actual)) { // not same if actual is null
+ throw new
IllegalArgumentException(GraphI18n.actualLocationIsNotSameAsInputLocation.text(actual,
at));
+ }
+ assert actual != null;
+ if (!actual.hasPath()) {
+ throw new
IllegalArgumentException(GraphI18n.actualLocationMustHavePath.text(actual));
+ }
+ this.actualLocation = actual;
+ }
+
+ /**
+ * Get the actual location of the node that was deleted.
+ *
+ * @return the actual location, or null if the actual location was not set
+ */
+ public Location getActualLocationOfNode() {
+ return actualLocation;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.jboss.dna.graph.request.ChangeRequest#changes(java.lang.String,
org.jboss.dna.graph.property.Path)
+ */
+ public boolean changes( String workspace,
+ Path path ) {
+ return this.workspaceName.equals(workspace) && at.hasPath() &&
at.getPath().isAtOrBelow(path);
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.jboss.dna.graph.request.ChangeRequest#changedLocation()
+ */
+ public Location changedLocation() {
+ return at;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see java.lang.Object#equals(java.lang.Object)
+ */
+ @Override
+ public boolean equals( Object obj ) {
+ if (obj == this) return true;
+ if (this.getClass().isInstance(obj)) {
+ DeleteChildrenRequest that = (DeleteChildrenRequest)obj;
+ if (!this.at().equals(that.at())) return false;
+ if (!this.inWorkspace().equals(that.inWorkspace())) return false;
+ return true;
+ }
+ return false;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see java.lang.Object#toString()
+ */
+ @Override
+ public String toString() {
+ return "delete nodes below " + at() + " in the \"" +
workspaceName + "\" workspace";
+ }
+}
Property changes on:
trunk/dna-graph/src/main/java/org/jboss/dna/graph/request/DeleteChildrenRequest.java
___________________________________________________________________
Name: svn:keywords
+ Id Revision
Name: svn:eol-style
+ LF
Modified:
trunk/dna-graph/src/main/java/org/jboss/dna/graph/request/processor/RequestProcessor.java
===================================================================
---
trunk/dna-graph/src/main/java/org/jboss/dna/graph/request/processor/RequestProcessor.java 2009-05-15
18:36:03 UTC (rev 909)
+++
trunk/dna-graph/src/main/java/org/jboss/dna/graph/request/processor/RequestProcessor.java 2009-05-15
19:28:48 UTC (rev 910)
@@ -47,6 +47,7 @@
import org.jboss.dna.graph.request.CreateNodeRequest;
import org.jboss.dna.graph.request.CreateWorkspaceRequest;
import org.jboss.dna.graph.request.DeleteBranchRequest;
+import org.jboss.dna.graph.request.DeleteChildrenRequest;
import org.jboss.dna.graph.request.DestroyWorkspaceRequest;
import org.jboss.dna.graph.request.GetWorkspacesRequest;
import org.jboss.dna.graph.request.InvalidRequestException;
@@ -352,6 +353,39 @@
public abstract void process( DeleteBranchRequest request );
/**
+ * Process a request to delete all of the child nodes under the supplied existing
node.
+ * <p>
+ * This method does nothing if the request is null.
+ * </p>
+ *
+ * @param request the delete request
+ * @throws ReferentialIntegrityException if the delete could not be performed because
some references to deleted nodes would
+ * have remained after the delete operation completed
+ */
+ public void process( DeleteChildrenRequest request ) {
+ if (request == null) return;
+ if (request.isCancelled()) return;
+ // First get all of the children under the node ...
+ ReadAllChildrenRequest readChildren = new ReadAllChildrenRequest(request.at(),
request.inWorkspace());
+ process(readChildren);
+ if (readChildren.hasError()) {
+ request.setError(readChildren.getError());
+ return;
+ }
+ if (readChildren.isCancelled()) return;
+
+ // Issue a DeleteBranchRequest for each child ...
+ for (Location child : readChildren) {
+ if (request.isCancelled()) return;
+ DeleteBranchRequest deleteChild = new DeleteBranchRequest(child,
request.inWorkspace());
+ process(deleteChild);
+ }
+
+ // Set the actual location of the parent node ...
+ request.setActualLocationOfNode(readChildren.getActualLocationOfNode());
+ }
+
+ /**
* Process a request to move a branch at a specified location into a different
location.
* <p>
* This method does nothing if the request is null.
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-05-15
18:36:03 UTC (rev 909)
+++
trunk/extensions/dna-connector-store-jpa/src/main/java/org/jboss/dna/connector/store/jpa/model/basic/BasicRequestProcessor.java 2009-05-15
19:28:48 UTC (rev 910)
@@ -85,6 +85,7 @@
import org.jboss.dna.graph.request.CreateNodeRequest;
import org.jboss.dna.graph.request.CreateWorkspaceRequest;
import org.jboss.dna.graph.request.DeleteBranchRequest;
+import org.jboss.dna.graph.request.DeleteChildrenRequest;
import org.jboss.dna.graph.request.DestroyWorkspaceRequest;
import org.jboss.dna.graph.request.GetWorkspacesRequest;
import org.jboss.dna.graph.request.InvalidRequestException;
@@ -1243,15 +1244,34 @@
@Override
public void process( DeleteBranchRequest request ) {
logger.trace(request.toString());
+ Location location = delete(request, request.at(), request.inWorkspace(), true);
+ if (location != null) request.setActualLocationOfNode(location);
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see
org.jboss.dna.graph.request.processor.RequestProcessor#process(org.jboss.dna.graph.request.DeleteChildrenRequest)
+ */
+ @Override
+ public void process( DeleteChildrenRequest request ) {
+ logger.trace(request.toString());
+ Location location = delete(request, request.at(), request.inWorkspace(), false);
+ if (location != null) request.setActualLocationOfNode(location);
+ }
+
+ protected Location delete( Request request,
+ Location location,
+ String workspaceName,
+ boolean deleteTopOfBranch ) {
Location actualLocation = null;
try {
// Find the workspace ...
- WorkspaceEntity workspace = getExistingWorkspace(request.inWorkspace(),
request);
- if (workspace == null) return;
+ WorkspaceEntity workspace = getExistingWorkspace(workspaceName, request);
+ if (workspace == null) return null;
Long workspaceId = workspace.getId();
assert workspaceId != null;
- Location location = request.at();
ActualLocation actual = getActualLocation(workspaceId, location);
actualLocation = actual.location;
Path path = actualLocation.getPath();
@@ -1274,7 +1294,7 @@
List<Location> deletedLocations = query.getNodeLocations(true,
true);
// Now delete the subgraph ...
- query.deleteSubgraph(true);
+ query.deleteSubgraph(deleteTopOfBranch);
// Verify referential integrity: that none of the deleted nodes are
referenced by nodes not being deleted.
List<ReferenceEntity> invalidReferences =
query.getInwardReferences();
@@ -1299,14 +1319,16 @@
throw new ReferentialIntegrityException(invalidRefs, msg);
}
- // And adjust the SNS index and indexes ...
- ChildEntity.adjustSnsIndexesAndIndexesAfterRemoving(entities,
- workspaceId,
- parentUuidString,
- childName,
- nsId,
- indexInParent);
- entities.flush();
+ if (deleteTopOfBranch) {
+ // And adjust the SNS index and indexes ...
+ ChildEntity.adjustSnsIndexesAndIndexesAfterRemoving(entities,
+ workspaceId,
+
parentUuidString,
+ childName,
+ nsId,
+ indexInParent);
+ entities.flush();
+ }
// Remove from the cache of children locations all entries for deleted
nodes ...
cache.removeBranch(workspaceId, deletedLocations);
@@ -1317,9 +1339,9 @@
} catch (Throwable e) { // Includes PathNotFoundException
request.setError(e);
- return;
+ return null;
}
- request.setActualLocationOfNode(actualLocation);
+ return actualLocation;
}
/**