Author: bcarothers
Date: 2009-06-26 22:54:06 -0400 (Fri, 26 Jun 2009)
New Revision: 1065
Added:
trunk/dna-graph/src/main/java/org/jboss/dna/graph/connector/map/
trunk/dna-graph/src/main/java/org/jboss/dna/graph/connector/map/AbstractMapWorkspace.java
trunk/dna-graph/src/main/java/org/jboss/dna/graph/connector/map/MapNode.java
trunk/dna-graph/src/main/java/org/jboss/dna/graph/connector/map/MapRepository.java
trunk/dna-graph/src/main/java/org/jboss/dna/graph/connector/map/MapRepositoryConnection.java
trunk/dna-graph/src/main/java/org/jboss/dna/graph/connector/map/MapRepositorySource.java
trunk/dna-graph/src/main/java/org/jboss/dna/graph/connector/map/MapRequestProcessor.java
trunk/dna-graph/src/main/java/org/jboss/dna/graph/connector/map/MapWorkspace.java
trunk/dna-graph/src/main/java/org/jboss/dna/graph/connector/map/package-info.java
trunk/extensions/dna-connector-jbosscache/src/main/java/org/jboss/dna/connector/jbosscache/JBossCacheRepository.java
Removed:
trunk/dna-graph/src/main/java/org/jboss/dna/graph/connector/inmemory/InMemoryNode.java
trunk/dna-graph/src/main/java/org/jboss/dna/graph/connector/inmemory/InMemoryRepositoryConnection.java
trunk/dna-graph/src/main/java/org/jboss/dna/graph/connector/inmemory/InMemoryRequestProcessor.java
trunk/extensions/dna-connector-jbosscache/src/main/java/org/jboss/dna/connector/jbosscache/JBossCacheConnection.java
trunk/extensions/dna-connector-jbosscache/src/main/java/org/jboss/dna/connector/jbosscache/JBossCacheLexicon.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/JBossCacheWorkspaces.java
trunk/extensions/dna-connector-jbosscache/src/test/java/org/jboss/dna/connector/jbosscache/JBossCacheRequestProcessorTest.java
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/InMemoryRepositorySource.java
trunk/dna-graph/src/test/java/org/jboss/dna/graph/connector/inmemory/InMemoryRepositoryTest.java
trunk/dna-graph/src/test/java/org/jboss/dna/graph/connector/inmemory/InMemoryRepositoryWorkspaceTest.java
trunk/extensions/dna-connector-jbosscache/src/main/java/org/jboss/dna/connector/jbosscache/JBossCacheSource.java
Log:
DNA-470 Provide Base Set of Connector Classes for All Map-Based Connectors
Applied patch that creates a new MapRepository class (and associated classes) based on the
original InMemoryRepository implementation and refactors the In-Memory connector and JBoss
Cache connector to utilize the new MapRepository.
Deleted:
trunk/dna-graph/src/main/java/org/jboss/dna/graph/connector/inmemory/InMemoryNode.java
===================================================================
---
trunk/dna-graph/src/main/java/org/jboss/dna/graph/connector/inmemory/InMemoryNode.java 2009-06-24
22:14:12 UTC (rev 1064)
+++
trunk/dna-graph/src/main/java/org/jboss/dna/graph/connector/inmemory/InMemoryNode.java 2009-06-27
02:54:06 UTC (rev 1065)
@@ -1,173 +0,0 @@
-/*
- * JBoss DNA (
http://www.jboss.org/dna)
- * See the COPYRIGHT.txt file distributed with this work for information
- * regarding copyright ownership. Some portions may be licensed
- * to Red Hat, Inc. under one or more contributor license agreements.
- * See the AUTHORS.txt file in the distribution for a full listing of
- * individual contributors.
- *
- * JBoss DNA is free software. Unless otherwise indicated, all code in JBoss DNA
- * is licensed to you under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation; either version 2.1 of
- * the License, or (at your option) any later version.
- *
- * JBoss DNA is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this software; if not, write to the Free
- * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA, or see the FSF site:
http://www.fsf.org.
- */
-package org.jboss.dna.graph.connector.inmemory;
-
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.LinkedList;
-import java.util.Map;
-import java.util.Set;
-import java.util.UUID;
-import net.jcip.annotations.NotThreadSafe;
-import org.jboss.dna.graph.ExecutionContext;
-import org.jboss.dna.graph.property.Name;
-import org.jboss.dna.graph.property.Path;
-import org.jboss.dna.graph.property.Property;
-import org.jboss.dna.graph.property.PropertyFactory;
-
-/**
- * @author Randall Hauch
- */
-@NotThreadSafe
-public class InMemoryNode {
-
- private final UUID uuid;
- private InMemoryNode parent;
- private Path.Segment name;
- private final Map<Name, Property> properties = new HashMap<Name,
Property>();
- private final LinkedList<InMemoryNode> children = new
LinkedList<InMemoryNode>();
- final Set<Name> existingNames = new HashSet<Name>();
-
- public InMemoryNode( UUID uuid ) {
- assert uuid != null;
- this.uuid = uuid;
- }
-
- /**
- * @return uuid
- */
- public UUID getUuid() {
- return uuid;
- }
-
- /**
- * @return name
- */
- public Path.Segment getName() {
- return name;
- }
-
- /**
- * @param name Sets name to the specified value.
- */
- protected void setName( Path.Segment name ) {
- this.name = name;
- }
-
- /**
- * @return parent
- */
- public InMemoryNode getParent() {
- return parent;
- }
-
- /**
- * @param parent Sets parent to the specified value.
- */
- protected void setParent( InMemoryNode parent ) {
- this.parent = parent;
- }
-
- /**
- * @return children
- */
- LinkedList<InMemoryNode> getChildren() {
- return children;
- }
-
- /**
- * @return properties
- */
- protected Map<Name, Property> getProperties() {
- return properties;
- }
-
- public InMemoryNode setProperty( Property property ) {
- if (property != null) {
- this.properties.put(property.getName(), property);
- }
- return this;
- }
-
- public InMemoryNode setProperty( ExecutionContext context,
- String name,
- Object... values ) {
- PropertyFactory propertyFactory = context.getPropertyFactory();
- Name propertyName = context.getValueFactories().getNameFactory().create(name);
- return setProperty(propertyFactory.create(propertyName, values));
- }
-
- public Property getProperty( ExecutionContext context,
- String name ) {
- Name propertyName = context.getValueFactories().getNameFactory().create(name);
- return getProperty(propertyName);
- }
-
- public Property getProperty( Name name ) {
- return this.properties.get(name);
- }
-
- /**
- * {@inheritDoc}
- *
- * @see java.lang.Object#hashCode()
- */
- @Override
- public int hashCode() {
- return uuid.hashCode();
- }
-
- /**
- * {@inheritDoc}
- *
- * @see java.lang.Object#equals(java.lang.Object)
- */
- @Override
- public boolean equals( Object obj ) {
- if (obj == this) return true;
- if (obj instanceof InMemoryNode) {
- InMemoryNode that = (InMemoryNode)obj;
- if (!this.getUuid().equals(that.getUuid())) return false;
- return true;
- }
- return false;
- }
-
- /**
- * {@inheritDoc}
- *
- * @see java.lang.Object#toString()
- */
- @Override
- public String toString() {
- StringBuilder sb = new StringBuilder();
- if (this.name == null) {
- sb.append("");
- } else {
- sb.append(this.name);
- }
- sb.append(" (").append(uuid).append(")");
- return sb.toString();
- }
-}
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-06-24
22:14:12 UTC (rev 1064)
+++
trunk/dna-graph/src/main/java/org/jboss/dna/graph/connector/inmemory/InMemoryRepository.java 2009-06-27
02:54:06 UTC (rev 1065)
@@ -23,420 +23,80 @@
*/
package org.jboss.dna.graph.connector.inmemory;
-import java.util.ArrayList;
import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.ListIterator;
import java.util.Map;
-import java.util.Set;
import java.util.UUID;
-import java.util.concurrent.locks.ReadWriteLock;
-import java.util.concurrent.locks.ReentrantReadWriteLock;
import net.jcip.annotations.GuardedBy;
import net.jcip.annotations.NotThreadSafe;
-import org.jboss.dna.common.util.CheckArg;
import org.jboss.dna.graph.ExecutionContext;
+import org.jboss.dna.graph.connector.map.AbstractMapWorkspace;
+import org.jboss.dna.graph.connector.map.MapNode;
+import org.jboss.dna.graph.connector.map.MapRepository;
+import org.jboss.dna.graph.connector.map.MapWorkspace;
import org.jboss.dna.graph.property.Name;
-import org.jboss.dna.graph.property.Path;
-import org.jboss.dna.graph.property.PathFactory;
-import org.jboss.dna.graph.property.Property;
-import org.jboss.dna.graph.property.PropertyFactory;
-import org.jboss.dna.graph.property.PropertyType;
-import org.jboss.dna.graph.property.Reference;
-import org.jboss.dna.graph.property.UuidFactory;
-import org.jboss.dna.graph.property.ValueFactory;
-import org.jboss.dna.graph.property.basic.RootPath;
-import org.jboss.dna.graph.request.CreateWorkspaceRequest.CreateConflictBehavior;
/**
* @author Randall Hauch
*/
@NotThreadSafe
-public class InMemoryRepository {
+public class InMemoryRepository extends MapRepository {
- protected final ReadWriteLock lock = new ReentrantReadWriteLock();
- protected final UUID rootNodeUuid;
- private final String sourceName;
- private final String defaultWorkspaceName;
- private final Map<String, Workspace> workspaces = new HashMap<String,
Workspace>();
-
public InMemoryRepository( String sourceName,
UUID rootNodeUuid ) {
- this(sourceName, rootNodeUuid, null);
+ super(sourceName, rootNodeUuid, null);
+ initialize();
}
public InMemoryRepository( String sourceName,
UUID rootNodeUuid,
String defaultWorkspaceName ) {
- CheckArg.isNotEmpty(sourceName, "sourceName");
- CheckArg.isNotNull(rootNodeUuid, "rootNodeUUID");
- this.rootNodeUuid = rootNodeUuid;
- this.sourceName = sourceName;
- this.defaultWorkspaceName = defaultWorkspaceName != null ? defaultWorkspaceName :
"";
- // Create the default workspace ...
- workspaces.put(this.defaultWorkspaceName, new
Workspace(this.defaultWorkspaceName));
+ super(sourceName, rootNodeUuid, defaultWorkspaceName);
+ initialize();
}
- /**
- * @return sourceName
- */
- public String getSourceName() {
- return sourceName;
- }
-
- /**
- * @return lock
- */
- public ReadWriteLock getLock() {
- return lock;
- }
-
@GuardedBy( "getLock()" )
- public Set<String> getWorkspaceNames() {
- return workspaces.keySet();
+ protected MapWorkspace createWorkspace( ExecutionContext context,
+ String name ) {
+ return new Workspace(this, name);
}
- @GuardedBy( "getLock()" )
- public Workspace getWorkspace( ExecutionContext context,
- String name ) {
- if (name == null) name = defaultWorkspaceName;
- return workspaces.get(name);
- }
+ protected class Workspace extends AbstractMapWorkspace {
+ private final Map<UUID, MapNode> nodesByUuid = new HashMap<UUID,
MapNode>();
- @GuardedBy( "getLock()" )
- public Workspace createWorkspace( ExecutionContext context,
- String name,
- CreateConflictBehavior behavior ) {
- String newName = name;
- boolean conflictingName = workspaces.containsKey(newName);
- if (conflictingName) {
- switch (behavior) {
- case DO_NOT_CREATE:
- return null;
- case CREATE_WITH_ADJUSTED_NAME:
- int counter = 0;
- do {
- newName = name + (++counter);
- } while (workspaces.containsKey(newName));
- break;
- }
- }
- assert workspaces.containsKey(newName) == false;
- Workspace workspace = new Workspace(newName);
- workspaces.put(newName, workspace);
- return workspace;
- }
+ public Workspace( MapRepository repository,
+ String name ) {
+ super(repository, name);
- @GuardedBy( "getLock()" )
- public Workspace createWorkspace( ExecutionContext context,
- String name,
- CreateConflictBehavior existingWorkspaceBehavior,
- String nameOfWorkspaceToClone ) {
- Workspace workspace = createWorkspace(context, name, existingWorkspaceBehavior);
- if (workspace == null) {
- // Unable to create because of a duplicate name ...
- return null;
+ initialize();
}
- Workspace original = getWorkspace(context, nameOfWorkspaceToClone);
- if (original != null) {
- // Copy the properties of the root node ...
- InMemoryNode root = workspace.getRoot();
- InMemoryNode origRoot = original.getRoot();
- root.getProperties().clear();
- root.getProperties().putAll(origRoot.getProperties());
- // Loop over each child and call this method to copy the immediate children
(and below).
- // Note that this makes the copy have the same UUID as the original.
- for (InMemoryNode originalNode : origRoot.getChildren()) {
- original.copyNode(context, originalNode, workspace, root,
originalNode.getName().getName(), true, null);
- }
- }
- return workspace;
- }
-
- @GuardedBy( "getLock()" )
- public boolean destroyWorkspace( String name ) {
- return workspaces.remove(name) != null;
- }
-
- protected class Workspace {
- private final Map<UUID, InMemoryNode> nodesByUuid = new HashMap<UUID,
InMemoryNode>();
- private final String name;
-
- protected Workspace( String name ) {
- assert name != null;
- this.name = name;
- // Create the root node ...
- InMemoryNode root = new InMemoryNode(rootNodeUuid);
- nodesByUuid.put(root.getUuid(), root);
- }
-
- /**
- * @return name
- */
- public String getName() {
- return name;
- }
-
- public InMemoryNode getRoot() {
- return nodesByUuid.get(rootNodeUuid);
- }
-
- public InMemoryNode getNode( UUID uuid ) {
- assert uuid != null;
- return nodesByUuid.get(uuid);
- }
-
- protected Map<UUID, InMemoryNode> getNodesByUuid() {
- return nodesByUuid;
- }
-
- public InMemoryNode getNode( ExecutionContext context,
- String path ) {
- assert context != null;
- assert path != null;
- return getNode(context.getValueFactories().getPathFactory().create(path));
- }
-
- /**
- * Find a node with the given path.
- *
- * @param path the path to the node; may not be null
- * @return the node with the path, or null if the node does not exist
- */
- public InMemoryNode getNode( Path path ) {
- assert path != null;
- InMemoryNode node = getRoot();
- for (Path.Segment segment : path) {
- InMemoryNode desiredChild = null;
- for (InMemoryNode child : node.getChildren()) {
- if (child == null) continue;
- Path.Segment childName = child.getName();
- if (childName == null) continue;
- if (childName.equals(segment)) {
- desiredChild = child;
- break;
- }
- }
- if (desiredChild != null) {
- node = desiredChild;
- } else {
- return null;
- }
- }
- return node;
- }
-
- /**
- * Returns the absolute path to the given node
- *
- * @param pathFactory the path factory to use to create the path from the list of
names of all of the nodes on the path
- * from the root node to the given node
- * @param node the node for which the path should be returned
- * @return the absolute path to the given node
- */
- Path pathFor( PathFactory pathFactory,
- InMemoryNode node ) {
+ protected void addNodeToMap( MapNode node ) {
assert node != null;
- assert pathFactory != null;
-
- LinkedList<Path.Segment> segments = new
LinkedList<Path.Segment>();
- InMemoryNode root = getRoot();
-
- do {
- segments.addFirst(node.getName());
- node = node.getParent();
- } while (!node.equals(root));
-
- return pathFactory.createAbsolutePath(segments);
+ assert nodesByUuid != null;
+ nodesByUuid.put(node.getUuid(), node);
}
- /**
- * Find the lowest existing node along the path.
- *
- * @param path the path to the node; may not be null
- * @return the lowest existing node along the path, or the root node if no node
exists on the path
- */
- public Path getLowestExistingPath( Path path ) {
- assert path != null;
- InMemoryNode node = getRoot();
- int segmentNumber = 0;
- for (Path.Segment segment : path) {
- InMemoryNode desiredChild = null;
- for (InMemoryNode child : node.getChildren()) {
- if (child == null) continue;
- Path.Segment childName = child.getName();
- if (childName == null) continue;
- if (childName.equals(segment)) {
- desiredChild = child;
- break;
- }
- }
- if (desiredChild != null) {
- node = desiredChild;
- } else {
- return path.subpath(0, segmentNumber);
- }
- ++segmentNumber;
- }
- return RootPath.INSTANCE;
+ protected MapNode removeNodeFromMap( UUID nodeUuid ) {
+ assert nodeUuid != null;
+ return nodesByUuid.remove(nodeUuid);
}
- public void removeNode( ExecutionContext context,
- InMemoryNode node ) {
- assert context != null;
- assert node != null;
- if (getRoot().equals(node)) {
- nodesByUuid.clear();
- // Create the root node ...
- InMemoryNode root = new InMemoryNode(rootNodeUuid);
- nodesByUuid.put(root.getUuid(), root);
- return;
- }
- InMemoryNode parent = node.getParent();
- assert parent != null;
- parent.getChildren().remove(node);
- correctSameNameSiblingIndexes(context, parent, node.getName().getName());
- removeUuidReference(node);
+ protected void removeAllNodesFromMap() {
+ nodesByUuid.clear();
}
- protected void removeUuidReference( InMemoryNode node ) {
- nodesByUuid.remove(node.getUuid());
- for (InMemoryNode child : node.getChildren()) {
- removeUuidReference(child);
- }
+ public MapNode getNode( UUID nodeUuid ) {
+ assert nodeUuid != null;
+ return nodesByUuid.get(nodeUuid);
}
/**
- * Create a node at the supplied path. The parent of the new node must already
exist.
- *
- * @param context the environment; may not be null
- * @param pathToNewNode the path to the new node; may not be null
- * @return the new node (or root if the path specified the root)
- */
- public InMemoryNode createNode( ExecutionContext context,
- String pathToNewNode ) {
- assert context != null;
- assert pathToNewNode != null;
- Path path =
context.getValueFactories().getPathFactory().create(pathToNewNode);
- if (path.isRoot()) return getRoot();
- Path parentPath = path.getParent();
- InMemoryNode parentNode = getNode(parentPath);
- Name name = path.getLastSegment().getName();
- return createNode(context, parentNode, name, null);
- }
-
- /**
- * Create a new node with the supplied name, as a child of the supplied parent.
- *
- * @param context the execution context
- * @param parentNode the parent node; may not be null
- * @param name the name; may not be null
- * @param uuid the UUID of the node, or null if the UUID is to be generated
- * @return the new node
- */
- public InMemoryNode createNode( ExecutionContext context,
- InMemoryNode parentNode,
- Name name,
- UUID uuid ) {
- assert context != null;
- assert name != null;
- if (parentNode == null) parentNode = getRoot();
- if (uuid == null) uuid = UUID.randomUUID();
- InMemoryNode node = new InMemoryNode(uuid);
- nodesByUuid.put(node.getUuid(), node);
- node.setParent(parentNode);
- // Find the last node with this same name ...
- int nextIndex = 1;
- if (parentNode.existingNames.contains(name)) {
- ListIterator<InMemoryNode> iter =
parentNode.getChildren().listIterator(parentNode.getChildren().size());
- while (iter.hasPrevious()) {
- InMemoryNode prev = iter.previous();
- if (prev.getName().getName().equals(name)) {
- nextIndex = prev.getName().getIndex() + 1;
- break;
- }
- }
- }
- Path.Segment newName =
context.getValueFactories().getPathFactory().createSegment(name, nextIndex);
- node.setName(newName);
- parentNode.getChildren().add(node);
- parentNode.existingNames.add(name);
- return node;
- }
-
- /**
- * Move the supplied node to the new parent. This method automatically removes
the node from its existing parent, and also
- * correctly adjusts the {@link Path.Segment#getIndex() index} to be correct in
the new parent.
- *
- * @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}
- * @param beforeNode the node before which this new node should be placed
- */
- public void moveNode( ExecutionContext context,
- InMemoryNode node,
- Name desiredNewName,
- Workspace newWorkspace,
- InMemoryNode newParent,
- InMemoryNode beforeNode ) {
- assert context != null;
- assert newParent != null;
- assert node != null;
- // Why was this restriction here? -- BRC
- // assert newWorkspace.getRoot().equals(newParent) != true;
- assert this.getRoot().equals(node) != true;
- InMemoryNode oldParent = node.getParent();
- Name oldName = node.getName().getName();
- if (oldParent != null) {
- boolean removed = oldParent.getChildren().remove(node);
- assert removed == true;
- node.setParent(null);
- correctSameNameSiblingIndexes(context, oldParent, oldName);
- }
- node.setParent(newParent);
- Name newName = oldName;
- if (desiredNewName != null) {
- newName = desiredNewName;
-
node.setName(context.getValueFactories().getPathFactory().createSegment(desiredNewName,
1));
- }
-
- if (beforeNode == null) {
- newParent.getChildren().add(node);
- } else {
- int index = newParent.getChildren().indexOf(beforeNode);
- newParent.getChildren().add(index, node);
- }
- correctSameNameSiblingIndexes(context, newParent, newName);
-
- // If the node was moved to a new workspace...
- if (!this.equals(newWorkspace)) {
- // We need to remove the node from this workspace's map of nodes ...
- this.moveNodeToWorkspace(node, newWorkspace);
- }
- }
-
- protected void moveNodeToWorkspace( InMemoryNode node,
- Workspace newWorkspace ) {
- assert this.nodesByUuid.containsKey(node.getUuid());
- assert !newWorkspace.nodesByUuid.containsKey(node.getUuid());
-
- this.nodesByUuid.remove(node.getUuid());
- newWorkspace.nodesByUuid.put(node.getUuid(), node);
- for (InMemoryNode child : node.getChildren()) {
- moveNodeToWorkspace(child, newWorkspace);
- }
- }
-
- /**
* This should copy the subgraph given by the original node and place the new
copy under the supplied new parent. Note
* that internal references between nodes within the original subgraph must be
reflected as internal nodes within the new
* subgraph.
+ * <p>
+ * This method is trivially overridden for testing purposes.
+ * </p>
*
* @param context the context; may not be null
* @param original the node to be copied; may not be null
@@ -448,152 +108,24 @@
* null if the UUIDs are to be maintained
* @return the new node, which is the top of the new subgraph
*/
- public InMemoryNode copyNode( ExecutionContext context,
- InMemoryNode original,
- Workspace newWorkspace,
- InMemoryNode newParent,
- Name desiredName,
- boolean recursive,
- Map<UUID, UUID> oldToNewUuids ) {
- assert context != null;
- assert original != null;
- assert newParent != null;
- assert newWorkspace != null;
- boolean reuseUuids = oldToNewUuids == null;
-
- // Get or create the new node ...
- Name childName = desiredName != null ? desiredName :
original.getName().getName();
- UUID uuidForCopy = reuseUuids ? original.getUuid() : UUID.randomUUID();
- InMemoryNode copy = newWorkspace.createNode(context, newParent, childName,
uuidForCopy);
- if (!reuseUuids) {
- assert oldToNewUuids != null;
- oldToNewUuids.put(original.getUuid(), copy.getUuid());
- }
-
- // Copy the properties ...
- copy.getProperties().clear();
- copy.getProperties().putAll(original.getProperties());
- if (recursive) {
- // Loop over each child and call this method ...
- for (InMemoryNode child : original.getChildren()) {
- copyNode(context, child, newWorkspace, copy, null, true,
oldToNewUuids);
- }
- }
-
- if (!reuseUuids) {
- assert oldToNewUuids != null;
- // Now, adjust any references in the new subgraph to objects in the
original subgraph
- // (because they were internal references, and need to be internal to the
new subgraph)
- PropertyFactory propertyFactory = context.getPropertyFactory();
- UuidFactory uuidFactory = context.getValueFactories().getUuidFactory();
- ValueFactory<Reference> referenceFactory =
context.getValueFactories().getReferenceFactory();
- for (Map.Entry<UUID, UUID> oldToNew : oldToNewUuids.entrySet()) {
- InMemoryNode oldNode = this.getNode(oldToNew.getKey());
- InMemoryNode newNode = newWorkspace.getNode(oldToNew.getValue());
- assert oldNode != null;
- assert newNode != null;
- // Iterate over the properties of the new ...
- for (Map.Entry<Name, Property> entry :
newNode.getProperties().entrySet()) {
- Property property = entry.getValue();
- // Now see if any of the property values are references ...
- List<Object> newValues = new ArrayList<Object>();
- boolean foundReference = false;
- for (Iterator<?> iter = property.getValues();
iter.hasNext();) {
- Object value = iter.next();
- PropertyType type = PropertyType.discoverType(value);
- if (type == PropertyType.REFERENCE) {
- UUID oldReferencedUuid = uuidFactory.create(value);
- UUID newReferencedUuid =
oldToNewUuids.get(oldReferencedUuid);
- if (newReferencedUuid != null) {
-
newValues.add(referenceFactory.create(newReferencedUuid));
- foundReference = true;
- }
- } else {
- newValues.add(value);
- }
- }
- // If we found at least one reference, we have to build a new
Property object ...
- if (foundReference) {
- Property newProperty =
propertyFactory.create(property.getName(), newValues);
- entry.setValue(newProperty);
- }
- }
- }
- }
-
- return copy;
- }
-
- public Set<UUID> getUuidsUnderNode( InMemoryNode node ) {
- Set<UUID> uuids = new HashSet<UUID>();
- uuidsUnderNode(node, uuids);
-
- return uuids;
- }
-
- private void uuidsUnderNode( InMemoryNode node,
- Set<UUID> accumulator ) {
- accumulator.add(node.getUuid());
-
- for (InMemoryNode child : node.getChildren()) {
- uuidsUnderNode(child, accumulator);
- }
- }
-
- protected void correctSameNameSiblingIndexes( ExecutionContext context,
- InMemoryNode parentNode,
- Name name ) {
- if (parentNode == null) return;
- // Look for the highest existing index ...
- List<InMemoryNode> childrenWithSameNames = new
LinkedList<InMemoryNode>();
- for (InMemoryNode child : parentNode.getChildren()) {
- if (child.getName().getName().equals(name))
childrenWithSameNames.add(child);
- }
- if (childrenWithSameNames.size() == 0) return;
- if (childrenWithSameNames.size() == 1) {
- InMemoryNode childWithSameName = childrenWithSameNames.get(0);
- Path.Segment newName =
context.getValueFactories().getPathFactory().createSegment(name, Path.DEFAULT_INDEX);
- childWithSameName.setName(newName);
- return;
- }
- int index = 1;
- for (InMemoryNode childWithSameName : childrenWithSameNames) {
- Path.Segment segment = childWithSameName.getName();
- if (segment.getIndex() != index) {
- Path.Segment newName =
context.getValueFactories().getPathFactory().createSegment(name, index);
- childWithSameName.setName(newName);
- }
- ++index;
- }
- }
-
- /**
- * {@inheritDoc}
- *
- * @see java.lang.Object#equals(java.lang.Object)
- */
@Override
- public boolean equals( Object obj ) {
- if (obj == this) return true;
- if (obj instanceof Workspace) {
- Workspace that = (Workspace)obj;
- // Assume the workspaces are in the same repository ...
- if (!this.name.equals(that.name)) return false;
- return true;
- }
- return false;
+ protected MapNode copyNode( ExecutionContext context,
+ MapNode original,
+ MapWorkspace newWorkspace,
+ MapNode newParent,
+ Name desiredName,
+ boolean recursive,
+ Map<UUID, UUID> oldToNewUuids ) {
+ return super.copyNode(context, original, newWorkspace, newParent,
desiredName, recursive, oldToNewUuids);
}
/**
- * {@inheritDoc}
+ * Method added to support testing
*
- * @see java.lang.Object#toString()
+ * @return the number of nodes in the backing map
*/
- @Override
- public String toString() {
- return InMemoryRepository.this.getSourceName() + "/" +
this.getName();
+ final int size() {
+ return nodesByUuid.size();
}
-
}
-
}
Deleted:
trunk/dna-graph/src/main/java/org/jboss/dna/graph/connector/inmemory/InMemoryRepositoryConnection.java
===================================================================
---
trunk/dna-graph/src/main/java/org/jboss/dna/graph/connector/inmemory/InMemoryRepositoryConnection.java 2009-06-24
22:14:12 UTC (rev 1064)
+++
trunk/dna-graph/src/main/java/org/jboss/dna/graph/connector/inmemory/InMemoryRepositoryConnection.java 2009-06-27
02:54:06 UTC (rev 1065)
@@ -1,135 +0,0 @@
-/*
- * JBoss DNA (
http://www.jboss.org/dna)
- * See the COPYRIGHT.txt file distributed with this work for information
- * regarding copyright ownership. Some portions may be licensed
- * to Red Hat, Inc. under one or more contributor license agreements.
- * See the AUTHORS.txt file in the distribution for a full listing of
- * individual contributors.
- *
- * JBoss DNA is free software. Unless otherwise indicated, all code in JBoss DNA
- * is licensed to you under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation; either version 2.1 of
- * the License, or (at your option) any later version.
- *
- * JBoss DNA is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this software; if not, write to the Free
- * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA, or see the FSF site:
http://www.fsf.org.
- */
-package org.jboss.dna.graph.connector.inmemory;
-
-import java.util.concurrent.TimeUnit;
-import java.util.concurrent.locks.Lock;
-import javax.transaction.xa.XAResource;
-import org.jboss.dna.common.statistic.Stopwatch;
-import org.jboss.dna.common.util.Logger;
-import org.jboss.dna.graph.ExecutionContext;
-import org.jboss.dna.graph.cache.CachePolicy;
-import org.jboss.dna.graph.connector.RepositoryConnection;
-import org.jboss.dna.graph.connector.RepositorySourceException;
-import org.jboss.dna.graph.request.Request;
-import org.jboss.dna.graph.request.processor.RequestProcessor;
-
-/**
- * @author Randall Hauch
- */
-public class InMemoryRepositoryConnection implements RepositoryConnection {
-
- private final InMemoryRepositorySource source;
- private final InMemoryRepository repository;
-
- InMemoryRepositoryConnection( InMemoryRepositorySource source,
- InMemoryRepository repository ) {
- assert source != null;
- assert repository != null;
- this.source = source;
- this.repository = repository;
- }
-
- /**
- * {@inheritDoc}
- */
- public String getSourceName() {
- return source.getName();
- }
-
- /**
- * {@inheritDoc}
- */
- public CachePolicy getDefaultCachePolicy() {
- return source.getDefaultCachePolicy();
- }
-
- /**
- * {@inheritDoc}
- */
- public XAResource getXAResource() {
- return null;
- }
-
- /**
- * {@inheritDoc}
- */
- public boolean ping( long time,
- TimeUnit unit ) {
- return true;
- }
-
- /**
- * {@inheritDoc}
- */
- public void close() {
- // do nothing
- }
-
- /**
- * {@inheritDoc}
- *
- * @see
org.jboss.dna.graph.connector.RepositoryConnection#execute(org.jboss.dna.graph.ExecutionContext,
- * org.jboss.dna.graph.request.Request)
- */
- public void execute( ExecutionContext context,
- Request request ) throws RepositorySourceException {
- Logger logger = context.getLogger(getClass());
- Stopwatch sw = null;
- if (logger.isTraceEnabled()) {
- sw = new Stopwatch();
- sw.start();
- }
- // Do any commands update/write?
- RequestProcessor processor = new InMemoryRequestProcessor(context,
this.repository, this.source.getRepositoryContext());
-
- Lock lock = request.isReadOnly() ? repository.getLock().readLock() :
repository.getLock().writeLock();
- lock.lock();
- try {
- // Obtain the lock and execute the commands ...
- processor.process(request);
- } finally {
- try {
- processor.close();
- } finally {
- lock.unlock();
- }
- }
- if (logger.isTraceEnabled()) {
- assert sw != null;
- sw.stop();
- logger.trace("InMemoryRepositoryConnection.execute(...) took " +
sw.getTotalDuration());
- }
- }
-
- /**
- * {@inheritDoc}
- *
- * @see java.lang.Object#toString()
- */
- @Override
- public String toString() {
- return "Connection to the \"" + getSourceName() + "\"
in-memory repository";
- }
-}
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-06-24
22:14:12 UTC (rev 1064)
+++
trunk/dna-graph/src/main/java/org/jboss/dna/graph/connector/inmemory/InMemoryRepositorySource.java 2009-06-27
02:54:06 UTC (rev 1065)
@@ -52,6 +52,8 @@
import org.jboss.dna.graph.connector.RepositorySource;
import org.jboss.dna.graph.connector.RepositorySourceCapabilities;
import org.jboss.dna.graph.connector.RepositorySourceException;
+import org.jboss.dna.graph.connector.map.MapRepositoryConnection;
+import org.jboss.dna.graph.connector.map.MapRepositorySource;
/**
* A {@link RepositorySource} for an in-memory repository. Each {@link
InMemoryRepositorySource} instance contains its own
@@ -59,7 +61,7 @@
*
* @author Randall Hauch
*/
-public class InMemoryRepositorySource implements RepositorySource, ObjectFactory {
+public class InMemoryRepositorySource implements MapRepositorySource, ObjectFactory {
/**
* The initial version is 1
@@ -258,7 +260,7 @@
if (repository == null) {
repository = new InMemoryRepository(name, rootNodeUuid,
defaultWorkspaceName);
}
- return new InMemoryRepositoryConnection(this, repository);
+ return new MapRepositoryConnection(this, repository);
}
/**
Deleted:
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-06-24
22:14:12 UTC (rev 1064)
+++
trunk/dna-graph/src/main/java/org/jboss/dna/graph/connector/inmemory/InMemoryRequestProcessor.java 2009-06-27
02:54:06 UTC (rev 1065)
@@ -1,498 +0,0 @@
-/*
- * JBoss DNA (
http://www.jboss.org/dna)
- * See the COPYRIGHT.txt file distributed with this work for information
- * regarding copyright ownership. Some portions may be licensed
- * to Red Hat, Inc. under one or more contributor license agreements.
- * See the AUTHORS.txt file in the distribution for a full listing of
- * individual contributors.
- *
- * 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.connector.inmemory;
-
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import java.util.UUID;
-import org.jboss.dna.common.i18n.I18n;
-import org.jboss.dna.common.util.CheckArg;
-import org.jboss.dna.graph.DnaLexicon;
-import org.jboss.dna.graph.ExecutionContext;
-import org.jboss.dna.graph.GraphI18n;
-import org.jboss.dna.graph.JcrLexicon;
-import org.jboss.dna.graph.Location;
-import org.jboss.dna.graph.connector.RepositoryContext;
-import org.jboss.dna.graph.connector.UuidAlreadyExistsException;
-import org.jboss.dna.graph.property.Name;
-import org.jboss.dna.graph.property.NamespaceRegistry;
-import org.jboss.dna.graph.property.Path;
-import org.jboss.dna.graph.property.PathFactory;
-import org.jboss.dna.graph.property.PathNotFoundException;
-import org.jboss.dna.graph.property.Property;
-import org.jboss.dna.graph.property.PropertyFactory;
-import org.jboss.dna.graph.property.Path.Segment;
-import org.jboss.dna.graph.request.CloneWorkspaceRequest;
-import org.jboss.dna.graph.request.CopyBranchRequest;
-import org.jboss.dna.graph.request.CreateNodeRequest;
-import org.jboss.dna.graph.request.CreateWorkspaceRequest;
-import org.jboss.dna.graph.request.DeleteBranchRequest;
-import org.jboss.dna.graph.request.DestroyWorkspaceRequest;
-import org.jboss.dna.graph.request.GetWorkspacesRequest;
-import org.jboss.dna.graph.request.InvalidWorkspaceException;
-import org.jboss.dna.graph.request.MoveBranchRequest;
-import org.jboss.dna.graph.request.ReadAllChildrenRequest;
-import org.jboss.dna.graph.request.ReadAllPropertiesRequest;
-import org.jboss.dna.graph.request.Request;
-import org.jboss.dna.graph.request.UpdatePropertiesRequest;
-import org.jboss.dna.graph.request.VerifyWorkspaceRequest;
-import org.jboss.dna.graph.request.processor.RequestProcessor;
-
-/**
- * A {@link RequestProcessor} implementation that operates on an {@link
InMemoryRepository} and its
- * {@link InMemoryRepository.Workspace workspaces}.
- */
-public class InMemoryRequestProcessor extends RequestProcessor {
- private final PathFactory pathFactory;
- private final PropertyFactory propertyFactory;
- private final InMemoryRepository repository;
-
- protected InMemoryRequestProcessor( ExecutionContext context,
- InMemoryRepository repository,
- RepositoryContext repositoryContext ) {
- super(repository.getSourceName(), context, repositoryContext != null ?
repositoryContext.getObserver() : null);
- this.repository = repository;
- pathFactory = context.getValueFactories().getPathFactory();
- propertyFactory = context.getPropertyFactory();
- }
-
- @Override
- public void process( ReadAllChildrenRequest request ) {
- InMemoryRepository.Workspace workspace = getWorkspace(request,
request.inWorkspace());
- InMemoryNode node = getTargetNode(workspace, request, request.of());
- if (node == null) return;
- Location actualLocation = getActualLocation(request.of().getPath(), node);
- Path path = actualLocation.getPath();
- // Get the names of the children ...
- List<InMemoryNode> children = node.getChildren();
- for (InMemoryNode child : children) {
- Segment childName = child.getName();
- Path childPath = pathFactory.create(path, childName);
- request.addChild(childPath, propertyFactory.create(DnaLexicon.UUID,
child.getUuid()));
- }
- request.setActualLocationOfNode(actualLocation);
- setCacheableInfo(request);
- }
-
- @Override
- public void process( ReadAllPropertiesRequest request ) {
- InMemoryRepository.Workspace workspace = getWorkspace(request,
request.inWorkspace());
- InMemoryNode node = getTargetNode(workspace, request, request.at());
- if (node == null) return;
- // Get the properties of the node ...
- Location actualLocation = getActualLocation(request.at().getPath(), node);
- request.addProperty(propertyFactory.create(DnaLexicon.UUID, node.getUuid()));
- for (Property property : node.getProperties().values()) {
- request.addProperty(property);
- }
- request.setActualLocationOfNode(actualLocation);
- setCacheableInfo(request);
- }
-
- @Override
- public void process( CopyBranchRequest request ) {
- InMemoryRepository.Workspace workspace = getWorkspace(request,
request.fromWorkspace());
- InMemoryRepository.Workspace newWorkspace = getWorkspace(request,
request.intoWorkspace());
- if (workspace == null || newWorkspace == null) return;
- InMemoryNode node = getTargetNode(workspace, request, request.from());
- if (node == null) return;
-
- Map<UUID, UUID> copyMap = null;
- Set<UUID> uuidsInFromBranch = null;
-
- switch (request.uuidConflictBehavior()) {
- case ALWAYS_CREATE_NEW_UUID:
-
- /*
- * The copyNode method uses the presence of a non-null map as an
indicator that new UUIDs should be created
- * during the copy operation
- */
- copyMap = new HashMap<UUID, UUID>();
- break;
- case REPLACE_EXISTING_NODE:
- uuidsInFromBranch = workspace.getUuidsUnderNode(node);
-
- for (UUID uuid : uuidsInFromBranch) {
- InMemoryNode existing;
- if (null != (existing = newWorkspace.getNode(uuid))) {
- newWorkspace.removeNode(this.getExecutionContext(), existing);
- }
- }
- break;
- case THROW_EXCEPTION:
- uuidsInFromBranch = workspace.getUuidsUnderNode(node);
-
- for (UUID uuid : uuidsInFromBranch) {
- InMemoryNode existing;
- if (null != (existing = newWorkspace.getNode(uuid))) {
- NamespaceRegistry namespaces =
this.getExecutionContext().getNamespaceRegistry();
- String path = newWorkspace.pathFor(pathFactory,
existing).getString(namespaces);
- request.setError(new
UuidAlreadyExistsException(this.getSourceName(), uuid, path, newWorkspace.getName()));
- return;
- }
- }
- break;
-
- default:
- throw new IllegalStateException("Unexpected UUID conflict behavior:
" + request.uuidConflictBehavior());
- }
-
- // Look up the new parent, which must exist ...
- Path newParentPath = request.into().getPath();
- Name desiredName = request.desiredName();
- InMemoryNode newParent = newWorkspace.getNode(newParentPath);
- InMemoryNode newNode = workspace.copyNode(getExecutionContext(),
- node,
- newWorkspace,
- newParent,
- desiredName,
- true,
- copyMap);
- Path newPath =
getExecutionContext().getValueFactories().getPathFactory().create(newParentPath,
newNode.getName());
- Location oldLocation = getActualLocation(request.from().getPath(), node);
- Location newLocation = Location.create(newPath, newNode.getUuid());
- request.setActualLocations(oldLocation, newLocation);
- recordChange(request);
- }
-
- @Override
- public void process( CreateNodeRequest request ) {
- InMemoryRepository.Workspace workspace = getWorkspace(request,
request.inWorkspace());
- if (workspace == null) return;
- Path parent = request.under().getPath();
- CheckArg.isNotNull(parent, "request.under().getPath()");
- InMemoryNode node = null;
- // Look up the parent node, which must exist ...
- // System.err.println(request.toString());
- InMemoryNode parentNode = workspace.getNode(parent);
- if (parentNode == null) {
- Path lowestExisting = workspace.getLowestExistingPath(parent);
- request.setError(new PathNotFoundException(request.under(), lowestExisting,
-
GraphI18n.inMemoryNodeDoesNotExist.text(parent)));
- return;
- }
- UUID uuid = null;
- for (Property property : request.properties()) {
- if (property.getName().equals(DnaLexicon.UUID) ||
property.getName().equals(JcrLexicon.UUID)) {
- uuid =
getExecutionContext().getValueFactories().getUuidFactory().create(property.getValues().next());
- break;
- }
- }
- switch (request.conflictBehavior()) {
- case APPEND:
- case DO_NOT_REPLACE:
- node = workspace.createNode(getExecutionContext(), parentNode,
request.named(), uuid);
- break;
- case REPLACE:
- // See if the node already exists (this doesn't record an error on
the request) ...
- node = getTargetNode(workspace, null,
Location.create(pathFactory.create(parent, request.named()), uuid));
- if (node != null) {
- workspace.removeNode(getExecutionContext(), node);
- }
- node = workspace.createNode(getExecutionContext(), parentNode,
request.named(), uuid);
- break;
- case UPDATE:
- // See if the node already exists (this doesn't record an error on
the request) ...
- node = getTargetNode(workspace, null,
Location.create(pathFactory.create(parent, request.named()), uuid));
- if (node == null) {
- node = workspace.createNode(getExecutionContext(), parentNode,
request.named(), uuid);
- } // otherwise, we found it and we're setting any properties below
- break;
- }
- assert node != null;
- Path path =
getExecutionContext().getValueFactories().getPathFactory().create(parent,
node.getName());
- // Now add the properties to the supplied node ...
- for (Property property : request.properties()) {
- Name propName = property.getName();
- if (property.size() == 0) {
- node.getProperties().remove(propName);
- continue;
- }
- if (!propName.equals(DnaLexicon.UUID)) {
- node.getProperties().put(propName, property);
- }
- }
- Location actualLocation = getActualLocation(path, node);
- request.setActualLocationOfNode(actualLocation);
- recordChange(request);
- }
-
- @Override
- public void process( DeleteBranchRequest request ) {
- InMemoryRepository.Workspace workspace = getWorkspace(request,
request.inWorkspace());
- if (workspace == null) return;
- InMemoryNode node = getTargetNode(workspace, request, request.at());
- if (node == null) return;
- workspace.removeNode(getExecutionContext(), node);
- Location actualLocation = getActualLocation(request.at().getPath(), node);
- request.setActualLocationOfNode(actualLocation);
- recordChange(request);
- }
-
- @Override
- public void process( MoveBranchRequest request ) {
- InMemoryRepository.Workspace workspace = getWorkspace(request,
request.inWorkspace());
- if (workspace == null) return;
-
- InMemoryNode beforeNode = request.before() != null ? getTargetNode(workspace,
request, request.before()) : null;
- InMemoryNode node = getTargetNode(workspace, request, request.from());
- if (node == null) return;
- // Look up the new parent, which must exist ...
- Path newParentPath;
-
- if (request.into() != null) {
- newParentPath = request.into().getPath();
- } else {
- // into or before cannot both be null
- assert beforeNode != null;
-
- // Build the path from the before node to the root.
- LinkedList<Path.Segment> segments = new
LinkedList<Path.Segment>();
- InMemoryNode current = beforeNode.getParent();
- while (current != workspace.getRoot()) {
- segments.addFirst(current.getName());
- current = current.getParent();
- }
- newParentPath =
getExecutionContext().getValueFactories().getPathFactory().createAbsolutePath(segments);
- }
-
- InMemoryNode newParent = workspace.getNode(newParentPath);
- workspace.moveNode(getExecutionContext(), node, request.desiredName(), workspace,
newParent, beforeNode);
- assert node.getParent() == newParent;
- Path newPath =
getExecutionContext().getValueFactories().getPathFactory().create(newParentPath,
node.getName());
- Location oldLocation = getActualLocation(request.from().getPath(), node);
- Location newLocation = Location.create(newPath, node.getUuid());
- request.setActualLocations(oldLocation, newLocation);
- recordChange(request);
- }
-
- @Override
- public void process( UpdatePropertiesRequest request ) {
- InMemoryRepository.Workspace workspace = getWorkspace(request,
request.inWorkspace());
- InMemoryNode node = getTargetNode(workspace, request, request.on());
- if (node == null) return;
- // Now set (or remove) the properties to the supplied node ...
- for (Map.Entry<Name, Property> propertyEntry :
request.properties().entrySet()) {
- Property property = propertyEntry.getValue();
- if (property == null) {
- node.getProperties().remove(propertyEntry.getKey());
- continue;
- }
- Name propName = property.getName();
- if (!propName.equals(DnaLexicon.UUID)) {
- node.getProperties().put(propName, property);
- }
- }
- Location actualLocation = getActualLocation(request.on().getPath(), node);
- request.setActualLocationOfNode(actualLocation);
- recordChange(request);
- }
-
- /**
- * {@inheritDoc}
- *
- * @see
org.jboss.dna.graph.request.processor.RequestProcessor#process(org.jboss.dna.graph.request.CreateWorkspaceRequest)
- */
- @Override
- public void process( CreateWorkspaceRequest request ) {
- InMemoryRepository.Workspace workspace =
repository.createWorkspace(getExecutionContext(),
-
request.desiredNameOfNewWorkspace(),
-
request.conflictBehavior());
- if (workspace == null) {
- String msg =
GraphI18n.workspaceAlreadyExistsInRepository.text(request.desiredNameOfNewWorkspace(),
-
repository.getSourceName());
- request.setError(new InvalidWorkspaceException(msg));
- } else {
- InMemoryNode root = workspace.getRoot();
- request.setActualRootLocation(Location.create(pathFactory.createRootPath(),
root.getUuid()));
- request.setActualWorkspaceName(workspace.getName());
- recordChange(request);
- }
- }
-
- /**
- * {@inheritDoc}
- *
- * @see
org.jboss.dna.graph.request.processor.RequestProcessor#process(org.jboss.dna.graph.request.DestroyWorkspaceRequest)
- */
- @Override
- public void process( DestroyWorkspaceRequest request ) {
- InMemoryRepository.Workspace workspace =
repository.getWorkspace(getExecutionContext(), request.workspaceName());
- if (workspace != null) {
- InMemoryNode root = workspace.getRoot();
- request.setActualRootLocation(Location.create(pathFactory.createRootPath(),
root.getUuid()));
- recordChange(request);
- } else {
- String msg =
GraphI18n.workspaceDoesNotExistInRepository.text(request.workspaceName(),
repository.getSourceName());
- request.setError(new InvalidWorkspaceException(msg));
- }
- }
-
- /**
- * {@inheritDoc}
- *
- * @see
org.jboss.dna.graph.request.processor.RequestProcessor#process(org.jboss.dna.graph.request.GetWorkspacesRequest)
- */
- @Override
- public void process( GetWorkspacesRequest request ) {
- Set<String> names = repository.getWorkspaceNames();
- request.setAvailableWorkspaceNames(new HashSet<String>(names));
- setCacheableInfo(request);
- }
-
- /**
- * {@inheritDoc}
- *
- * @see
org.jboss.dna.graph.request.processor.RequestProcessor#process(org.jboss.dna.graph.request.VerifyWorkspaceRequest)
- */
- @Override
- public void process( VerifyWorkspaceRequest request ) {
- InMemoryRepository.Workspace original = getWorkspace(request,
request.workspaceName());
- if (original != null) {
- Path path =
getExecutionContext().getValueFactories().getPathFactory().createRootPath();
- request.setActualRootLocation(Location.create(path,
original.getRoot().getUuid()));
- request.setActualWorkspaceName(original.getName());
- }
- }
-
- /**
- * {@inheritDoc}
- *
- * @see
org.jboss.dna.graph.request.processor.RequestProcessor#process(org.jboss.dna.graph.request.CloneWorkspaceRequest)
- */
- @Override
- public void process( CloneWorkspaceRequest request ) {
- // Find the original workspace that we're cloning ...
- final ExecutionContext context = getExecutionContext();
- String targetWorkspaceName = request.desiredNameOfTargetWorkspace();
- String nameOfWorkspaceToBeCloned = request.nameOfWorkspaceToBeCloned();
- InMemoryRepository.Workspace original = repository.getWorkspace(context,
nameOfWorkspaceToBeCloned);
- InMemoryRepository.Workspace target = repository.getWorkspace(context,
targetWorkspaceName);
- if (original == null) {
- switch (request.cloneConflictBehavior()) {
- case DO_NOT_CLONE:
- String msg =
GraphI18n.workspaceDoesNotExistInRepository.text(nameOfWorkspaceToBeCloned,
-
repository.getSourceName());
- request.setError(new InvalidWorkspaceException(msg));
- return;
- case SKIP_CLONE:
- target = repository.createWorkspace(context, targetWorkspaceName,
request.targetConflictBehavior());
- if (target == null) {
- msg =
GraphI18n.workspaceAlreadyExistsInRepository.text(targetWorkspaceName,
repository.getSourceName());
- request.setError(new InvalidWorkspaceException(msg));
- } else {
- InMemoryNode root = target.getRoot();
-
request.setActualRootLocation(Location.create(pathFactory.createRootPath(),
root.getUuid()));
- request.setActualWorkspaceName(target.getName());
- }
- return;
- }
- }
- assert original != null;
- target = repository.createWorkspace(context,
- targetWorkspaceName,
- request.targetConflictBehavior(),
- nameOfWorkspaceToBeCloned);
- if (target == null) {
- // Since the original was there, the only reason the target wasn't
created was because the workspace already existed
- // ...
- String msg =
GraphI18n.workspaceAlreadyExistsInRepository.text(targetWorkspaceName,
repository.getSourceName());
- request.setError(new InvalidWorkspaceException(msg));
- } else {
- InMemoryNode root = target.getRoot();
- request.setActualRootLocation(Location.create(pathFactory.createRootPath(),
root.getUuid()));
- request.setActualWorkspaceName(target.getName());
- recordChange(request);
- }
- }
-
- protected Location getActualLocation( Path path,
- InMemoryNode node ) {
- if (path == null) {
- // Find the path on the node ...
- LinkedList<Path.Segment> segments = new
LinkedList<Path.Segment>();
- InMemoryNode n = node;
- while (n != null) {
- if (n.getParent() == null) break;
- segments.addFirst(n.getName());
- n = n.getParent();
- }
- path = pathFactory.createAbsolutePath(segments);
- }
- return Location.create(path, node.getUuid());
- }
-
- protected InMemoryRepository.Workspace getWorkspace( Request request,
- String workspaceName ) {
- // Get the workspace for this request ...
- InMemoryRepository.Workspace workspace =
repository.getWorkspace(getExecutionContext(), workspaceName);
- if (workspace == null) {
- String msg = GraphI18n.workspaceDoesNotExistInRepository.text(workspaceName,
repository.getSourceName());
- request.setError(new InvalidWorkspaceException(msg));
- }
- return workspace;
- }
-
- protected InMemoryNode getTargetNode( InMemoryRepository.Workspace workspace,
- Request request,
- Location location ) {
- if (workspace == null) return null;
- // Check first for the UUID ...
- InMemoryNode node = null;
- UUID uuid = location.getUuid();
- if (uuid != null) {
- node = workspace.getNode(uuid);
- }
- Path path = null;
- if (node == null) {
- // Look up the node with the supplied path ...
- path = location.getPath();
- if (path != null) {
- node = workspace.getNode(path);
- }
- }
- if (node == null && request != null) {
- if (path == null) {
- if (uuid == null) {
- // Missing both path and UUID ...
- I18n msg = GraphI18n.inMemoryConnectorRequestsMustHavePathOrUuid;
- request.setError(new IllegalArgumentException(msg.text()));
- return null;
- }
- // Missing path, and could not find by UUID ...
- request.setError(new PathNotFoundException(location,
pathFactory.createRootPath(),
-
GraphI18n.inMemoryNodeDoesNotExist.text(path)));
- return null;
- }
- // Could not find the node given the supplied path, so find the lowest path
that does exist ...
- Path lowestExisting = workspace.getLowestExistingPath(path);
- request.setError(new PathNotFoundException(location, lowestExisting,
GraphI18n.inMemoryNodeDoesNotExist.text(path)));
- }
- return node;
- }
-}
Added:
trunk/dna-graph/src/main/java/org/jboss/dna/graph/connector/map/AbstractMapWorkspace.java
===================================================================
---
trunk/dna-graph/src/main/java/org/jboss/dna/graph/connector/map/AbstractMapWorkspace.java
(rev 0)
+++
trunk/dna-graph/src/main/java/org/jboss/dna/graph/connector/map/AbstractMapWorkspace.java 2009-06-27
02:54:06 UTC (rev 1065)
@@ -0,0 +1,642 @@
+/*
+ * 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.connector.map;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.ListIterator;
+import java.util.Map;
+import java.util.Set;
+import java.util.UUID;
+import org.jboss.dna.graph.ExecutionContext;
+import org.jboss.dna.graph.connector.UuidAlreadyExistsException;
+import org.jboss.dna.graph.property.Name;
+import org.jboss.dna.graph.property.NamespaceRegistry;
+import org.jboss.dna.graph.property.Path;
+import org.jboss.dna.graph.property.PathFactory;
+import org.jboss.dna.graph.property.Property;
+import org.jboss.dna.graph.property.PropertyFactory;
+import org.jboss.dna.graph.property.PropertyType;
+import org.jboss.dna.graph.property.Reference;
+import org.jboss.dna.graph.property.UuidFactory;
+import org.jboss.dna.graph.property.ValueFactory;
+import org.jboss.dna.graph.property.basic.RootPath;
+import org.jboss.dna.graph.request.UuidConflictBehavior;
+
+/**
+ * A default implementation of {@link MapWorkspace} that only requires the user to
implement some simple, map-like operations.
+ */
+public abstract class AbstractMapWorkspace implements MapWorkspace {
+
+ private final MapRepository repository;
+ private final String name;
+
+ protected AbstractMapWorkspace( MapRepository repository,
+ String name ) {
+ assert repository != null;
+ assert name != null;
+
+ this.repository = repository;
+ this.name = name;
+ }
+
+ protected void initialize() {
+
+ // Create the root node ...
+ MapNode root = createMapNode(repository.getRootNodeUuid());
+ assert root != null;
+ addNodeToMap(root);
+
+ }
+
+ /**
+ * Adds the given node to the backing map, replacing any node already in the backing
map with the same UUID.
+ *
+ * @param node the node to add to the map; may not be null
+ */
+ protected abstract void addNodeToMap( MapNode node );
+
+ /**
+ * Removes the node with the given UUID from the backing map, returning the node if
it exists
+ *
+ * @param nodeUuid the UUID of the node to replace; may not be null
+ * @return if a node with that UUID exists in the backing map (prior to removal),
that node is returned; otherwise null
+ */
+ protected abstract MapNode removeNodeFromMap( UUID nodeUuid );
+
+ /**
+ * Removes all of the nodes from the backing map
+ */
+ protected abstract void removeAllNodesFromMap();
+
+ /**
+ * Gets the node with the given UUID from the backing map, if one exists
+ *
+ * @param nodeUuid the UUID of the node to be retrieved; may not be null
+ * @return the node that exists in the backing map with the given UUID
+ */
+ public abstract MapNode getNode( UUID nodeUuid );
+
+ /**
+ * Creates an empty {@link MapNode node} with the given UUID.
+ * <p>
+ * This method does not add the new map node to the map. That must be done with a
separate call to
+ * {@link #addNodeToMap(MapNode)}.
+ * </p>
+ *
+ * @param uuid the UUID that identifies the new node; may not be null
+ * @return the new node with the given UUID
+ */
+ protected MapNode createMapNode( UUID uuid ) {
+ assert uuid != null;
+ return new MapNode(uuid);
+ }
+
+ /**
+ * @return name
+ */
+ public String getName() {
+ return name;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see MapWorkspace#getRoot()
+ */
+ public MapNode getRoot() {
+ return getNode(repository.getRootNodeUuid());
+ }
+
+ /**
+ * Find a node with the given path.
+ *
+ * @param context the execution context to use to convert {@code path} to a {@link
Path}; may not be null
+ * @param path the path to the node; may not be null
+ * @return the node with the path, or null if the node does not exist
+ */
+ public MapNode getNode( ExecutionContext context,
+ String path ) {
+ assert context != null;
+ assert path != null;
+ return getNode(context.getValueFactories().getPathFactory().create(path));
+ }
+
+ /**
+ * Find a node with the given path.
+ *
+ * @param path the path to the node; may not be null
+ * @return the node with the path, or null if the node does not exist
+ */
+ public MapNode getNode( Path path ) {
+ assert path != null;
+ MapNode node = getRoot();
+ for (Path.Segment segment : path) {
+ MapNode desiredChild = null;
+ for (MapNode child : node.getChildren()) {
+ if (child == null) continue;
+ Path.Segment childName = child.getName();
+ if (childName == null) continue;
+ if (childName.equals(segment)) {
+ desiredChild = child;
+ break;
+ }
+ }
+ if (desiredChild != null) {
+ node = desiredChild;
+ } else {
+ return null;
+ }
+ }
+ return node;
+ }
+
+ /**
+ * Returns the absolute path to the given node
+ *
+ * @param pathFactory the path factory to use to create the path from the list of
names of all of the nodes on the path from
+ * the root node to the given node
+ * @param node the node for which the path should be returned
+ * @return the absolute path to the given node
+ */
+ public Path pathFor( PathFactory pathFactory,
+ MapNode node ) {
+ assert node != null;
+ assert pathFactory != null;
+
+ LinkedList<Path.Segment> segments = new LinkedList<Path.Segment>();
+ MapNode root = getRoot();
+
+ do {
+ segments.addFirst(node.getName());
+ node = node.getParent();
+ } while (!node.equals(root));
+
+ return pathFactory.createAbsolutePath(segments);
+ }
+
+ /**
+ * Find the lowest existing node along the path.
+ *
+ * @param path the path to the node; may not be null
+ * @return the lowest existing node along the path, or the root node if no node
exists on the path
+ */
+ public Path getLowestExistingPath( Path path ) {
+ assert path != null;
+ MapNode node = getRoot();
+ int segmentNumber = 0;
+ for (Path.Segment segment : path) {
+ MapNode desiredChild = null;
+ for (MapNode child : node.getChildren()) {
+ if (child == null) continue;
+ Path.Segment childName = child.getName();
+ if (childName == null) continue;
+ if (childName.equals(segment)) {
+ desiredChild = child;
+ break;
+ }
+ }
+ if (desiredChild != null) {
+ node = desiredChild;
+ } else {
+ return path.subpath(0, segmentNumber);
+ }
+ ++segmentNumber;
+ }
+ return RootPath.INSTANCE;
+ }
+
+ /**
+ * Removes the given node and its children, correcting the SNS and child indices for
its parent.
+ *
+ * @param context the current execution context
+ * @param node the node to be removed
+ */
+ public void removeNode( ExecutionContext context,
+ MapNode node ) {
+ assert context != null;
+ assert node != null;
+ if (getRoot().equals(node)) {
+ removeAllNodesFromMap();
+ // Recreate the root node ...
+ addNodeToMap(createMapNode(repository.getRootNodeUuid()));
+ return;
+ }
+ MapNode parent = node.getParent();
+ assert parent != null;
+ parent.getChildren().remove(node);
+ correctSameNameSiblingIndexes(context, parent, node.getName().getName());
+ removeUuidReference(node);
+ }
+
+ /**
+ * Recursively removes the given node and its children from the backing map
+ *
+ * @param node the root of the branch to be removed
+ */
+ protected void removeUuidReference( MapNode node ) {
+ assert node != null;
+ removeNodeFromMap(node.getUuid());
+
+ for (MapNode child : node.getChildren()) {
+ removeUuidReference(child);
+ }
+ }
+
+ /**
+ * Create a node at the supplied path. The parent of the new node must already
exist.
+ *
+ * @param context the environment; may not be null
+ * @param pathToNewNode the path to the new node; may not be null
+ * @return the new node (or root if the path specified the root)
+ */
+ public MapNode createNode( ExecutionContext context,
+ String pathToNewNode ) {
+ assert context != null;
+ assert pathToNewNode != null;
+ Path path = context.getValueFactories().getPathFactory().create(pathToNewNode);
+ if (path.isRoot()) return getRoot();
+ Path parentPath = path.getParent();
+ MapNode parentNode = getNode(parentPath);
+ Name name = path.getLastSegment().getName();
+ return createNode(context, parentNode, name, null);
+ }
+
+ /**
+ * Create a new node with the supplied name, as a child of the supplied parent.
+ *
+ * @param context the execution context
+ * @param parentNode the parent node; may not be null
+ * @param name the name; may not be null
+ * @param uuid the UUID of the node, or null if the UUID is to be generated
+ * @return the new node
+ */
+ public MapNode createNode( ExecutionContext context,
+ MapNode parentNode,
+ Name name,
+ UUID uuid ) {
+ assert context != null;
+ assert name != null;
+ if (parentNode == null) parentNode = getRoot();
+ if (uuid == null) uuid = UUID.randomUUID();
+
+ MapNode node = createMapNode(uuid);
+ addNodeToMap(node);
+
+ node.setParent(parentNode);
+ // Find the last node with this same name ...
+ int nextIndex = 1;
+ if (parentNode.existingNames.contains(name)) {
+ ListIterator<MapNode> iter =
parentNode.getChildren().listIterator(parentNode.getChildren().size());
+ while (iter.hasPrevious()) {
+ MapNode prev = iter.previous();
+ if (prev.getName().getName().equals(name)) {
+ nextIndex = prev.getName().getIndex() + 1;
+ break;
+ }
+ }
+ }
+ Path.Segment newName =
context.getValueFactories().getPathFactory().createSegment(name, nextIndex);
+ node.setName(newName);
+ parentNode.getChildren().add(node);
+ parentNode.existingNames.add(name);
+ return node;
+ }
+
+ /**
+ * Move the supplied node to the new parent. This method automatically removes the
node from its existing parent, and also
+ * correctly adjusts the {@link Path.Segment#getIndex() index} to be correct in the
new parent.
+ *
+ * @param context
+ * @param node the node to be moved; may not be the {@link
AbstractMapWorkspace#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
AbstractMapWorkspace#getRoot() root}
+ * @param beforeNode the node before which this new node should be placed
+ */
+ public void moveNode( ExecutionContext context,
+ MapNode node,
+ Name desiredNewName,
+ MapWorkspace newWorkspace,
+ MapNode newParent,
+ MapNode beforeNode ) {
+ assert context != null;
+ assert newParent != null;
+ assert node != null;
+ assert newWorkspace instanceof AbstractMapWorkspace;
+
+ AbstractMapWorkspace newAbstractMapWorkspace =
(AbstractMapWorkspace)newWorkspace;
+
+ // Why was this restriction here? -- BRC
+ // assert newAbstractMapWorkspace.getRoot().equals(newParent) != true;
+ assert this.getRoot().equals(node) != true;
+ MapNode oldParent = node.getParent();
+ Name oldName = node.getName().getName();
+ if (oldParent != null) {
+ boolean removed = oldParent.getChildren().remove(node);
+ assert removed == true;
+ node.setParent(null);
+ correctSameNameSiblingIndexes(context, oldParent, oldName);
+ }
+ node.setParent(newParent);
+ Name newName = oldName;
+ if (desiredNewName != null) {
+ newName = desiredNewName;
+
node.setName(context.getValueFactories().getPathFactory().createSegment(desiredNewName,
1));
+ }
+
+ if (beforeNode == null) {
+ newParent.getChildren().add(node);
+ } else {
+ int index = newParent.getChildren().indexOf(beforeNode);
+ newParent.getChildren().add(index, node);
+ }
+ correctSameNameSiblingIndexes(context, newParent, newName);
+
+ // If the node was moved to a new workspace...
+ if (!this.equals(newAbstractMapWorkspace)) {
+ // We need to remove the node from this workspace's map of nodes ...
+ this.moveNodeToWorkspace(node, newAbstractMapWorkspace);
+ }
+ }
+
+ /**
+ * Moves the branch rooted at the given node to the new workspace, removing it from
this workspace. If a node with any of the
+ * UUIDs in the branch already exists in the new workspace, it will be replaced by
the node from the branch.
+ *
+ * @param node the root node of the branch to be moved
+ * @param newWorkspace the workspace to which the branch should be moved
+ */
+ protected void moveNodeToWorkspace( MapNode node,
+ AbstractMapWorkspace newWorkspace ) {
+ assert getNode(node.getUuid()) != null;
+ assert newWorkspace.getNode(node.getUuid()) == null;
+
+ removeNodeFromMap(node.getUuid());
+ newWorkspace.addNodeToMap(node);
+
+ for (MapNode child : node.getChildren()) {
+ moveNodeToWorkspace(child, newWorkspace);
+ }
+ }
+
+ /**
+ * This should copy the subgraph given by the original node and place the new copy
under the supplied new parent. Note that
+ * internal references between nodes within the original subgraph must be reflected
as internal nodes within the new subgraph.
+ *
+ * @param context the context; may not be null
+ * @param original the node to be copied; may not be null
+ * @param newWorkspace the workspace containing the new parent node; may not be null
+ * @param newParent the parent where the copy is to be placed; may not be null
+ * @param desiredName the desired name for the node; if null, the name will be
obtained from the original node
+ * @param recursive true if the copy should be recursive
+ * @param uuidConflictBehavior the behavior to use if a UUID in the branch rooted at
{@code original} already exists in the
+ * new workspace
+ * @return the new node, which is the top of the new subgraph
+ */
+ public MapNode copyNode( ExecutionContext context,
+ MapNode original,
+ MapWorkspace newWorkspace,
+ MapNode newParent,
+ Name desiredName,
+ boolean recursive,
+ UuidConflictBehavior uuidConflictBehavior ) throws
UuidAlreadyExistsException {
+ Map<UUID, UUID> copyMap = null;
+ Set<UUID> uuidsInFromBranch = null;
+
+ switch (uuidConflictBehavior) {
+ case ALWAYS_CREATE_NEW_UUID:
+
+ /*
+ * The copyNode method uses the presence of a non-null map as an
indicator that new UUIDs should be created
+ * during the copy operation
+ */
+ copyMap = new HashMap<UUID, UUID>();
+ break;
+ case REPLACE_EXISTING_NODE:
+ uuidsInFromBranch = getUuidsUnderNode(original);
+
+ for (UUID uuid : uuidsInFromBranch) {
+ MapNode existing;
+ if (null != (existing = newWorkspace.getNode(uuid))) {
+ newWorkspace.removeNode(context, existing);
+ }
+ }
+ break;
+ case THROW_EXCEPTION:
+ uuidsInFromBranch = getUuidsUnderNode(original);
+ PathFactory pathFactory = context.getValueFactories().getPathFactory();
+ for (UUID uuid : uuidsInFromBranch) {
+ MapNode existing;
+ if (null != (existing = newWorkspace.getNode(uuid))) {
+ NamespaceRegistry namespaces = context.getNamespaceRegistry();
+ String path = newWorkspace.pathFor(pathFactory,
existing).getString(namespaces);
+ throw new UuidAlreadyExistsException(repository.getSourceName(),
uuid, path, newWorkspace.getName());
+ }
+ }
+ break;
+
+ default:
+ throw new IllegalStateException("Unexpected UUID conflict behavior:
" + uuidConflictBehavior);
+ }
+
+ return copyNode(context, original, newWorkspace, newParent, desiredName, true,
copyMap);
+ }
+
+ /**
+ * This should copy the subgraph given by the original node and place the new copy
under the supplied new parent. Note that
+ * internal references between nodes within the original subgraph must be reflected
as internal nodes within the new subgraph.
+ *
+ * @param context the context; may not be null
+ * @param original the node to be copied; may not be null
+ * @param newWorkspace the workspace containing the new parent node; may not be null
+ * @param newParent the parent where the copy is to be placed; may not be null
+ * @param desiredName the desired name for the node; if null, the name will be
obtained from the original node
+ * @param recursive true if the copy should be recursive
+ * @param oldToNewUuids the map of UUIDs of nodes in the new subgraph keyed by the
UUIDs of nodes in the original; may be null
+ * if the UUIDs are to be maintained
+ * @return the new node, which is the top of the new subgraph
+ */
+ protected MapNode copyNode( ExecutionContext context,
+ MapNode original,
+ MapWorkspace newWorkspace,
+ MapNode newParent,
+ Name desiredName,
+ boolean recursive,
+ Map<UUID, UUID> oldToNewUuids ) {
+ assert context != null;
+ assert original != null;
+ assert newParent != null;
+ assert newWorkspace != null;
+ boolean reuseUuids = oldToNewUuids == null;
+
+ // Get or create the new node ...
+ Name childName = desiredName != null ? desiredName :
original.getName().getName();
+ UUID uuidForCopy = reuseUuids ? original.getUuid() : UUID.randomUUID();
+ MapNode copy = newWorkspace.createNode(context, newParent, childName,
uuidForCopy);
+ if (!reuseUuids) {
+ oldToNewUuids.put(original.getUuid(), copy.getUuid());
+ }
+
+ // Copy the properties ...
+ copy.getProperties().clear();
+ copy.getProperties().putAll(original.getProperties());
+ if (recursive) {
+ // Loop over each child and call this method ...
+ for (MapNode child : original.getChildren()) {
+ copyNode(context, child, newWorkspace, copy, null, true, oldToNewUuids);
+ }
+ }
+
+ if (!reuseUuids) {
+ // Now, adjust any references in the new subgraph to objects in the original
subgraph
+ // (because they were internal references, and need to be internal to the new
subgraph)
+ PropertyFactory propertyFactory = context.getPropertyFactory();
+ UuidFactory uuidFactory = context.getValueFactories().getUuidFactory();
+ ValueFactory<Reference> referenceFactory =
context.getValueFactories().getReferenceFactory();
+ for (Map.Entry<UUID, UUID> oldToNew : oldToNewUuids.entrySet()) {
+ MapNode oldNode = this.getNode(oldToNew.getKey());
+ MapNode newNode = newWorkspace.getNode(oldToNew.getValue());
+ assert oldNode != null;
+ assert newNode != null;
+ // Iterate over the properties of the new ...
+ for (Map.Entry<Name, Property> entry :
newNode.getProperties().entrySet()) {
+ Property property = entry.getValue();
+ // Now see if any of the property values are references ...
+ List<Object> newValues = new ArrayList<Object>();
+ boolean foundReference = false;
+ for (Iterator<?> iter = property.getValues(); iter.hasNext();)
{
+ Object value = iter.next();
+ PropertyType type = PropertyType.discoverType(value);
+ if (type == PropertyType.REFERENCE) {
+ UUID oldReferencedUuid = uuidFactory.create(value);
+ UUID newReferencedUuid =
oldToNewUuids.get(oldReferencedUuid);
+ if (newReferencedUuid != null) {
+
newValues.add(referenceFactory.create(newReferencedUuid));
+ foundReference = true;
+ }
+ } else {
+ newValues.add(value);
+ }
+ }
+ // If we found at least one reference, we have to build a new
Property object ...
+ if (foundReference) {
+ Property newProperty = propertyFactory.create(property.getName(),
newValues);
+ entry.setValue(newProperty);
+ }
+ }
+ }
+ }
+
+ return copy;
+ }
+
+ /**
+ * Returns all of the UUIDs in the branch rooted at {@code node}
+ *
+ * @param node the root of the branch
+ * @return all of the UUIDs in the branch rooted at {@code node}
+ */
+ public Set<UUID> getUuidsUnderNode( MapNode node ) {
+ Set<UUID> uuids = new HashSet<UUID>();
+ uuidsUnderNode(node, uuids);
+
+ return uuids;
+ }
+
+ private void uuidsUnderNode( MapNode node,
+ Set<UUID> accumulator ) {
+ accumulator.add(node.getUuid());
+
+ for (MapNode child : node.getChildren()) {
+ uuidsUnderNode(child, accumulator);
+ }
+ }
+
+ /**
+ * Corrects the SNS indices for all children of the node with the given name
+ *
+ * @param context the execution context
+ * @param parentNode the parent node
+ * @param name the name of the child nodes for which the SNS indices should be
recalculated
+ */
+ protected void correctSameNameSiblingIndexes( ExecutionContext context,
+ MapNode parentNode,
+ Name name ) {
+ if (parentNode == null) return;
+ // Look for the highest existing index ...
+ List<MapNode> childrenWithSameNames = new LinkedList<MapNode>();
+ for (MapNode child : parentNode.getChildren()) {
+ if (child.getName().getName().equals(name))
childrenWithSameNames.add(child);
+ }
+ if (childrenWithSameNames.size() == 0) return;
+ if (childrenWithSameNames.size() == 1) {
+ MapNode childWithSameName = childrenWithSameNames.get(0);
+ Path.Segment newName =
context.getValueFactories().getPathFactory().createSegment(name, Path.DEFAULT_INDEX);
+ childWithSameName.setName(newName);
+ return;
+ }
+ int index = 1;
+ for (MapNode childWithSameName : childrenWithSameNames) {
+ Path.Segment segment = childWithSameName.getName();
+ if (segment.getIndex() != index) {
+ Path.Segment newName =
context.getValueFactories().getPathFactory().createSegment(name, index);
+ childWithSameName.setName(newName);
+ }
+ ++index;
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see java.lang.Object#equals(java.lang.Object)
+ */
+ @Override
+ public boolean equals( Object obj ) {
+ if (obj == this) return true;
+ if (obj instanceof AbstractMapWorkspace) {
+ AbstractMapWorkspace that = (AbstractMapWorkspace)obj;
+ // Assume the workspaces are in the same repository ...
+ if (!this.name.equals(that.name)) return false;
+ return true;
+ }
+ return false;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see java.lang.Object#toString()
+ */
+ @Override
+ public String toString() {
+ return repository.getSourceName() + "/" + this.getName();
+ }
+
+}
Property changes on:
trunk/dna-graph/src/main/java/org/jboss/dna/graph/connector/map/AbstractMapWorkspace.java
___________________________________________________________________
Name: svn:keywords
+ Id Revision
Name: svn:eol-style
+ LF
Added: trunk/dna-graph/src/main/java/org/jboss/dna/graph/connector/map/MapNode.java
===================================================================
--- trunk/dna-graph/src/main/java/org/jboss/dna/graph/connector/map/MapNode.java
(rev 0)
+++
trunk/dna-graph/src/main/java/org/jboss/dna/graph/connector/map/MapNode.java 2009-06-27
02:54:06 UTC (rev 1065)
@@ -0,0 +1,202 @@
+/*
+ * 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.connector.map;
+
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.LinkedList;
+import java.util.Map;
+import java.util.Set;
+import java.util.UUID;
+import org.jboss.dna.graph.ExecutionContext;
+import org.jboss.dna.graph.property.Name;
+import org.jboss.dna.graph.property.NameFactory;
+import org.jboss.dna.graph.property.Path;
+import org.jboss.dna.graph.property.Property;
+import org.jboss.dna.graph.property.PropertyFactory;
+
+public class MapNode {
+
+ private final UUID uuid;
+ private MapNode parent;
+ private Path.Segment name;
+ private final Map<Name, Property> properties = new HashMap<Name,
Property>();
+ private final LinkedList<MapNode> children = new LinkedList<MapNode>();
+ final Set<Name> existingNames = new HashSet<Name>();
+
+ public MapNode( UUID uuid ) {
+ assert uuid != null;
+ this.uuid = uuid;
+ }
+
+ /* (non-Javadoc)
+ * @see org.jboss.dna.graph.connector.map.MapNode#getUuid()
+ */
+ public UUID getUuid() {
+ return uuid;
+ }
+
+ /* (non-Javadoc)
+ * @see org.jboss.dna.graph.connector.map.MapNode#getName()
+ */
+ public Path.Segment getName() {
+ return name;
+ }
+
+ /**
+ * @param name Sets name to the specified value.
+ */
+ public void setName( Path.Segment name ) {
+ this.name = name;
+ }
+
+ public Set<Name> getUniqueChildNames() {
+ return existingNames;
+ }
+
+ /* (non-Javadoc)
+ * @see org.jboss.dna.graph.connector.map.MapNode#getParent()
+ */
+ public MapNode getParent() {
+ return parent;
+ }
+
+ /**
+ * @param parent Sets parent to the specified value.
+ */
+ public void setParent( MapNode parent ) {
+ this.parent = parent;
+ }
+
+ /**
+ * @return children
+ */
+ public LinkedList<MapNode> getChildren() {
+ return children;
+ }
+
+ /**
+ * @return properties
+ */
+ protected Map<Name, Property> getProperties() {
+ return properties;
+ }
+
+ /**
+ * Sets the property with the given name, overwriting any previous property for the
given name
+ *
+ * @param property the property to set
+ * @return this map node
+ */
+ public MapNode setProperty( Property property ) {
+ if (property != null) {
+ this.properties.put(property.getName(), property);
+ }
+ return this;
+ }
+
+ /**
+ * Sets the property with the given name, overwriting any previous property for the
given name
+ *
+ * @param context the current execution context, used to get a {@link NameFactory
name factory} and {@link PropertyFactory
+ * property factory}.
+ * @param name the name of the property
+ * @param values the values for the property
+ * @return this map node
+ */
+ public MapNode setProperty( ExecutionContext context,
+ String name,
+ Object... values ) {
+ PropertyFactory propertyFactory = context.getPropertyFactory();
+ Name propertyName = context.getValueFactories().getNameFactory().create(name);
+ return setProperty(propertyFactory.create(propertyName, values));
+ }
+
+ /**
+ * Returns the named property
+ *
+ * @param context the current execution context, used to get a {@link NameFactory
name factory}
+ * @param name the name of the property to return
+ * @return the property for the given name
+ */
+ public Property getProperty( ExecutionContext context,
+ String name ) {
+ Name propertyName = context.getValueFactories().getNameFactory().create(name);
+ return getProperty(propertyName);
+ }
+
+ /**
+ * Returns the named property
+ *
+ * @param name the name of the property to return
+ * @return the property for the given name
+ */
+ public Property getProperty( Name name ) {
+ return this.properties.get(name);
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see java.lang.Object#hashCode()
+ */
+ @Override
+ public int hashCode() {
+ return uuid.hashCode();
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see java.lang.Object#equals(java.lang.Object)
+ */
+ @Override
+ public boolean equals( Object obj ) {
+ if (obj == this) return true;
+ if (obj instanceof MapNode) {
+ MapNode that = (MapNode)obj;
+ if (!this.getUuid().equals(that.getUuid())) return false;
+ return true;
+ }
+ return false;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see java.lang.Object#toString()
+ */
+ @Override
+ public String toString() {
+ StringBuilder sb = new StringBuilder();
+ if (this.name == null) {
+ sb.append("");
+ } else {
+ sb.append(this.name);
+ }
+ sb.append(" (").append(uuid).append(")");
+ return sb.toString();
+ }
+
+}
Property changes on:
trunk/dna-graph/src/main/java/org/jboss/dna/graph/connector/map/MapNode.java
___________________________________________________________________
Name: svn:keywords
+ Id Revision
Name: svn:eol-style
+ LF
Added: trunk/dna-graph/src/main/java/org/jboss/dna/graph/connector/map/MapRepository.java
===================================================================
--- trunk/dna-graph/src/main/java/org/jboss/dna/graph/connector/map/MapRepository.java
(rev 0)
+++
trunk/dna-graph/src/main/java/org/jboss/dna/graph/connector/map/MapRepository.java 2009-06-27
02:54:06 UTC (rev 1065)
@@ -0,0 +1,271 @@
+/*
+ * 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.connector.map;
+
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Set;
+import java.util.UUID;
+import java.util.concurrent.locks.ReadWriteLock;
+import java.util.concurrent.locks.ReentrantReadWriteLock;
+import net.jcip.annotations.GuardedBy;
+import org.jboss.dna.common.util.CheckArg;
+import org.jboss.dna.graph.ExecutionContext;
+import org.jboss.dna.graph.request.UuidConflictBehavior;
+import org.jboss.dna.graph.request.CreateWorkspaceRequest.CreateConflictBehavior;
+
+/**
+ * A default implementation of a map-based repository.
+ * <p>
+ * {@code MapRepository} provides means for creating, retrieving, and destroying {@link
MapWorkspace map-based workspaces},
+ * including providing the locking primitives required for safe control of the
workspaces.
+ * </p>
+ */
+public abstract class MapRepository {
+
+ protected final ReadWriteLock lock = new ReentrantReadWriteLock();
+ protected final UUID rootNodeUuid;
+ private final String sourceName;
+ private final String defaultWorkspaceName;
+ private final Map<String, MapWorkspace> workspaces = new HashMap<String,
MapWorkspace>();
+
+ /**
+ * Creates a {@code MapRepository} with the given repository source name, root node
UUID, and a default workspace named
+ * {@code ""} (the empty string).
+ *
+ * @param sourceName the name of the repository source for use in error and
informational messages; may not be null or empty
+ * @param rootNodeUuid the UUID that will be used as the root node UUID for each
workspace in the repository; may not be null
+ * or empty
+ */
+ public MapRepository( String sourceName,
+ UUID rootNodeUuid ) {
+ this(sourceName, rootNodeUuid, null);
+ }
+
+ /**
+ * Creates a {@code MapRepository} with the given repository source name, root node
UUID, and a default workspace with the
+ * given name.
+ *
+ * @param sourceName the name of the repository source for use in error and
informational messages; may not be null or empty
+ * @param rootNodeUuid the UUID that will be used as the root node UUID for each
workspace in the repository; may not be null
+ * or empty
+ * @param defaultWorkspaceName the name of the default, auto-created workspace
+ */
+ public MapRepository( String sourceName,
+ UUID rootNodeUuid,
+ String defaultWorkspaceName ) {
+ CheckArg.isNotEmpty(sourceName, "sourceName");
+ CheckArg.isNotNull(rootNodeUuid, "rootNodeUUID");
+ this.rootNodeUuid = rootNodeUuid;
+ this.sourceName = sourceName;
+ this.defaultWorkspaceName = defaultWorkspaceName != null ? defaultWorkspaceName :
"";
+ }
+
+ /**
+ * Initializes the repository by creating the default workspace.
+ * <p>
+ * Due to the ordering restrictions on constructor chaining, this method cannot be
called until the repository is fully
+ * initialized. <b>This method MUST be called at the end of the constructor by
any class that implements {@code MapRepository}
+ * .</b>
+ */
+ protected void initialize() {
+ // Create the default workspace ...
+ workspaces.put(this.defaultWorkspaceName, createWorkspace(null,
+
this.defaultWorkspaceName,
+
CreateConflictBehavior.DO_NOT_CREATE));
+
+ }
+
+ /**
+ * Returns the UUID used by the root nodes in each workspace.
+ * <p>
+ * Note that the root nodes themselves are distinct objects in each workspace and a
change to the root node of one workspace
+ * does not imply a change to the root nodes of any other workspaces. However, the
JCR specification mandates that all
+ * referenceable root nodes in a repository use a common UUID (in support of node
correspondence); therefore this must be
+ * supported by DNA.
+ *
+ * @return the root node UUID
+ */
+ public final UUID getRootNodeUuid() {
+ return rootNodeUuid;
+ }
+
+ /**
+ * Returns the logical name (as opposed to the class name) of the repository source
that defined this instance of the
+ * repository for use in error, informational, and other contextual messages.
+ *
+ * @return sourceName the logical name for the repository source name
+ */
+ public String getSourceName() {
+ return sourceName;
+ }
+
+ /**
+ * Returns the lock that must be used to ensure consistent access to the repository
+ *
+ * @return lock the lock that must be used to ensure consistent access to the
repository
+ */
+ public ReadWriteLock getLock() {
+ return lock;
+ }
+
+ /**
+ * Returns a list of the names of the currently created workspaces
+ *
+ * @return a list of the names of the currently created workspaces
+ */
+ @GuardedBy( "getLock()" )
+ public Set<String> getWorkspaceNames() {
+ return workspaces.keySet();
+ }
+
+ /**
+ * Returns the workspace with the given name
+ *
+ * @param name the name of the workspace to return
+ * @return the workspace with the given name; may be null if no workspace with the
given name exists
+ */
+ @GuardedBy( "getLock()" )
+ public MapWorkspace getWorkspace( String name ) {
+ if (name == null) name = defaultWorkspaceName;
+ return workspaces.get(name);
+ }
+
+ /**
+ * Creates a new workspace with the given name containing only a root node.
+ * <p>
+ * <b>This method does NOT automatically add the newly created workspace to the
{@link #workspaces workspace map} or check to
+ * see if a workspace already exists in this repository with the same
name.</b>
+ * </p>
+ *
+ * @param context the context in which the workspace is to be created
+ * @param name the name of the workspace
+ * @return the newly created workspace; may not be null
+ */
+ @GuardedBy( "getLock()" )
+ protected abstract MapWorkspace createWorkspace( ExecutionContext context,
+ String name );
+
+ /**
+ * Attempts to create a workspace with the given name with name-collision behavior
determined by the behavior parameter.
+ * <p>
+ * This method will first check to see if a workspace already exists with the given
name. If no such workspace exists, the
+ * method will create a new workspace with the given name, add it to the {@code
#workspaces workspaces map}, and return it. If
+ * a workspace with the requested name already exists and the {@code behavior} is
{@link CreateConflictBehavior#DO_NOT_CREATE}
+ * , this method will return {@code null} without modifying the state of the
repository. If a workspace with the requested
+ * name already exists and the {@code behavior} is {@link
CreateConflictBehavior#CREATE_WITH_ADJUSTED_NAME}, this method will
+ * generate a unique new name for the workspace, create a new workspace with the
given name, added it to the {@code
+ * #workspaces workspaces map}, and return it.
+ *
+ * @param context the context in which the workspace is to be created; may not be
null
+ * @param name the requested name of the workspace. The name of the workspace that is
returned from this method may not be the
+ * same as the requested name; may not be null
+ * @param behavior the behavior to use in case a workspace with the requested name
already exists in the repository
+ * @return the newly created workspace or {@code null} if a workspace with the
requested name already exists in the repository
+ * and {@code behavior == CreateConflictBehavior#DO_NOT_CREATE}.
+ */
+ @GuardedBy( "getLock()" )
+ public MapWorkspace createWorkspace( ExecutionContext context,
+ String name,
+ CreateConflictBehavior behavior ) {
+ String newName = name;
+ boolean conflictingName = workspaces.containsKey(newName);
+ if (conflictingName) {
+ switch (behavior) {
+ case DO_NOT_CREATE:
+ return null;
+ case CREATE_WITH_ADJUSTED_NAME:
+ int counter = 0;
+ do {
+ newName = name + (++counter);
+ } while (workspaces.containsKey(newName));
+ break;
+ }
+ }
+ assert workspaces.containsKey(newName) == false;
+
+ MapWorkspace workspace = createWorkspace(context, name);
+ workspaces.put(name, workspace);
+ return workspace;
+ }
+
+ /**
+ * Attempts to create a workspace with the requested name as in the
+ * {@link #createWorkspace(ExecutionContext, String, CreateConflictBehavior)} method
and then clones the content from the
+ * given source workspace into the new workspace if the creation was successful.
+ * <p>
+ * If no workspace with the name {@code nameOfWorkspaceToClone} exists, the method
will return an empty workspace.
+ * </p>
+ *
+ * @param context the context in which the workspace is to be created; may not be
null
+ * @param name the requested name of the workspace. The name of the workspace that is
returned from this method may not be the
+ * same as the requested name; may not be null
+ * @param existingWorkspaceBehavior the behavior to use in case a workspace with the
requested name already exists in the
+ * repository
+ * @param nameOfWorkspaceToClone the name of the workspace from which the content
should be cloned; may not be null
+ * @return the newly created workspace with an exact copy of the contents from the
workspace named {@code
+ * nameOfWorkspaceToClone} or {@code null} if a workspace with the requested
name already exists in the repository and
+ * {@code behavior == CreateConflictBehavior#DO_NOT_CREATE}.
+ */
+ @GuardedBy( "getLock()" )
+ public MapWorkspace createWorkspace( ExecutionContext context,
+ String name,
+ CreateConflictBehavior
existingWorkspaceBehavior,
+ String nameOfWorkspaceToClone ) {
+ MapWorkspace workspace = createWorkspace(context, name,
existingWorkspaceBehavior);
+ if (workspace == null) {
+ // Unable to create because of a duplicate name ...
+ return null;
+ }
+ MapWorkspace original = getWorkspace(nameOfWorkspaceToClone);
+ if (original != null) {
+ // Copy the properties of the root node ...
+ MapNode root = workspace.getRoot();
+ MapNode origRoot = original.getRoot();
+ root.getProperties().clear();
+ root.getProperties().putAll(origRoot.getProperties());
+
+ // Loop over each child and call this method to copy the immediate children
(and below).
+ // Note that this makes the copy have the same UUID as the original.
+ for (MapNode originalNode : origRoot.getChildren()) {
+ original.copyNode(context, originalNode, workspace, root,
originalNode.getName().getName(), true, UuidConflictBehavior.REPLACE_EXISTING_NODE);
+ }
+ }
+
+ workspaces.put(name, workspace);
+ return workspace;
+ }
+
+ /**
+ * Removes the named workspace from the {@code #workspaces workspaces map}.
+ *
+ * @param name the name of the workspace to remove
+ * @return {@code true} if a workspace with that name previously existed in the map
+ */
+ @GuardedBy( "getLock()" )
+ public boolean destroyWorkspace( String name ) {
+ return workspaces.remove(name) != null;
+ }
+
+}
Property changes on:
trunk/dna-graph/src/main/java/org/jboss/dna/graph/connector/map/MapRepository.java
___________________________________________________________________
Name: svn:keywords
+ Id Revision
Name: svn:eol-style
+ LF
Added:
trunk/dna-graph/src/main/java/org/jboss/dna/graph/connector/map/MapRepositoryConnection.java
===================================================================
---
trunk/dna-graph/src/main/java/org/jboss/dna/graph/connector/map/MapRepositoryConnection.java
(rev 0)
+++
trunk/dna-graph/src/main/java/org/jboss/dna/graph/connector/map/MapRepositoryConnection.java 2009-06-27
02:54:06 UTC (rev 1065)
@@ -0,0 +1,132 @@
+/*
+ * 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.connector.map;
+
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.locks.Lock;
+import javax.transaction.xa.XAResource;
+import org.jboss.dna.common.statistic.Stopwatch;
+import org.jboss.dna.common.util.Logger;
+import org.jboss.dna.graph.ExecutionContext;
+import org.jboss.dna.graph.cache.CachePolicy;
+import org.jboss.dna.graph.connector.RepositoryConnection;
+import org.jboss.dna.graph.connector.RepositorySourceException;
+import org.jboss.dna.graph.request.Request;
+import org.jboss.dna.graph.request.processor.RequestProcessor;
+
+public class MapRepositoryConnection implements RepositoryConnection {
+ private final MapRepositorySource source;
+ private final MapRepository repository;
+
+ public MapRepositoryConnection( MapRepositorySource source,
+ MapRepository repository ) {
+ assert source != null;
+ assert repository != null;
+ this.source = source;
+ this.repository = repository;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public String getSourceName() {
+ return source.getName();
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public CachePolicy getDefaultCachePolicy() {
+ return source.getDefaultCachePolicy();
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public XAResource getXAResource() {
+ return null;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public boolean ping( long time,
+ TimeUnit unit ) {
+ return true;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public void close() {
+ // do nothing
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see
org.jboss.dna.graph.connector.RepositoryConnection#execute(org.jboss.dna.graph.ExecutionContext,
+ * org.jboss.dna.graph.request.Request)
+ */
+ public void execute( ExecutionContext context,
+ Request request ) throws RepositorySourceException {
+ Logger logger = context.getLogger(getClass());
+ Stopwatch sw = null;
+ if (logger.isTraceEnabled()) {
+ sw = new Stopwatch();
+ sw.start();
+ }
+ // Do any commands update/write?
+ RequestProcessor processor = new MapRequestProcessor(context, this.repository,
this.source.getRepositoryContext());
+
+ Lock lock = request.isReadOnly() ? repository.getLock().readLock() :
repository.getLock().writeLock();
+ lock.lock();
+ try {
+ // Obtain the lock and execute the commands ...
+ processor.process(request);
+ } finally {
+ try {
+ processor.close();
+ } finally {
+ lock.unlock();
+ }
+ }
+ if (logger.isTraceEnabled()) {
+ assert sw != null;
+ sw.stop();
+ logger.trace("MapRepositoryConnection.execute(...) took " +
sw.getTotalDuration());
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see java.lang.Object#toString()
+ */
+ @Override
+ public String toString() {
+ return "Connection to the \"" + getSourceName() + "\"
" + repository.getClass().getSimpleName();
+ }
+
+}
Property changes on:
trunk/dna-graph/src/main/java/org/jboss/dna/graph/connector/map/MapRepositoryConnection.java
___________________________________________________________________
Name: svn:keywords
+ Id Revision
Name: svn:eol-style
+ LF
Added:
trunk/dna-graph/src/main/java/org/jboss/dna/graph/connector/map/MapRepositorySource.java
===================================================================
---
trunk/dna-graph/src/main/java/org/jboss/dna/graph/connector/map/MapRepositorySource.java
(rev 0)
+++
trunk/dna-graph/src/main/java/org/jboss/dna/graph/connector/map/MapRepositorySource.java 2009-06-27
02:54:06 UTC (rev 1065)
@@ -0,0 +1,48 @@
+/*
+ * 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.connector.map;
+
+import org.jboss.dna.graph.cache.CachePolicy;
+import org.jboss.dna.graph.connector.RepositoryContext;
+import org.jboss.dna.graph.connector.RepositorySource;
+
+/**
+ * An extension of the {@link RepositorySource} class that provides a {@link CachePolicy
cache policy} and a
+ * {@link RepositoryContext repository context}.
+ */
+public interface MapRepositorySource extends RepositorySource {
+
+ /**
+ * Returns the {@link CachePolicy cache policy} for the repository source
+ * @return the {@link CachePolicy cache policy} for the repository source
+ */
+ CachePolicy getDefaultCachePolicy();
+
+ /**
+ * Returns the {@link RepositoryContext repository context} for the repository
source
+ * @return the {@link RepositoryContext repository context} for the repository
source
+ */
+ RepositoryContext getRepositoryContext();
+
+}
Property changes on:
trunk/dna-graph/src/main/java/org/jboss/dna/graph/connector/map/MapRepositorySource.java
___________________________________________________________________
Name: svn:keywords
+ Id Revision
Name: svn:eol-style
+ LF
Added:
trunk/dna-graph/src/main/java/org/jboss/dna/graph/connector/map/MapRequestProcessor.java
===================================================================
---
trunk/dna-graph/src/main/java/org/jboss/dna/graph/connector/map/MapRequestProcessor.java
(rev 0)
+++
trunk/dna-graph/src/main/java/org/jboss/dna/graph/connector/map/MapRequestProcessor.java 2009-06-27
02:54:06 UTC (rev 1065)
@@ -0,0 +1,485 @@
+/*
+ * 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.connector.map;
+
+import java.util.HashSet;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.UUID;
+import org.jboss.dna.common.i18n.I18n;
+import org.jboss.dna.common.util.CheckArg;
+import org.jboss.dna.graph.DnaLexicon;
+import org.jboss.dna.graph.ExecutionContext;
+import org.jboss.dna.graph.GraphI18n;
+import org.jboss.dna.graph.JcrLexicon;
+import org.jboss.dna.graph.Location;
+import org.jboss.dna.graph.connector.RepositoryContext;
+import org.jboss.dna.graph.property.Name;
+import org.jboss.dna.graph.property.Path;
+import org.jboss.dna.graph.property.PathFactory;
+import org.jboss.dna.graph.property.PathNotFoundException;
+import org.jboss.dna.graph.property.Property;
+import org.jboss.dna.graph.property.PropertyFactory;
+import org.jboss.dna.graph.property.Path.Segment;
+import org.jboss.dna.graph.request.CloneWorkspaceRequest;
+import org.jboss.dna.graph.request.CopyBranchRequest;
+import org.jboss.dna.graph.request.CreateNodeRequest;
+import org.jboss.dna.graph.request.CreateWorkspaceRequest;
+import org.jboss.dna.graph.request.DeleteBranchRequest;
+import org.jboss.dna.graph.request.DestroyWorkspaceRequest;
+import org.jboss.dna.graph.request.GetWorkspacesRequest;
+import org.jboss.dna.graph.request.InvalidWorkspaceException;
+import org.jboss.dna.graph.request.MoveBranchRequest;
+import org.jboss.dna.graph.request.ReadAllChildrenRequest;
+import org.jboss.dna.graph.request.ReadAllPropertiesRequest;
+import org.jboss.dna.graph.request.Request;
+import org.jboss.dna.graph.request.UpdatePropertiesRequest;
+import org.jboss.dna.graph.request.VerifyWorkspaceRequest;
+import org.jboss.dna.graph.request.processor.RequestProcessor;
+
+/**
+ * The default implementation of the {@link RequestProcessor} for map repositories.
+ *
+ */
+public class MapRequestProcessor extends RequestProcessor {
+ private final PathFactory pathFactory;
+ private final PropertyFactory propertyFactory;
+ private final MapRepository repository;
+
+ public MapRequestProcessor( ExecutionContext context,
+ MapRepository repository,
+ RepositoryContext repositoryContext ) {
+ super(repository.getSourceName(), context, repositoryContext != null ?
repositoryContext.getObserver() : null);
+ this.repository = repository;
+ pathFactory = context.getValueFactories().getPathFactory();
+ propertyFactory = context.getPropertyFactory();
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see
org.jboss.dna.graph.request.processor.RequestProcessor#process(org.jboss.dna.graph.request.ReadAllChildrenRequest)
+ */
+ @Override
+ public void process( ReadAllChildrenRequest request ) {
+ MapWorkspace workspace = getWorkspace(request, request.inWorkspace());
+ MapNode node = getTargetNode(workspace, request, request.of());
+ if (node == null) return;
+ Location actualLocation = getActualLocation(request.of().getPath(), node);
+ Path path = actualLocation.getPath();
+ // Get the names of the children ...
+ List<MapNode> children = node.getChildren();
+ for (MapNode child : children) {
+ Segment childName = child.getName();
+ Path childPath = pathFactory.create(path, childName);
+ request.addChild(childPath, propertyFactory.create(DnaLexicon.UUID,
child.getUuid()));
+ }
+ request.setActualLocationOfNode(actualLocation);
+ setCacheableInfo(request);
+ }
+
+ @Override
+ public void process( ReadAllPropertiesRequest request ) {
+ MapWorkspace workspace = getWorkspace(request, request.inWorkspace());
+ MapNode node = getTargetNode(workspace, request, request.at());
+ if (node == null) return;
+ // Get the properties of the node ...
+ Location actualLocation = getActualLocation(request.at().getPath(), node);
+ request.addProperty(propertyFactory.create(DnaLexicon.UUID, node.getUuid()));
+ for (Property property : node.getProperties().values()) {
+ request.addProperty(property);
+ }
+ request.setActualLocationOfNode(actualLocation);
+ setCacheableInfo(request);
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see
org.jboss.dna.graph.request.processor.RequestProcessor#process(org.jboss.dna.graph.request.CopyBranchRequest)
+ */
+ @Override
+ public void process( CopyBranchRequest request ) {
+ MapWorkspace workspace = getWorkspace(request, request.fromWorkspace());
+ MapWorkspace newWorkspace = getWorkspace(request, request.intoWorkspace());
+ if (workspace == null || newWorkspace == null) return;
+ MapNode node = getTargetNode(workspace, request, request.from());
+ if (node == null) return;
+
+ // Look up the new parent, which must exist ...
+ Path newParentPath = request.into().getPath();
+ Name desiredName = request.desiredName();
+ MapNode newParent = newWorkspace.getNode(newParentPath);
+ MapNode newNode = workspace.copyNode(getExecutionContext(),
+ node,
+ newWorkspace,
+ newParent,
+ desiredName,
+ true,
+ request.uuidConflictBehavior());
+ Path newPath =
getExecutionContext().getValueFactories().getPathFactory().create(newParentPath,
newNode.getName());
+ Location oldLocation = getActualLocation(request.from().getPath(), node);
+ Location newLocation = Location.create(newPath, newNode.getUuid());
+ request.setActualLocations(oldLocation, newLocation);
+ recordChange(request);
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see
org.jboss.dna.graph.request.processor.RequestProcessor#process(org.jboss.dna.graph.request.CreateNodeRequest)
+ */
+ @Override
+ public void process( CreateNodeRequest request ) {
+ MapWorkspace workspace = getWorkspace(request, request.inWorkspace());
+ if (workspace == null) return;
+ Path parent = request.under().getPath();
+ CheckArg.isNotNull(parent, "request.under().getPath()");
+ MapNode node = null;
+ // Look up the parent node, which must exist ...
+
+ MapNode parentNode = workspace.getNode(parent);
+ if (parentNode == null) {
+ Path lowestExisting = workspace.getLowestExistingPath(parent);
+ request.setError(new PathNotFoundException(request.under(), lowestExisting,
+
GraphI18n.inMemoryNodeDoesNotExist.text(parent)));
+ return;
+ }
+ UUID uuid = null;
+ for (Property property : request.properties()) {
+ if (property.getName().equals(DnaLexicon.UUID) ||
property.getName().equals(JcrLexicon.UUID)) {
+ uuid =
getExecutionContext().getValueFactories().getUuidFactory().create(property.getValues().next());
+ break;
+ }
+ }
+ switch (request.conflictBehavior()) {
+ case APPEND:
+ case DO_NOT_REPLACE:
+ node = workspace.createNode(getExecutionContext(), parentNode,
request.named(), uuid);
+ break;
+ case REPLACE:
+ // See if the node already exists (this doesn't record an error on
the request) ...
+ node = getTargetNode(workspace, null,
Location.create(pathFactory.create(parent, request.named()), uuid));
+ if (node != null) {
+ workspace.removeNode(getExecutionContext(), node);
+ }
+ node = workspace.createNode(getExecutionContext(), parentNode,
request.named(), uuid);
+ break;
+ case UPDATE:
+ // See if the node already exists (this doesn't record an error on
the request) ...
+ node = getTargetNode(workspace, null,
Location.create(pathFactory.create(parent, request.named()), uuid));
+ if (node == null) {
+ node = workspace.createNode(getExecutionContext(), parentNode,
request.named(), uuid);
+ } // otherwise, we found it and we're setting any properties below
+ break;
+ }
+ assert node != null;
+ Path path =
getExecutionContext().getValueFactories().getPathFactory().create(parent,
node.getName());
+ // Now add the properties to the supplied node ...
+ for (Property property : request.properties()) {
+ Name propName = property.getName();
+ if (property.size() == 0) {
+ node.getProperties().remove(propName);
+ continue;
+ }
+ if (!propName.equals(DnaLexicon.UUID)) {
+ node.getProperties().put(propName, property);
+ }
+ }
+ Location actualLocation = getActualLocation(path, node);
+ request.setActualLocationOfNode(actualLocation);
+ recordChange(request);
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see
org.jboss.dna.graph.request.processor.RequestProcessor#process(org.jboss.dna.graph.request.DeleteBranchRequest)
+ */
+ @Override
+ public void process( DeleteBranchRequest request ) {
+ MapWorkspace workspace = getWorkspace(request, request.inWorkspace());
+ if (workspace == null) return;
+ MapNode node = getTargetNode(workspace, request, request.at());
+ if (node == null) return;
+ workspace.removeNode(getExecutionContext(), node);
+ Location actualLocation = getActualLocation(request.at().getPath(), node);
+ request.setActualLocationOfNode(actualLocation);
+ recordChange(request);
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see
org.jboss.dna.graph.request.processor.RequestProcessor#process(org.jboss.dna.graph.request.MoveBranchRequest)
+ */
+ @Override
+ public void process( MoveBranchRequest request ) {
+ MapWorkspace workspace = getWorkspace(request, request.inWorkspace());
+ if (workspace == null) return;
+
+ MapNode beforeNode = request.before() != null ? getTargetNode(workspace, request,
request.before()) : null;
+ MapNode node = getTargetNode(workspace, request, request.from());
+ if (node == null) return;
+ // Look up the new parent, which must exist ...
+ Path newParentPath;
+
+ if (request.into() != null) {
+ newParentPath = request.into().getPath();
+ } else {
+ // into or before cannot both be null
+ assert beforeNode != null;
+
+ // Build the path from the before node to the root.
+ LinkedList<Path.Segment> segments = new
LinkedList<Path.Segment>();
+ MapNode current = beforeNode.getParent();
+ while (current != workspace.getRoot()) {
+ segments.addFirst(current.getName());
+ current = current.getParent();
+ }
+ newParentPath =
getExecutionContext().getValueFactories().getPathFactory().createAbsolutePath(segments);
+ }
+
+ MapNode newParent = workspace.getNode(newParentPath);
+ workspace.moveNode(getExecutionContext(), node, request.desiredName(), workspace,
newParent, beforeNode);
+ assert node.getParent() == newParent;
+ Path newPath =
getExecutionContext().getValueFactories().getPathFactory().create(newParentPath,
node.getName());
+ Location oldLocation = getActualLocation(request.from().getPath(), node);
+ Location newLocation = Location.create(newPath, node.getUuid());
+ request.setActualLocations(oldLocation, newLocation);
+ recordChange(request);
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see
org.jboss.dna.graph.request.processor.RequestProcessor#process(org.jboss.dna.graph.request.UpdatePropertiesRequest)
+ */
+ @Override
+ public void process( UpdatePropertiesRequest request ) {
+ MapWorkspace workspace = getWorkspace(request, request.inWorkspace());
+ MapNode node = getTargetNode(workspace, request, request.on());
+ if (node == null) return;
+ // Now set (or remove) the properties to the supplied node ...
+ for (Map.Entry<Name, Property> propertyEntry :
request.properties().entrySet()) {
+ Property property = propertyEntry.getValue();
+ if (property == null) {
+ node.getProperties().remove(propertyEntry.getKey());
+ continue;
+ }
+ Name propName = property.getName();
+ if (!propName.equals(DnaLexicon.UUID)) {
+ node.getProperties().put(propName, property);
+ }
+ }
+ Location actualLocation = getActualLocation(request.on().getPath(), node);
+ request.setActualLocationOfNode(actualLocation);
+ recordChange(request);
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see
org.jboss.dna.graph.request.processor.RequestProcessor#process(org.jboss.dna.graph.request.CreateWorkspaceRequest)
+ */
+ @Override
+ public void process( CreateWorkspaceRequest request ) {
+ MapWorkspace workspace = repository.createWorkspace(getExecutionContext(),
+
request.desiredNameOfNewWorkspace(),
+ request.conflictBehavior());
+ if (workspace == null) {
+ String msg =
GraphI18n.workspaceAlreadyExistsInRepository.text(request.desiredNameOfNewWorkspace(),
+
repository.getSourceName());
+ request.setError(new InvalidWorkspaceException(msg));
+ } else {
+ MapNode root = workspace.getRoot();
+ request.setActualRootLocation(Location.create(pathFactory.createRootPath(),
root.getUuid()));
+ request.setActualWorkspaceName(workspace.getName());
+ recordChange(request);
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see
org.jboss.dna.graph.request.processor.RequestProcessor#process(org.jboss.dna.graph.request.DestroyWorkspaceRequest)
+ */
+ @Override
+ public void process( DestroyWorkspaceRequest request ) {
+ MapWorkspace workspace = repository.getWorkspace(request.workspaceName());
+ if (workspace != null) {
+ MapNode root = workspace.getRoot();
+ request.setActualRootLocation(Location.create(pathFactory.createRootPath(),
root.getUuid()));
+ recordChange(request);
+ } else {
+ String msg =
GraphI18n.workspaceDoesNotExistInRepository.text(request.workspaceName(),
repository.getSourceName());
+ request.setError(new InvalidWorkspaceException(msg));
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see
org.jboss.dna.graph.request.processor.RequestProcessor#process(org.jboss.dna.graph.request.GetWorkspacesRequest)
+ */
+ @Override
+ public void process( GetWorkspacesRequest request ) {
+ Set<String> names = repository.getWorkspaceNames();
+ request.setAvailableWorkspaceNames(new HashSet<String>(names));
+ setCacheableInfo(request);
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see
org.jboss.dna.graph.request.processor.RequestProcessor#process(org.jboss.dna.graph.request.VerifyWorkspaceRequest)
+ */
+ @Override
+ public void process( VerifyWorkspaceRequest request ) {
+ MapWorkspace original = getWorkspace(request, request.workspaceName());
+ if (original != null) {
+ Path path =
getExecutionContext().getValueFactories().getPathFactory().createRootPath();
+ request.setActualRootLocation(Location.create(path,
original.getRoot().getUuid()));
+ request.setActualWorkspaceName(original.getName());
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see
org.jboss.dna.graph.request.processor.RequestProcessor#process(org.jboss.dna.graph.request.CloneWorkspaceRequest)
+ */
+ @Override
+ public void process( CloneWorkspaceRequest request ) {
+ // Find the original workspace that we're cloning ...
+ final ExecutionContext context = getExecutionContext();
+ String targetWorkspaceName = request.desiredNameOfTargetWorkspace();
+ String nameOfWorkspaceToBeCloned = request.nameOfWorkspaceToBeCloned();
+ MapWorkspace original = repository.getWorkspace(nameOfWorkspaceToBeCloned);
+ MapWorkspace target = repository.getWorkspace(targetWorkspaceName);
+ if (original == null) {
+ switch (request.cloneConflictBehavior()) {
+ case DO_NOT_CLONE:
+ String msg =
GraphI18n.workspaceDoesNotExistInRepository.text(nameOfWorkspaceToBeCloned,
+
repository.getSourceName());
+ request.setError(new InvalidWorkspaceException(msg));
+ return;
+ case SKIP_CLONE:
+ target = repository.createWorkspace(context, targetWorkspaceName,
request.targetConflictBehavior());
+ if (target == null) {
+ msg =
GraphI18n.workspaceAlreadyExistsInRepository.text(targetWorkspaceName,
repository.getSourceName());
+ request.setError(new InvalidWorkspaceException(msg));
+ } else {
+ MapNode root = target.getRoot();
+
request.setActualRootLocation(Location.create(pathFactory.createRootPath(),
root.getUuid()));
+ request.setActualWorkspaceName(target.getName());
+ }
+ return;
+ }
+ }
+ assert original != null;
+ target = repository.createWorkspace(context,
+ targetWorkspaceName,
+ request.targetConflictBehavior(),
+ nameOfWorkspaceToBeCloned);
+ if (target == null) {
+ // Since the original was there, the only reason the target wasn't
created was because the workspace already existed
+ // ...
+ String msg =
GraphI18n.workspaceAlreadyExistsInRepository.text(targetWorkspaceName,
repository.getSourceName());
+ request.setError(new InvalidWorkspaceException(msg));
+ } else {
+ MapNode root = target.getRoot();
+ request.setActualRootLocation(Location.create(pathFactory.createRootPath(),
root.getUuid()));
+ request.setActualWorkspaceName(target.getName());
+ recordChange(request);
+ }
+ }
+
+ protected Location getActualLocation( Path path,
+ MapNode node ) {
+ if (path == null) {
+ // Find the path on the node ...
+ LinkedList<Path.Segment> segments = new
LinkedList<Path.Segment>();
+ MapNode n = node;
+ while (n != null) {
+ if (n.getParent() == null) break;
+ segments.addFirst(n.getName());
+ n = n.getParent();
+ }
+ path = pathFactory.createAbsolutePath(segments);
+ }
+ return Location.create(path, node.getUuid());
+ }
+
+ protected MapWorkspace getWorkspace( Request request,
+ String workspaceName ) {
+ // Get the workspace for this request ...
+ MapWorkspace workspace = repository.getWorkspace(workspaceName);
+ if (workspace == null) {
+ String msg = GraphI18n.workspaceDoesNotExistInRepository.text(workspaceName,
repository.getSourceName());
+ request.setError(new InvalidWorkspaceException(msg));
+ }
+ return workspace;
+ }
+
+ protected MapNode getTargetNode( MapWorkspace workspace,
+ Request request,
+ Location location ) {
+ if (workspace == null) return null;
+ // Check first for the UUID ...
+ MapNode node = null;
+ UUID uuid = location.getUuid();
+ if (uuid != null) {
+ node = workspace.getNode(uuid);
+ }
+ Path path = null;
+ if (node == null) {
+ // Look up the node with the supplied path ...
+ path = location.getPath();
+ if (path != null) {
+ node = workspace.getNode(path);
+ }
+ }
+ if (node == null && request != null) {
+ if (path == null) {
+ if (uuid == null) {
+ // Missing both path and UUID ...
+ I18n msg = GraphI18n.inMemoryConnectorRequestsMustHavePathOrUuid;
+ request.setError(new IllegalArgumentException(msg.text()));
+ return null;
+ }
+ // Missing path, and could not find by UUID ...
+ request.setError(new PathNotFoundException(location,
pathFactory.createRootPath(),
+
GraphI18n.inMemoryNodeDoesNotExist.text(path)));
+ return null;
+ }
+ // Could not find the node given the supplied path, so find the lowest path
that does exist ...
+ Path lowestExisting = workspace.getLowestExistingPath(path);
+ request.setError(new PathNotFoundException(location, lowestExisting,
GraphI18n.inMemoryNodeDoesNotExist.text(path)));
+ }
+ return node;
+ }
+}
Property changes on:
trunk/dna-graph/src/main/java/org/jboss/dna/graph/connector/map/MapRequestProcessor.java
___________________________________________________________________
Name: svn:keywords
+ Id Revision
Name: svn:eol-style
+ LF
Added: trunk/dna-graph/src/main/java/org/jboss/dna/graph/connector/map/MapWorkspace.java
===================================================================
--- trunk/dna-graph/src/main/java/org/jboss/dna/graph/connector/map/MapWorkspace.java
(rev 0)
+++
trunk/dna-graph/src/main/java/org/jboss/dna/graph/connector/map/MapWorkspace.java 2009-06-27
02:54:06 UTC (rev 1065)
@@ -0,0 +1,172 @@
+/*
+ * 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.connector.map;
+
+import java.util.UUID;
+import org.jboss.dna.graph.ExecutionContext;
+import org.jboss.dna.graph.connector.UuidAlreadyExistsException;
+import org.jboss.dna.graph.property.Name;
+import org.jboss.dna.graph.property.Path;
+import org.jboss.dna.graph.property.PathFactory;
+import org.jboss.dna.graph.request.UuidConflictBehavior;
+
+/**
+ * The {@code MapWorkspace} defines the required methods for workspaces in a {@link
MapRepository map repository}. By default, a
+ * map repository supports multiple workspaces, each equating logically to a map of UUIDs
to {@link MapNode map nodes}.
+ * <p>
+ * As each map node (except the root-node for the workspace) has a non-null parent and a
set of children, the {@link MapNode map
+ * nodes} naturally construct a tree within the workspace.
+ * </p>
+ */
+public interface MapWorkspace {
+
+ /**
+ * Returns the name of the workspace. There can only be one workspace with a given
name per repository.
+ *
+ * @return the name of the workspace
+ */
+ String getName();
+
+ /**
+ * Returns the root node in the workspace. This returns a {@link MapNode map node}
where {@code node.getParent() == null} and
+ * {@code node.getUuid() == repository.getRootNodeUuid()}.
+ *
+ * @return the root node in the workspace
+ */
+ MapNode getRoot();
+
+ /**
+ * Returns the node with the given UUID, if one exists or {@code null} if no
{@MapNode node} with the given UUID
+ * exists in the workspace.
+ * <p>
+ * That is, {@code node == null || node.getUuid().equals(uuid)} for the returned
node.
+ * </p>
+ *
+ * @param uuid the UUID of the node to be retrieved; may not be null
+ * @return the node with the given UUID, if one exists or {@code null} if no
{@MapNode node} with the given UUID
+ * exists in the workspace.
+ */
+ MapNode getNode( UUID uuid );
+
+ /**
+ * Returns the node at the given path, if one exists of {@code null} if no {@MapNode
node} exists at the given path.
+ *
+ * @param path the path of the node to retrieve; may not be null
+ * @return the node at the given path, if one exists of {@code null} if no {@MapNode
node} exists at the given path.
+ */
+ MapNode getNode( Path path );
+
+ /**
+ * Removes the given node. This method will return silently if the given node does
not exist in this workspace.
+ *
+ * @param context the current execution context; may not be null
+ * @param node the node to be removed; may not be null
+ */
+ void removeNode( ExecutionContext context,
+ MapNode node );
+
+ /**
+ * Create a node at the supplied path. The parent of the new node must already
exist.
+ *
+ * @param context the environment; may not be null
+ * @param pathToNewNode the path to the new node; may not be null
+ * @return the new node (or root if the path specified the root)
+ */
+ MapNode createNode( ExecutionContext context,
+ String pathToNewNode );
+
+ /**
+ * Create a new node with the supplied name, as a child of the supplied parent.
+ *
+ * @param context the execution context
+ * @param parentNode the parent node; may not be null
+ * @param name the name; may not be null
+ * @param uuid the UUID of the node, or null if the UUID is to be generated
+ * @return the new node
+ */
+ MapNode createNode( ExecutionContext context,
+ MapNode parentNode,
+ Name name,
+ UUID uuid );
+
+ /**
+ * Move the supplied node to the new parent. This method automatically removes the
node from its existing parent, and also
+ * correctly adjusts the {@link Path.Segment#getIndex() index} to be correct in the
new parent.
+ *
+ * @param context
+ * @param node the node to be moved; may not be the {@link MapWorkspace#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 MapWorkspace#getRoot()
root}
+ * @param beforeNode the node before which this new node should be placed
+ */
+ void moveNode( ExecutionContext context,
+ MapNode node,
+ Name desiredNewName,
+ MapWorkspace newWorkspace,
+ MapNode newParent,
+ MapNode beforeNode );
+
+ /**
+ * This should copy the subgraph given by the original node and place the new copy
under the supplied new parent. Note that
+ * internal references between nodes within the original subgraph must be reflected
as internal nodes within the new subgraph.
+ *
+ * @param context the context; may not be null
+ * @param original the node to be copied; may not be null
+ * @param newWorkspace the workspace containing the new parent node; may not be null
+ * @param newParent the parent where the copy is to be placed; may not be null
+ * @param desiredName the desired name for the node; if null, the name will be
obtained from the original node
+ * @param recursive true if the copy should be recursive
+ * @param uuidConflictBehavior the behavior to use to manage UUIDs from the source
into the target
+ * @return the new node, which is the top of the new subgraph
+ * @throws UuidAlreadyExistsException if {@code uuidConflictBehavior} is true and and
a UUID in the source tree alread exists
+ * in the new workspace
+ */
+ MapNode copyNode( ExecutionContext context,
+ MapNode original,
+ MapWorkspace newWorkspace,
+ MapNode newParent,
+ Name desiredName,
+ boolean recursive,
+ UuidConflictBehavior uuidConflictBehavior ) throws
UuidAlreadyExistsException;
+
+ /**
+ * Find the lowest existing node along the path.
+ *
+ * @param path the path to the node; may not be null
+ * @return the lowest existing node along the path, or the root node if no node
exists on the path
+ */
+ Path getLowestExistingPath( Path path );
+
+ /**
+ * Returns the path for the given node with this workspace if one exists, or a {@code
null} if no node exists at the given
+ * path.
+ *
+ * @param pathFactory the path factory to use to construct the path; may not be null
+ * @param node the node for which the path should be retrieved; may not be null
+ * @return the path for the given node with this workspace if one exists or null if
the node does not exist in this workspace
+ */
+ Path pathFor( PathFactory pathFactory,
+ MapNode node );
+}
Property changes on:
trunk/dna-graph/src/main/java/org/jboss/dna/graph/connector/map/MapWorkspace.java
___________________________________________________________________
Name: svn:keywords
+ Id Revision
Name: svn:eol-style
+ LF
Added: trunk/dna-graph/src/main/java/org/jboss/dna/graph/connector/map/package-info.java
===================================================================
--- trunk/dna-graph/src/main/java/org/jboss/dna/graph/connector/map/package-info.java
(rev 0)
+++
trunk/dna-graph/src/main/java/org/jboss/dna/graph/connector/map/package-info.java 2009-06-27
02:54:06 UTC (rev 1065)
@@ -0,0 +1,72 @@
+/*
+ * JBoss DNA (
http://www.jboss.org/dna)
+ * See the COPYRIGHT.txt file distributed with this work for information
+ * regarding copyright ownership. Some portions may be licensed
+ * to Red Hat, Inc. under one or more contributor license agreements.
+ * See the AUTHORS.txt file in the distribution for a full listing of
+ * individual contributors.
+ *
+ * JBoss DNA is free software. Unless otherwise indicated, all code in JBoss DNA
+ * is licensed to you under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * JBoss DNA is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site:
http://www.fsf.org.
+ */
+/**
+ * The {@link MapRepository} class and its supporting classes provide a default
implementation of the connector
+ * classes for connectors that support the transient or persistent mapping of a UUID to a
{@link MapNode standard
+ * representation of a node}.
+ * To implement a connector based on this framework, one must create an implementation of
{@link MapRepositorySource the repository source},
+ * an implementation of {@link MapRepository the repository itself}, and an
implementation of {@link MapWorkspace the workspace}.
+ * <p>
+ * The {@link MapRepositorySource repository source implementation} contains properties
for the repository configuration and caching policies. A key
+ * method in the {@code MapRepositorySource} implementation if the {@link
org.jboss.dna.graph.connector.RepositorySource#getConnection()} method,
+ * which should generally be implemented using the {@link MapRepositoryConnection default
connection implementation}.
+ * <pre>
+ * if (repository == null) {
+ * repository = new InMemoryRepository(name, rootNodeUuid, defaultWorkspaceName);
+ * }
+ * return new MapRepositoryConnection(this, repository);
+ * </pre>
+ * </p>
+ * <p>
+ * The {@link MapRepository repository implementation} is only required to provide an
implementation of the {@link
MapRepository#createWorkspace(org.jboss.dna.graph.ExecutionContext, String)}
+ * method that returns the appropriate {@link MapWorkspace workspace} implementation for
the connector. However, all constructors for the repository must
+ * call {@link MapRepository#initialize()} after the constructor has completed its
initialization, as demonstrated below:
+ * <pre>
+ * public InMemoryRepository( String sourceName,
+ * UUID rootNodeUuid,
+ * String defaultWorkspaceName ) {
+ * initialize();
+ * }
+ * </pre>
+ * </p>
+ * <p>
+ * Finally, the {@link MapWorkspace workspace implementation} must be created.
Implementors should consider extending the {@link AbstractMapWorkspace} class, which
provides reasonable default implementations (assuming that the backing map provides O(1)
lookups - a sine qua non for maps) for almost
+ * this class imposes a requirement that its {@link AbstractMapWorkspace#initialize()}
method also be called at the end of each constructor, like so:
+ * <pre>
+ * public Workspace( MapRepository repository,
+ * String name ) {
+ * super(repository, name);
+ *
+ * initialize();
+ * }
+ * </pre>
+ * </p>
+ *
+ * @see org.jboss.dna.graph.connector.inmemory.InMemoryRepository
+ * @see org.jboss.dna.graph.connector.inmemory.InMemoryRepositorySource
+ * @see org.jboss.dna.graph.connector.inmemory.InMemoryRepository#Workspace
+ */
+
+package org.jboss.dna.graph.connector.map;
+
Property changes on:
trunk/dna-graph/src/main/java/org/jboss/dna/graph/connector/map/package-info.java
___________________________________________________________________
Name: svn:keywords
+ Id Revision
Name: svn:eol-style
+ LF
Modified:
trunk/dna-graph/src/test/java/org/jboss/dna/graph/connector/inmemory/InMemoryRepositoryTest.java
===================================================================
---
trunk/dna-graph/src/test/java/org/jboss/dna/graph/connector/inmemory/InMemoryRepositoryTest.java 2009-06-24
22:14:12 UTC (rev 1064)
+++
trunk/dna-graph/src/test/java/org/jboss/dna/graph/connector/inmemory/InMemoryRepositoryTest.java 2009-06-27
02:54:06 UTC (rev 1065)
@@ -31,7 +31,8 @@
import static org.junit.matchers.JUnitMatchers.hasItems;
import java.util.UUID;
import org.jboss.dna.graph.ExecutionContext;
-import org.jboss.dna.graph.connector.inmemory.InMemoryRepository.Workspace;
+import org.jboss.dna.graph.connector.map.MapNode;
+import org.jboss.dna.graph.connector.map.MapWorkspace;
import org.jboss.dna.graph.property.Name;
import org.jboss.dna.graph.property.NameFactory;
import org.jboss.dna.graph.property.PathFactory;
@@ -99,7 +100,7 @@
String workspaceName = "New Workspace";
assertThat(repository.createWorkspace(context, workspaceName,
CreateConflictBehavior.DO_NOT_CREATE), is(notNullValue()));
assertThat(repository.getWorkspaceNames(), hasItems(workspaceName));
- Workspace secondWorkspace = repository.createWorkspace(context,
+ MapWorkspace secondWorkspace = repository.createWorkspace(context,
workspaceName,
CreateConflictBehavior.CREATE_WITH_ADJUSTED_NAME);
assertThat(secondWorkspace, is(notNullValue()));
@@ -124,25 +125,25 @@
@Test
public void shouldCloneWorkspaceAndCopyContentsIfWorkspaceWithSpecifiedNameExists()
{
String workspaceName = "Original Workspace";
- Workspace workspace = repository.createWorkspace(context, workspaceName,
CreateConflictBehavior.DO_NOT_CREATE);
+ MapWorkspace workspace = repository.createWorkspace(context, workspaceName,
CreateConflictBehavior.DO_NOT_CREATE);
assertThat(workspace, is(notNullValue()));
assertThat(repository.getWorkspaceNames(), hasItems(workspaceName));
// Populate the workspace with a few nodes ...
- InMemoryNode root = workspace.getRoot();
- InMemoryNode node_a = workspace.createNode(context, root,
nameFactory.create("a"), null);
- InMemoryNode node_b = workspace.createNode(context, node_a,
nameFactory.create("b"), null);
- InMemoryNode node_c = workspace.createNode(context, node_b,
nameFactory.create("c"), null);
- InMemoryNode node_d = workspace.createNode(context, root,
nameFactory.create("d"), null);
- InMemoryNode node_e = workspace.createNode(context, node_d,
nameFactory.create("e"), null);
- InMemoryNode node_b2 = workspace.createNode(context, node_d,
nameFactory.create("b"), null);
+ MapNode root = workspace.getRoot();
+ MapNode node_a = workspace.createNode(context, root,
nameFactory.create("a"), null);
+ MapNode node_b = workspace.createNode(context, node_a,
nameFactory.create("b"), null);
+ MapNode node_c = workspace.createNode(context, node_b,
nameFactory.create("c"), null);
+ MapNode node_d = workspace.createNode(context, root,
nameFactory.create("d"), null);
+ MapNode node_e = workspace.createNode(context, node_d,
nameFactory.create("e"), null);
+ MapNode node_b2 = workspace.createNode(context, node_d,
nameFactory.create("b"), null);
ValueFactory<String> stringFactory =
context.getValueFactories().getStringFactory();
Name propertyName = nameFactory.create("something");
Property property = propertyFactory.create(propertyName,
stringFactory.create("Worth the wait"));
- node_b.getProperties().put(propertyName, property);
+ node_b.setProperty(property);
- assertThat(workspace.getNodesByUuid().size(), is(7));
+ assertThat(((InMemoryRepository.Workspace) workspace).size(), is(7));
assertThat(workspace.getNode(pathFactory.create("/")),
is(sameInstance(workspace.getRoot())));
assertThat(workspace.getNode(pathFactory.create("/a")),
is(sameInstance(node_a)));
assertThat(workspace.getNode(pathFactory.create("/a/b")),
is(sameInstance(node_b)));
@@ -150,11 +151,11 @@
assertThat(workspace.getNode(pathFactory.create("/d")),
is(sameInstance(node_d)));
assertThat(workspace.getNode(pathFactory.create("/d/e")),
is(sameInstance(node_e)));
assertThat(workspace.getNode(pathFactory.create("/d/b")),
is(sameInstance(node_b2)));
-
assertThat(workspace.getNode(pathFactory.create("/a/b")).getProperties().get(propertyName),
is(property));
+
assertThat(workspace.getNode(pathFactory.create("/a/b")).getProperty(propertyName),
is(property));
// Now clone the workspace ...
String newWorkspaceName = "New Workspace";
- Workspace new_workspace = repository.createWorkspace(context,
+ MapWorkspace new_workspace = repository.createWorkspace(context,
newWorkspaceName,
CreateConflictBehavior.DO_NOT_CREATE,
workspaceName);
@@ -162,7 +163,7 @@
assertThat(repository.getWorkspaceNames(), hasItems(workspaceName,
newWorkspaceName));
// Now check that the original workspace still has its content ...
- assertThat(workspace.getNodesByUuid().size(), is(7));
+ assertThat(((InMemoryRepository.Workspace) workspace).size(), is(7));
assertThat(workspace.getNode(pathFactory.create("/")),
is(sameInstance(workspace.getRoot())));
assertThat(workspace.getNode(pathFactory.create("/a")),
is(sameInstance(node_a)));
assertThat(workspace.getNode(pathFactory.create("/a/b")),
is(sameInstance(node_b)));
@@ -170,10 +171,10 @@
assertThat(workspace.getNode(pathFactory.create("/d")),
is(sameInstance(node_d)));
assertThat(workspace.getNode(pathFactory.create("/d/e")),
is(sameInstance(node_e)));
assertThat(workspace.getNode(pathFactory.create("/d/b")),
is(sameInstance(node_b2)));
-
assertThat(workspace.getNode(pathFactory.create("/a/b")).getProperties().get(propertyName),
is(property));
+
assertThat(workspace.getNode(pathFactory.create("/a/b")).getProperty(propertyName),
is(property));
// Now check that the new workspace has its content ...
- assertThat(new_workspace.getNodesByUuid().size(), is(7));
+ assertThat(((InMemoryRepository.Workspace) new_workspace).size(), is(7));
// Since we cloned workspaces, the UUIDs should be the same in each workspace
...
assertThat(workspace.getNode(pathFactory.create("/")).getUuid(),
@@ -195,25 +196,25 @@
@Test
public void
shouldCloneWorkspaceButShouldNotCopyContentsIfWorkspaceWithSpecifiedNameDoesNotExist() {
String workspaceName = "Original Workspace";
- Workspace workspace = repository.createWorkspace(context, workspaceName,
CreateConflictBehavior.DO_NOT_CREATE);
+ MapWorkspace workspace = repository.createWorkspace(context, workspaceName,
CreateConflictBehavior.DO_NOT_CREATE);
assertThat(workspace, is(notNullValue()));
assertThat(repository.getWorkspaceNames(), hasItems(workspaceName));
// Populate the workspace with a few nodes ...
- InMemoryNode root = workspace.getRoot();
- InMemoryNode node_a = workspace.createNode(context, root,
nameFactory.create("a"), null);
- InMemoryNode node_b = workspace.createNode(context, node_a,
nameFactory.create("b"), null);
- InMemoryNode node_c = workspace.createNode(context, node_b,
nameFactory.create("c"), null);
- InMemoryNode node_d = workspace.createNode(context, root,
nameFactory.create("d"), null);
- InMemoryNode node_e = workspace.createNode(context, node_d,
nameFactory.create("e"), null);
- InMemoryNode node_b2 = workspace.createNode(context, node_d,
nameFactory.create("b"), null);
+ MapNode root = workspace.getRoot();
+ MapNode node_a = workspace.createNode(context, root,
nameFactory.create("a"), null);
+ MapNode node_b = workspace.createNode(context, node_a,
nameFactory.create("b"), null);
+ MapNode node_c = workspace.createNode(context, node_b,
nameFactory.create("c"), null);
+ MapNode node_d = workspace.createNode(context, root,
nameFactory.create("d"), null);
+ MapNode node_e = workspace.createNode(context, node_d,
nameFactory.create("e"), null);
+ MapNode node_b2 = workspace.createNode(context, node_d,
nameFactory.create("b"), null);
ValueFactory<String> stringFactory =
context.getValueFactories().getStringFactory();
Name propertyName = nameFactory.create("something");
Property property = propertyFactory.create(propertyName,
stringFactory.create("Worth the wait"));
- node_b.getProperties().put(propertyName, property);
+ node_b.setProperty(property);
- assertThat(workspace.getNodesByUuid().size(), is(7));
+ assertThat(((InMemoryRepository.Workspace) workspace).size(), is(7));
assertThat(workspace.getNode(pathFactory.create("/")),
is(sameInstance(workspace.getRoot())));
assertThat(workspace.getNode(pathFactory.create("/a")),
is(sameInstance(node_a)));
assertThat(workspace.getNode(pathFactory.create("/a/b")),
is(sameInstance(node_b)));
@@ -221,11 +222,11 @@
assertThat(workspace.getNode(pathFactory.create("/d")),
is(sameInstance(node_d)));
assertThat(workspace.getNode(pathFactory.create("/d/e")),
is(sameInstance(node_e)));
assertThat(workspace.getNode(pathFactory.create("/d/b")),
is(sameInstance(node_b2)));
-
assertThat(workspace.getNode(pathFactory.create("/a/b")).getProperties().get(propertyName),
is(property));
+
assertThat(workspace.getNode(pathFactory.create("/a/b")).getProperty(propertyName),
is(property));
// Now clone the workspace ...
String newWorkspaceName = "New Workspace";
- Workspace new_workspace = repository.createWorkspace(context,
+ MapWorkspace new_workspace = repository.createWorkspace(context,
newWorkspaceName,
CreateConflictBehavior.DO_NOT_CREATE,
"non-existant
workspace");
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-06-24
22:14:12 UTC (rev 1064)
+++
trunk/dna-graph/src/test/java/org/jboss/dna/graph/connector/inmemory/InMemoryRepositoryWorkspaceTest.java 2009-06-27
02:54:06 UTC (rev 1065)
@@ -34,7 +34,7 @@
import java.util.Map;
import java.util.UUID;
import org.jboss.dna.graph.ExecutionContext;
-import org.jboss.dna.graph.connector.inmemory.InMemoryRepository.Workspace;
+import org.jboss.dna.graph.connector.map.MapNode;
import org.jboss.dna.graph.property.Name;
import org.jboss.dna.graph.property.NameFactory;
import org.jboss.dna.graph.property.PathFactory;
@@ -75,7 +75,7 @@
rootUuid = UUID.randomUUID();
repository = new InMemoryRepository(repositoryName, rootUuid);
workspaceName = "My Workspace";
- workspace = repository.createWorkspace(context, workspaceName,
CreateConflictBehavior.DO_NOT_CREATE);
+ workspace = (InMemoryRepository.Workspace) repository.createWorkspace(context,
workspaceName, CreateConflictBehavior.DO_NOT_CREATE);
}
@Test
@@ -97,33 +97,33 @@
public void shouldAllowRootToBeRemoved() {
workspace.removeNode(context, workspace.getRoot());
assertThat(workspace.getRoot().getChildren().size(), is(0));
- assertThat(workspace.getRoot().getProperties().size(), is(0));
+ // assertThat(workspace.getRoot().getProperties().size(), is(0));
}
@Test
public void shouldCreateNodesByPath() {
Name name_a = nameFactory.create("a");
- InMemoryNode node_a = workspace.createNode(context, workspace.getRoot(), name_a,
null);
+ MapNode node_a = workspace.createNode(context, workspace.getRoot(), name_a,
null);
assertThat(node_a, is(notNullValue()));
assertThat(node_a.getParent(), is(workspace.getRoot()));
assertThat(node_a.getName().getName(), is(name_a));
assertThat(node_a.getName().hasIndex(), is(false));
Name name_b = nameFactory.create("b");
- InMemoryNode node_b = workspace.createNode(context, node_a, name_b, null);
+ MapNode node_b = workspace.createNode(context, node_a, name_b, null);
assertThat(node_b, is(notNullValue()));
assertThat(node_b.getParent(), is(node_a));
assertThat(node_b.getName().getName(), is(name_b));
assertThat(node_b.getName().hasIndex(), is(false));
Name name_c = nameFactory.create("c");
- InMemoryNode node_c = workspace.createNode(context, node_b, name_c, null);
+ MapNode node_c = workspace.createNode(context, node_b, name_c, null);
assertThat(node_c, is(notNullValue()));
assertThat(node_c.getParent(), is(node_b));
assertThat(node_c.getName().getName(), is(name_c));
assertThat(node_c.getName().hasIndex(), is(false));
- assertThat(workspace.getNodesByUuid().size(), is(4));
+ assertThat(workspace.size(), is(4));
assertThat(workspace.getNode(pathFactory.create("/")),
is(sameInstance(workspace.getRoot())));
assertThat(workspace.getNode(pathFactory.create("/a")),
is(sameInstance(node_a)));
assertThat(workspace.getNode(pathFactory.create("/a/b")),
is(sameInstance(node_b)));
@@ -132,11 +132,11 @@
@Test
public void shouldNotFindNodesThatDoNotExist() {
- InMemoryNode node_a = workspace.createNode(context, workspace.getRoot(),
nameFactory.create("a"), null);
- InMemoryNode node_b = workspace.createNode(context, node_a,
nameFactory.create("b"), null);
+ MapNode node_a = workspace.createNode(context, workspace.getRoot(),
nameFactory.create("a"), null);
+ MapNode node_b = workspace.createNode(context, node_a,
nameFactory.create("b"), null);
/*Node node_c =*/workspace.createNode(context, node_b,
nameFactory.create("c"), null);
- assertThat(workspace.getNodesByUuid().size(), is(4));
+ assertThat(workspace.size(), is(4));
assertThat(workspace.getNode(pathFactory.create("/a")), is(node_a));
assertThat(workspace.getNode(pathFactory.create("/a/b")), is(node_b));
assertThat(workspace.getNode(pathFactory.create("/a[1]")),
is(node_a));
@@ -150,50 +150,50 @@
@Test
public void shouldCorrectlyManageIndexesOfSiblingsWithSameNames() {
Name name_a1 = nameFactory.create("a");
- InMemoryNode node_a1 = workspace.createNode(context, workspace.getRoot(),
name_a1, null);
+ MapNode node_a1 = workspace.createNode(context, workspace.getRoot(), name_a1,
null);
assertThat(node_a1, is(notNullValue()));
assertThat(node_a1.getParent(), is(workspace.getRoot()));
assertThat(node_a1.getName().getName(), is(name_a1));
assertThat(node_a1.getName().hasIndex(), is(false));
Name name_a2 = nameFactory.create("a");
- InMemoryNode node_a2 = workspace.createNode(context, workspace.getRoot(),
name_a2, null);
+ MapNode node_a2 = workspace.createNode(context, workspace.getRoot(), name_a2,
null);
assertThat(node_a2, is(notNullValue()));
assertThat(node_a2.getParent(), is(workspace.getRoot()));
assertThat(node_a2.getName().getName(), is(name_a2));
assertThat(node_a2.getName().hasIndex(), is(true));
assertThat(node_a2.getName().getIndex(), is(2));
- // node 1 should now have an index ...
+ // node 1 should now have an index ..
assertThat(node_a1.getName().getIndex(), is(1));
- // Add another node without the same name ...
+ // Add another node without the same name ..
Name name_b = nameFactory.create("b");
- InMemoryNode node_b = workspace.createNode(context, workspace.getRoot(), name_b,
null);
+ MapNode node_b = workspace.createNode(context, workspace.getRoot(), name_b,
null);
assertThat(node_b, is(notNullValue()));
assertThat(node_b.getParent(), is(workspace.getRoot()));
assertThat(node_b.getName().getName(), is(name_b));
assertThat(node_b.getName().hasIndex(), is(false));
- // Add a third node with the same name ...
+ // Add a third node with the same name ..
Name name_a3 = nameFactory.create("a");
- InMemoryNode node_a3 = workspace.createNode(context, workspace.getRoot(),
name_a3, null);
+ MapNode node_a3 = workspace.createNode(context, workspace.getRoot(), name_a3,
null);
assertThat(node_a3, is(notNullValue()));
assertThat(node_a3.getParent(), is(workspace.getRoot()));
assertThat(node_a3.getName().getName(), is(name_a3));
assertThat(node_a3.getName().hasIndex(), is(true));
assertThat(node_a3.getName().getIndex(), is(3));
- // Check the number of children ...
+ // Check the number of children ..
assertThat(workspace.getRoot().getChildren().size(), is(4));
assertThat(workspace.getRoot().getChildren(), hasItems(node_a1, node_a2, node_b,
node_a3));
- assertThat(workspace.getNodesByUuid().size(), is(5));
+ assertThat(workspace.size(), is(5));
assertThat(workspace.getNode(pathFactory.create("/a[1]")),
is(sameInstance(node_a1)));
assertThat(workspace.getNode(pathFactory.create("/a[2]")),
is(sameInstance(node_a2)));
assertThat(workspace.getNode(pathFactory.create("/a[3]")),
is(sameInstance(node_a3)));
assertThat(workspace.getNode(pathFactory.create("/b")),
is(sameInstance(node_b)));
- // Removing a node with the same name will reduce the index ...
+ // Removing a node with the same name will reduce the index ..
workspace.removeNode(context, node_a2);
assertThat(workspace.getRoot().getChildren().size(), is(3));
assertThat(workspace.getRoot().getChildren(), hasItems(node_a1, node_b,
node_a3));
@@ -201,26 +201,26 @@
assertThat(node_b.getName().hasIndex(), is(false));
assertThat(node_a3.getName().getIndex(), is(2));
- // Removing a node with the same name will reduce the index ...
+ // Removing a node with the same name will reduce the index ..
workspace.removeNode(context, node_a1);
assertThat(workspace.getRoot().getChildren().size(), is(2));
assertThat(workspace.getRoot().getChildren(), hasItems(node_b, node_a3));
assertThat(node_b.getName().hasIndex(), is(false));
assertThat(node_a3.getName().hasIndex(), is(false));
- assertThat(workspace.getNodesByUuid().size(), is(3));
+ assertThat(workspace.size(), is(3));
}
@Test
public void shouldMoveNodesWithinSameWorkspace() {
- InMemoryNode root = workspace.getRoot();
- InMemoryNode node_a = workspace.createNode(context, root,
nameFactory.create("a"), null);
- InMemoryNode node_b = workspace.createNode(context, node_a,
nameFactory.create("b"), null);
- InMemoryNode node_c = workspace.createNode(context, node_b,
nameFactory.create("c"), null);
- InMemoryNode node_d = workspace.createNode(context, root,
nameFactory.create("d"), null);
- InMemoryNode node_e = workspace.createNode(context, node_d,
nameFactory.create("e"), null);
- InMemoryNode node_b2 = workspace.createNode(context, node_d,
nameFactory.create("b"), null);
+ MapNode root = workspace.getRoot();
+ MapNode node_a = workspace.createNode(context, root,
nameFactory.create("a"), null);
+ MapNode node_b = workspace.createNode(context, node_a,
nameFactory.create("b"), null);
+ MapNode node_c = workspace.createNode(context, node_b,
nameFactory.create("c"), null);
+ MapNode node_d = workspace.createNode(context, root,
nameFactory.create("d"), null);
+ MapNode node_e = workspace.createNode(context, node_d,
nameFactory.create("e"), null);
+ MapNode node_b2 = workspace.createNode(context, node_d,
nameFactory.create("b"), null);
- assertThat(workspace.getNodesByUuid().size(), is(7));
+ assertThat(workspace.size(), is(7));
assertThat(workspace.getNode(pathFactory.create("/")),
is(sameInstance(workspace.getRoot())));
assertThat(workspace.getNode(pathFactory.create("/a")),
is(sameInstance(node_a)));
assertThat(workspace.getNode(pathFactory.create("/a/b")),
is(sameInstance(node_b)));
@@ -252,18 +252,18 @@
@Test
public void shouldMoveNodeBeforeAnother() {
- InMemoryNode root = workspace.getRoot();
- InMemoryNode node_a = workspace.createNode(context, root,
nameFactory.create("a"), null);
- InMemoryNode node_b = workspace.createNode(context, node_a,
nameFactory.create("b"), null);
- InMemoryNode node_c = workspace.createNode(context, node_b,
nameFactory.create("c"), null);
- InMemoryNode node_d = workspace.createNode(context, root,
nameFactory.create("d"), null);
- InMemoryNode node_e = workspace.createNode(context, node_d,
nameFactory.create("e"), null);
- InMemoryNode node_b2 = workspace.createNode(context, node_d,
nameFactory.create("b"), null);
+ MapNode root = workspace.getRoot();
+ MapNode node_a = workspace.createNode(context, root,
nameFactory.create("a"), null);
+ MapNode node_b = workspace.createNode(context, node_a,
nameFactory.create("b"), null);
+ MapNode node_c = workspace.createNode(context, node_b,
nameFactory.create("c"), null);
+ MapNode node_d = workspace.createNode(context, root,
nameFactory.create("d"), null);
+ MapNode node_e = workspace.createNode(context, node_d,
nameFactory.create("e"), null);
+ MapNode node_b2 = workspace.createNode(context, node_d,
nameFactory.create("b"), null);
Name propName = nameFactory.create("prop");
node_b.setProperty(propertyFactory.create(propName, "node_b"));
node_b2.setProperty(propertyFactory.create(propName, "node_b2"));
- assertThat(workspace.getNodesByUuid().size(), is(7));
+ assertThat(workspace.size(), is(7));
assertThat(workspace.getNode(pathFactory.create("/")),
is(sameInstance(workspace.getRoot())));
assertThat(workspace.getNode(pathFactory.create("/a")),
is(sameInstance(node_a)));
assertThat(workspace.getNode(pathFactory.create("/a/b")),
is(sameInstance(node_b)));
@@ -303,16 +303,16 @@
@Test
public void shouldMoveNodesFromOneWorkspaceToAnother() {
- // Populate the workspace with some content ...
- InMemoryNode root = workspace.getRoot();
- InMemoryNode node_a = workspace.createNode(context, root,
nameFactory.create("a"), null);
- InMemoryNode node_b = workspace.createNode(context, node_a,
nameFactory.create("b"), null);
- InMemoryNode node_c = workspace.createNode(context, node_b,
nameFactory.create("c"), null);
- InMemoryNode node_d = workspace.createNode(context, root,
nameFactory.create("d"), null);
- InMemoryNode node_e = workspace.createNode(context, node_d,
nameFactory.create("e"), null);
- InMemoryNode node_b2 = workspace.createNode(context, node_d,
nameFactory.create("b"), null);
+ // Populate the workspace with some content ..
+ MapNode root = workspace.getRoot();
+ MapNode node_a = workspace.createNode(context, root,
nameFactory.create("a"), null);
+ MapNode node_b = workspace.createNode(context, node_a,
nameFactory.create("b"), null);
+ MapNode node_c = workspace.createNode(context, node_b,
nameFactory.create("c"), null);
+ MapNode node_d = workspace.createNode(context, root,
nameFactory.create("d"), null);
+ MapNode node_e = workspace.createNode(context, node_d,
nameFactory.create("e"), null);
+ MapNode node_b2 = workspace.createNode(context, node_d,
nameFactory.create("b"), null);
- assertThat(workspace.getNodesByUuid().size(), is(7));
+ assertThat(workspace.size(), is(7));
assertThat(workspace.getNode(pathFactory.create("/")),
is(sameInstance(workspace.getRoot())));
assertThat(workspace.getNode(pathFactory.create("/a")),
is(sameInstance(node_a)));
assertThat(workspace.getNode(pathFactory.create("/a/b")),
is(sameInstance(node_b)));
@@ -321,19 +321,19 @@
assertThat(workspace.getNode(pathFactory.create("/d/e")),
is(sameInstance(node_e)));
assertThat(workspace.getNode(pathFactory.create("/d/b")),
is(sameInstance(node_b2)));
- // Create the second workspace and populate it with some content ...
- Workspace new_workspace = repository.createWorkspace(context, "Second
Workspace", CreateConflictBehavior.DO_NOT_CREATE);
+ // Create the second workspace and populate it with some content ..
+ InMemoryRepository.Workspace new_workspace = (InMemoryRepository.Workspace)
repository.createWorkspace(context, "Second Workspace",
CreateConflictBehavior.DO_NOT_CREATE);
assertThat(new_workspace, is(notNullValue()));
- InMemoryNode new_root = new_workspace.getRoot();
- InMemoryNode new_node_a = new_workspace.createNode(context, new_root,
nameFactory.create("a"), null);
- InMemoryNode new_node_b = new_workspace.createNode(context, new_node_a,
nameFactory.create("b"), null);
- InMemoryNode new_node_c = new_workspace.createNode(context, new_node_b,
nameFactory.create("c"), null);
- InMemoryNode new_node_d = new_workspace.createNode(context, new_root,
nameFactory.create("d"), null);
- InMemoryNode new_node_e = new_workspace.createNode(context, new_node_d,
nameFactory.create("e"), null);
- InMemoryNode new_node_b2 = new_workspace.createNode(context, new_node_d,
nameFactory.create("b"), null);
+ MapNode new_root = new_workspace.getRoot();
+ MapNode new_node_a = new_workspace.createNode(context, new_root,
nameFactory.create("a"), null);
+ MapNode new_node_b = new_workspace.createNode(context, new_node_a,
nameFactory.create("b"), null);
+ MapNode new_node_c = new_workspace.createNode(context, new_node_b,
nameFactory.create("c"), null);
+ MapNode new_node_d = new_workspace.createNode(context, new_root,
nameFactory.create("d"), null);
+ MapNode new_node_e = new_workspace.createNode(context, new_node_d,
nameFactory.create("e"), null);
+ MapNode new_node_b2 = new_workspace.createNode(context, new_node_d,
nameFactory.create("b"), null);
- assertThat(new_workspace.getNodesByUuid().size(), is(7));
+ assertThat(new_workspace.size(), is(7));
assertThat(new_workspace.getNode(pathFactory.create("/")),
is(sameInstance(new_root)));
assertThat(new_workspace.getNode(pathFactory.create("/a")),
is(sameInstance(new_node_a)));
assertThat(new_workspace.getNode(pathFactory.create("/a/b")),
is(sameInstance(new_node_b)));
@@ -345,14 +345,14 @@
// Move 'workspace::/a/b' into 'newWorkspace::/d'
workspace.moveNode(context, node_b, null, new_workspace, new_node_d, null);
- assertThat(workspace.getNodesByUuid().size(), is(5));
+ assertThat(workspace.size(), is(5));
assertThat(workspace.getNode(pathFactory.create("/")),
is(sameInstance(workspace.getRoot())));
assertThat(workspace.getNode(pathFactory.create("/a")),
is(sameInstance(node_a)));
assertThat(workspace.getNode(pathFactory.create("/d")),
is(sameInstance(node_d)));
assertThat(workspace.getNode(pathFactory.create("/d/e")),
is(sameInstance(node_e)));
assertThat(workspace.getNode(pathFactory.create("/d/b")),
is(sameInstance(node_b2)));
- assertThat(new_workspace.getNodesByUuid().size(), is(9));
+ assertThat(new_workspace.size(), is(9));
assertThat(new_workspace.getNode(pathFactory.create("/")),
is(sameInstance(new_root)));
assertThat(new_workspace.getNode(pathFactory.create("/a")),
is(sameInstance(new_node_a)));
assertThat(new_workspace.getNode(pathFactory.create("/d")),
is(sameInstance(new_node_d)));
@@ -364,20 +364,20 @@
@Test
public void shouldCopyNodesWithinSameWorkspace() {
- InMemoryNode root = workspace.getRoot();
- InMemoryNode node_a = workspace.createNode(context, root,
nameFactory.create("a"), null);
- InMemoryNode node_b = workspace.createNode(context, node_a,
nameFactory.create("b"), null);
- InMemoryNode node_c = workspace.createNode(context, node_b,
nameFactory.create("c"), null);
- InMemoryNode node_d = workspace.createNode(context, root,
nameFactory.create("d"), null);
- InMemoryNode node_e = workspace.createNode(context, node_d,
nameFactory.create("e"), null);
- InMemoryNode node_b2 = workspace.createNode(context, node_d,
nameFactory.create("b"), null);
+ MapNode root = workspace.getRoot();
+ MapNode node_a = workspace.createNode(context, root,
nameFactory.create("a"), null);
+ MapNode node_b = workspace.createNode(context, node_a,
nameFactory.create("b"), null);
+ MapNode node_c = workspace.createNode(context, node_b,
nameFactory.create("c"), null);
+ MapNode node_d = workspace.createNode(context, root,
nameFactory.create("d"), null);
+ MapNode node_e = workspace.createNode(context, node_d,
nameFactory.create("e"), null);
+ MapNode node_b2 = workspace.createNode(context, node_d,
nameFactory.create("b"), null);
ValueFactory<String> stringFactory = valueFactories.getStringFactory();
Name propertyName = nameFactory.create("something");
Property property = propertyFactory.create(propertyName,
stringFactory.create("Worth the wait"));
- node_b.getProperties().put(propertyName, property);
+ node_b.setProperty(property);
- assertThat(workspace.getNodesByUuid().size(), is(7));
+ assertThat(workspace.size(), is(7));
assertThat(workspace.getNode(pathFactory.create("/")),
is(sameInstance(workspace.getRoot())));
assertThat(workspace.getNode(pathFactory.create("/a")),
is(sameInstance(node_a)));
assertThat(workspace.getNode(pathFactory.create("/a/b")),
is(sameInstance(node_b)));
@@ -386,11 +386,11 @@
assertThat(workspace.getNode(pathFactory.create("/d/e")),
is(sameInstance(node_e)));
assertThat(workspace.getNode(pathFactory.create("/d/b")),
is(sameInstance(node_b2)));
-
assertThat(workspace.getNode(pathFactory.create("/a/b")).getProperties().get(propertyName),
is(property));
+
assertThat(workspace.getNode(pathFactory.create("/a/b")).getProperty(propertyName),
is(property));
workspace.copyNode(context, node_b, workspace, node_d, null, true, new
HashMap<UUID, UUID>());
- assertThat(workspace.getNodesByUuid().size(), is(9));
+ assertThat(workspace.size(), is(9));
assertThat(workspace.getNode(pathFactory.create("/")),
is(sameInstance(workspace.getRoot())));
assertThat(workspace.getNode(pathFactory.create("/a")),
is(sameInstance(node_a)));
assertThat(workspace.getNode(pathFactory.create("/a/b")),
is(sameInstance(node_b)));
@@ -401,27 +401,27 @@
assertThat(workspace.getNode(pathFactory.create("/d/b[2]")),
is(notNullValue()));
assertThat(workspace.getNode(pathFactory.create("/d/b[2]/c")),
is(notNullValue()));
-
assertThat(workspace.getNode(pathFactory.create("/a/b")).getProperties().get(propertyName),
is(property));
-
assertThat(workspace.getNode(pathFactory.create("/d/b[2]")).getProperties().get(propertyName),
is(property));
+
assertThat(workspace.getNode(pathFactory.create("/a/b")).getProperty(propertyName),
is(property));
+
assertThat(workspace.getNode(pathFactory.create("/d/b[2]")).getProperty(propertyName),
is(property));
}
@Test
public void shouldCopyNodesFromOneWorkspaceToAnotherAndKeepSameUuids() {
- // Populate the workspace with some content ...
- InMemoryNode root = workspace.getRoot();
- InMemoryNode node_a = workspace.createNode(context, root,
nameFactory.create("a"), null);
- InMemoryNode node_b = workspace.createNode(context, node_a,
nameFactory.create("b"), null);
- InMemoryNode node_c = workspace.createNode(context, node_b,
nameFactory.create("c"), null);
- InMemoryNode node_d = workspace.createNode(context, root,
nameFactory.create("d"), null);
- InMemoryNode node_e = workspace.createNode(context, node_d,
nameFactory.create("e"), null);
- InMemoryNode node_b2 = workspace.createNode(context, node_d,
nameFactory.create("b"), null);
+ // Populate the workspace with some content ..
+ MapNode root = workspace.getRoot();
+ MapNode node_a = workspace.createNode(context, root,
nameFactory.create("a"), null);
+ MapNode node_b = workspace.createNode(context, node_a,
nameFactory.create("b"), null);
+ MapNode node_c = workspace.createNode(context, node_b,
nameFactory.create("c"), null);
+ MapNode node_d = workspace.createNode(context, root,
nameFactory.create("d"), null);
+ MapNode node_e = workspace.createNode(context, node_d,
nameFactory.create("e"), null);
+ MapNode node_b2 = workspace.createNode(context, node_d,
nameFactory.create("b"), null);
ValueFactory<String> stringFactory = valueFactories.getStringFactory();
Name propertyName = nameFactory.create("something");
Property property = propertyFactory.create(propertyName,
stringFactory.create("Worth the wait"));
- node_b.getProperties().put(propertyName, property);
+ node_b.setProperty(property);
- assertThat(workspace.getNodesByUuid().size(), is(7));
+ assertThat(workspace.size(), is(7));
assertThat(workspace.getNode(pathFactory.create("/")),
is(sameInstance(workspace.getRoot())));
assertThat(workspace.getNode(pathFactory.create("/a")),
is(sameInstance(node_a)));
assertThat(workspace.getNode(pathFactory.create("/a/b")),
is(sameInstance(node_b)));
@@ -430,21 +430,21 @@
assertThat(workspace.getNode(pathFactory.create("/d/e")),
is(sameInstance(node_e)));
assertThat(workspace.getNode(pathFactory.create("/d/b")),
is(sameInstance(node_b2)));
-
assertThat(workspace.getNode(pathFactory.create("/a/b")).getProperties().get(propertyName),
is(property));
+
assertThat(workspace.getNode(pathFactory.create("/a/b")).getProperty(propertyName),
is(property));
- // Create the second workspace and populate it with some content ...
- Workspace new_workspace = repository.createWorkspace(context, "Second
Workspace", CreateConflictBehavior.DO_NOT_CREATE);
+ // Create the second workspace and populate it with some content ..
+ InMemoryRepository.Workspace new_workspace = (InMemoryRepository.Workspace)
repository.createWorkspace(context, "Second Workspace",
CreateConflictBehavior.DO_NOT_CREATE);
assertThat(new_workspace, is(notNullValue()));
- InMemoryNode new_root = new_workspace.getRoot();
- InMemoryNode new_node_a = new_workspace.createNode(context, new_root,
nameFactory.create("a"), null);
- InMemoryNode new_node_b = new_workspace.createNode(context, new_node_a,
nameFactory.create("b"), null);
- InMemoryNode new_node_c = new_workspace.createNode(context, new_node_b,
nameFactory.create("c"), null);
- InMemoryNode new_node_d = new_workspace.createNode(context, new_root,
nameFactory.create("d"), null);
- InMemoryNode new_node_e = new_workspace.createNode(context, new_node_d,
nameFactory.create("e"), null);
- InMemoryNode new_node_b2 = new_workspace.createNode(context, new_node_d,
nameFactory.create("b"), null);
+ MapNode new_root = new_workspace.getRoot();
+ MapNode new_node_a = new_workspace.createNode(context, new_root,
nameFactory.create("a"), null);
+ MapNode new_node_b = new_workspace.createNode(context, new_node_a,
nameFactory.create("b"), null);
+ MapNode new_node_c = new_workspace.createNode(context, new_node_b,
nameFactory.create("c"), null);
+ MapNode new_node_d = new_workspace.createNode(context, new_root,
nameFactory.create("d"), null);
+ MapNode new_node_e = new_workspace.createNode(context, new_node_d,
nameFactory.create("e"), null);
+ MapNode new_node_b2 = new_workspace.createNode(context, new_node_d,
nameFactory.create("b"), null);
- assertThat(new_workspace.getNodesByUuid().size(), is(7));
+ assertThat(new_workspace.size(), is(7));
assertThat(new_workspace.getNode(pathFactory.create("/")),
is(sameInstance(new_root)));
assertThat(new_workspace.getNode(pathFactory.create("/a")),
is(sameInstance(new_node_a)));
assertThat(new_workspace.getNode(pathFactory.create("/a/b")),
is(sameInstance(new_node_b)));
@@ -454,9 +454,9 @@
assertThat(new_workspace.getNode(pathFactory.create("/d/b")),
is(sameInstance(new_node_b2)));
// Copy 'workspace::/a/b' into 'newWorkspace::/d'
- workspace.copyNode(context, node_b, new_workspace, new_node_d, null, true,
null);
+ workspace.copyNode(context, node_b, new_workspace, new_node_d, null, true,
(Map<UUID, UUID>) null);
- assertThat(workspace.getNodesByUuid().size(), is(7));
+ assertThat(workspace.size(), is(7));
assertThat(workspace.getNode(pathFactory.create("/")),
is(sameInstance(workspace.getRoot())));
assertThat(workspace.getNode(pathFactory.create("/a")),
is(sameInstance(node_a)));
assertThat(workspace.getNode(pathFactory.create("/a/b")),
is(sameInstance(node_b)));
@@ -464,9 +464,9 @@
assertThat(workspace.getNode(pathFactory.create("/d")),
is(sameInstance(node_d)));
assertThat(workspace.getNode(pathFactory.create("/d/e")),
is(sameInstance(node_e)));
assertThat(workspace.getNode(pathFactory.create("/d/b")),
is(sameInstance(node_b2)));
-
assertThat(workspace.getNode(pathFactory.create("/a/b")).getProperties().get(propertyName),
is(property));
+
assertThat(workspace.getNode(pathFactory.create("/a/b")).getProperty(propertyName),
is(property));
- assertThat(new_workspace.getNodesByUuid().size(), is(9));
+ assertThat(new_workspace.size(), is(9));
assertThat(new_workspace.getNode(pathFactory.create("/")),
is(sameInstance(new_root)));
assertThat(new_workspace.getNode(pathFactory.create("/a")),
is(sameInstance(new_node_a)));
assertThat(new_workspace.getNode(pathFactory.create("/a/b")),
is(sameInstance(new_node_b)));
@@ -477,11 +477,11 @@
assertThat(new_workspace.getNode(pathFactory.create("/d/b[2]")),
is(notNullValue()));
assertThat(new_workspace.getNode(pathFactory.create("/d/b[2]/c")),
is(notNullValue()));
-
assertThat(new_workspace.getNode(pathFactory.create("/d/b[2]")).getProperties().get(propertyName),
is(property));
+
assertThat(new_workspace.getNode(pathFactory.create("/d/b[2]")).getProperty(propertyName),
is(property));
- // The new copy should have the same UUIDs as in the original, since we specified
no UUID map ...
- InMemoryNode new_copy_b =
new_workspace.getNode(pathFactory.create("/d/b[2]"));
- InMemoryNode new_copy_c =
new_workspace.getNode(pathFactory.create("/d/b[2]/c"));
+ // The new copy should have the same UUIDs as in the original, since we specified
no UUID map ..
+ MapNode new_copy_b =
new_workspace.getNode(pathFactory.create("/d/b[2]"));
+ MapNode new_copy_c =
new_workspace.getNode(pathFactory.create("/d/b[2]/c"));
assertThat(new_copy_b, is(notNullValue()));
assertThat(new_copy_c, is(notNullValue()));
assertThat(new_copy_b.getUuid(), is(node_b.getUuid()));
@@ -490,21 +490,21 @@
@Test
public void shouldCopyNodesFromOneWorkspaceToAnotherAndGenerateNewUuids() {
- // Populate the workspace with some content ...
- InMemoryNode root = workspace.getRoot();
- InMemoryNode node_a = workspace.createNode(context, root,
nameFactory.create("a"), null);
- InMemoryNode node_b = workspace.createNode(context, node_a,
nameFactory.create("b"), null);
- InMemoryNode node_c = workspace.createNode(context, node_b,
nameFactory.create("c"), null);
- InMemoryNode node_d = workspace.createNode(context, root,
nameFactory.create("d"), null);
- InMemoryNode node_e = workspace.createNode(context, node_d,
nameFactory.create("e"), null);
- InMemoryNode node_b2 = workspace.createNode(context, node_d,
nameFactory.create("b"), null);
+ // Populate the workspace with some content ..
+ MapNode root = workspace.getRoot();
+ MapNode node_a = workspace.createNode(context, root,
nameFactory.create("a"), null);
+ MapNode node_b = workspace.createNode(context, node_a,
nameFactory.create("b"), null);
+ MapNode node_c = workspace.createNode(context, node_b,
nameFactory.create("c"), null);
+ MapNode node_d = workspace.createNode(context, root,
nameFactory.create("d"), null);
+ MapNode node_e = workspace.createNode(context, node_d,
nameFactory.create("e"), null);
+ MapNode node_b2 = workspace.createNode(context, node_d,
nameFactory.create("b"), null);
ValueFactory<String> stringFactory = valueFactories.getStringFactory();
Name propertyName = nameFactory.create("something");
Property property = propertyFactory.create(propertyName,
stringFactory.create("Worth the wait"));
- node_b.getProperties().put(propertyName, property);
+ node_b.setProperty(property);
- assertThat(workspace.getNodesByUuid().size(), is(7));
+ assertThat(workspace.size(), is(7));
assertThat(workspace.getNode(pathFactory.create("/")),
is(sameInstance(workspace.getRoot())));
assertThat(workspace.getNode(pathFactory.create("/a")),
is(sameInstance(node_a)));
assertThat(workspace.getNode(pathFactory.create("/a/b")),
is(sameInstance(node_b)));
@@ -513,21 +513,21 @@
assertThat(workspace.getNode(pathFactory.create("/d/e")),
is(sameInstance(node_e)));
assertThat(workspace.getNode(pathFactory.create("/d/b")),
is(sameInstance(node_b2)));
-
assertThat(workspace.getNode(pathFactory.create("/a/b")).getProperties().get(propertyName),
is(property));
+
assertThat(workspace.getNode(pathFactory.create("/a/b")).getProperty(propertyName),
is(property));
- // Create the second workspace and populate it with some content ...
- Workspace new_workspace = repository.createWorkspace(context, "Second
Workspace", CreateConflictBehavior.DO_NOT_CREATE);
+ // Create the second workspace and populate it with some content ..
+ InMemoryRepository.Workspace new_workspace = (InMemoryRepository.Workspace)
repository.createWorkspace(context, "Second Workspace",
CreateConflictBehavior.DO_NOT_CREATE);
assertThat(new_workspace, is(notNullValue()));
- InMemoryNode new_root = new_workspace.getRoot();
- InMemoryNode new_node_a = new_workspace.createNode(context, new_root,
nameFactory.create("a"), null);
- InMemoryNode new_node_b = new_workspace.createNode(context, new_node_a,
nameFactory.create("b"), null);
- InMemoryNode new_node_c = new_workspace.createNode(context, new_node_b,
nameFactory.create("c"), null);
- InMemoryNode new_node_d = new_workspace.createNode(context, new_root,
nameFactory.create("d"), null);
- InMemoryNode new_node_e = new_workspace.createNode(context, new_node_d,
nameFactory.create("e"), null);
- InMemoryNode new_node_b2 = new_workspace.createNode(context, new_node_d,
nameFactory.create("b"), null);
+ MapNode new_root = new_workspace.getRoot();
+ MapNode new_node_a = new_workspace.createNode(context, new_root,
nameFactory.create("a"), null);
+ MapNode new_node_b = new_workspace.createNode(context, new_node_a,
nameFactory.create("b"), null);
+ MapNode new_node_c = new_workspace.createNode(context, new_node_b,
nameFactory.create("c"), null);
+ MapNode new_node_d = new_workspace.createNode(context, new_root,
nameFactory.create("d"), null);
+ MapNode new_node_e = new_workspace.createNode(context, new_node_d,
nameFactory.create("e"), null);
+ MapNode new_node_b2 = new_workspace.createNode(context, new_node_d,
nameFactory.create("b"), null);
- assertThat(new_workspace.getNodesByUuid().size(), is(7));
+ assertThat(new_workspace.size(), is(7));
assertThat(new_workspace.getNode(pathFactory.create("/")),
is(sameInstance(new_root)));
assertThat(new_workspace.getNode(pathFactory.create("/a")),
is(sameInstance(new_node_a)));
assertThat(new_workspace.getNode(pathFactory.create("/a/b")),
is(sameInstance(new_node_b)));
@@ -540,7 +540,7 @@
Map<UUID, UUID> oldToNewUuids = new HashMap<UUID, UUID>();
workspace.copyNode(context, node_b, new_workspace, new_node_d, null, true,
oldToNewUuids);
- assertThat(workspace.getNodesByUuid().size(), is(7));
+ assertThat(workspace.size(), is(7));
assertThat(workspace.getNode(pathFactory.create("/")),
is(sameInstance(workspace.getRoot())));
assertThat(workspace.getNode(pathFactory.create("/a")),
is(sameInstance(node_a)));
assertThat(workspace.getNode(pathFactory.create("/a/b")),
is(sameInstance(node_b)));
@@ -549,9 +549,9 @@
assertThat(workspace.getNode(pathFactory.create("/d/e")),
is(sameInstance(node_e)));
assertThat(workspace.getNode(pathFactory.create("/d/b")),
is(sameInstance(node_b2)));
-
assertThat(workspace.getNode(pathFactory.create("/a/b")).getProperties().get(propertyName),
is(property));
+
assertThat(workspace.getNode(pathFactory.create("/a/b")).getProperty(propertyName),
is(property));
- assertThat(new_workspace.getNodesByUuid().size(), is(9));
+ assertThat(new_workspace.size(), is(9));
assertThat(new_workspace.getNode(pathFactory.create("/")),
is(sameInstance(new_root)));
assertThat(new_workspace.getNode(pathFactory.create("/a")),
is(sameInstance(new_node_a)));
assertThat(new_workspace.getNode(pathFactory.create("/a/b")),
is(sameInstance(new_node_b)));
@@ -562,11 +562,11 @@
assertThat(new_workspace.getNode(pathFactory.create("/d/b[2]")),
is(notNullValue()));
assertThat(new_workspace.getNode(pathFactory.create("/d/b[2]/c")),
is(notNullValue()));
-
assertThat(new_workspace.getNode(pathFactory.create("/d/b[2]")).getProperties().get(propertyName),
is(property));
+
assertThat(new_workspace.getNode(pathFactory.create("/d/b[2]")).getProperty(propertyName),
is(property));
- // The new copy should have different UUIDs than in the original, since we did
specify a UUID map ...
- InMemoryNode new_copy_b =
new_workspace.getNode(pathFactory.create("/d/b[2]"));
- InMemoryNode new_copy_c =
new_workspace.getNode(pathFactory.create("/d/b[2]/c"));
+ // The new copy should have different UUIDs than in the original, since we did
specify a UUID map ..
+ MapNode new_copy_b =
new_workspace.getNode(pathFactory.create("/d/b[2]"));
+ MapNode new_copy_c =
new_workspace.getNode(pathFactory.create("/d/b[2]/c"));
assertThat(new_copy_b, is(notNullValue()));
assertThat(new_copy_c, is(notNullValue()));
assertThat(new_copy_b.getUuid(), is(not(node_b.getUuid())));
@@ -577,20 +577,20 @@
@Test
public void shouldCopyNodesWhenDesiredNameIsSpecified() {
- InMemoryNode root = workspace.getRoot();
- InMemoryNode node_a = workspace.createNode(context, root,
nameFactory.create("a"), null);
- InMemoryNode node_b = workspace.createNode(context, node_a,
nameFactory.create("b"), null);
- InMemoryNode node_c = workspace.createNode(context, node_b,
nameFactory.create("c"), null);
- InMemoryNode node_d = workspace.createNode(context, root,
nameFactory.create("d"), null);
- InMemoryNode node_e = workspace.createNode(context, node_d,
nameFactory.create("e"), null);
- InMemoryNode node_b2 = workspace.createNode(context, node_d,
nameFactory.create("b"), null);
+ MapNode root = workspace.getRoot();
+ MapNode node_a = workspace.createNode(context, root,
nameFactory.create("a"), null);
+ MapNode node_b = workspace.createNode(context, node_a,
nameFactory.create("b"), null);
+ MapNode node_c = workspace.createNode(context, node_b,
nameFactory.create("c"), null);
+ MapNode node_d = workspace.createNode(context, root,
nameFactory.create("d"), null);
+ MapNode node_e = workspace.createNode(context, node_d,
nameFactory.create("e"), null);
+ MapNode node_b2 = workspace.createNode(context, node_d,
nameFactory.create("b"), null);
ValueFactory<String> stringFactory = valueFactories.getStringFactory();
Name propertyName = nameFactory.create("something");
Property property = propertyFactory.create(propertyName,
stringFactory.create("Worth the wait"));
- node_b.getProperties().put(propertyName, property);
+ node_b.setProperty(property);
- assertThat(workspace.getNodesByUuid().size(), is(7));
+ assertThat(workspace.size(), is(7));
assertThat(workspace.getNode(pathFactory.create("/")),
is(sameInstance(workspace.getRoot())));
assertThat(workspace.getNode(pathFactory.create("/a")),
is(sameInstance(node_a)));
assertThat(workspace.getNode(pathFactory.create("/a/b")),
is(sameInstance(node_b)));
@@ -599,11 +599,11 @@
assertThat(workspace.getNode(pathFactory.create("/d/e")),
is(sameInstance(node_e)));
assertThat(workspace.getNode(pathFactory.create("/d/b")),
is(sameInstance(node_b2)));
-
assertThat(workspace.getNode(pathFactory.create("/a/b")).getProperties().get(propertyName),
is(property));
+
assertThat(workspace.getNode(pathFactory.create("/a/b")).getProperty(propertyName),
is(property));
workspace.copyNode(context, node_b, workspace, node_d,
nameFactory.create("x"), true, new HashMap<UUID, UUID>());
- assertThat(workspace.getNodesByUuid().size(), is(9));
+ assertThat(workspace.size(), is(9));
assertThat(workspace.getNode(pathFactory.create("/")),
is(sameInstance(workspace.getRoot())));
assertThat(workspace.getNode(pathFactory.create("/a")),
is(sameInstance(node_a)));
assertThat(workspace.getNode(pathFactory.create("/a/b")),
is(sameInstance(node_b)));
@@ -614,8 +614,8 @@
assertThat(workspace.getNode(pathFactory.create("/d/x")),
is(notNullValue()));
assertThat(workspace.getNode(pathFactory.create("/d/x/c")),
is(notNullValue()));
-
assertThat(workspace.getNode(pathFactory.create("/a/b")).getProperties().get(propertyName),
is(property));
-
assertThat(workspace.getNode(pathFactory.create("/d/x")).getProperties().get(propertyName),
is(property));
+
assertThat(workspace.getNode(pathFactory.create("/a/b")).getProperty(propertyName),
is(property));
+
assertThat(workspace.getNode(pathFactory.create("/d/x")).getProperty(propertyName),
is(property));
}
@Test
Deleted:
trunk/extensions/dna-connector-jbosscache/src/main/java/org/jboss/dna/connector/jbosscache/JBossCacheConnection.java
===================================================================
---
trunk/extensions/dna-connector-jbosscache/src/main/java/org/jboss/dna/connector/jbosscache/JBossCacheConnection.java 2009-06-24
22:14:12 UTC (rev 1064)
+++
trunk/extensions/dna-connector-jbosscache/src/main/java/org/jboss/dna/connector/jbosscache/JBossCacheConnection.java 2009-06-27
02:54:06 UTC (rev 1065)
@@ -1,108 +0,0 @@
-/*
- * JBoss DNA (
http://www.jboss.org/dna)
- * See the COPYRIGHT.txt file distributed with this work for information
- * regarding copyright ownership. Some portions may be licensed
- * to Red Hat, Inc. under one or more contributor license agreements.
- * See the AUTHORS.txt file in the distribution for a full listing of
- * individual contributors.
- *
- * JBoss DNA is free software. Unless otherwise indicated, all code in JBoss DNA
- * is licensed to you under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation; either version 2.1 of
- * the License, or (at your option) any later version.
- *
- * JBoss DNA is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this software; if not, write to the Free
- * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA, or see the FSF site:
http://www.fsf.org.
- */
-package org.jboss.dna.connector.jbosscache;
-
-import java.util.concurrent.TimeUnit;
-import javax.transaction.xa.XAResource;
-import org.jboss.dna.graph.ExecutionContext;
-import org.jboss.dna.graph.cache.CachePolicy;
-import org.jboss.dna.graph.connector.RepositoryConnection;
-import org.jboss.dna.graph.connector.RepositorySourceException;
-import org.jboss.dna.graph.observe.Observer;
-import org.jboss.dna.graph.request.Request;
-import org.jboss.dna.graph.request.processor.RequestProcessor;
-
-/**
- * The repository connection to a JBoss Cache instance.
- *
- * @author Randall Hauch
- */
-public class JBossCacheConnection implements RepositoryConnection {
-
- private final JBossCacheSource source;
- private final JBossCacheWorkspaces workspaces;
-
- JBossCacheConnection( JBossCacheSource source,
- JBossCacheWorkspaces workspaces ) {
- assert source != null;
- assert workspaces != null;
- this.source = source;
- this.workspaces = workspaces;
- }
-
- /**
- * {@inheritDoc}
- */
- public String getSourceName() {
- return source.getName();
- }
-
- /**
- * {@inheritDoc}
- */
- public CachePolicy getDefaultCachePolicy() {
- return source.getDefaultCachePolicy();
- }
-
- /**
- * {@inheritDoc}
- */
- public XAResource getXAResource() {
- return null;
- }
-
- /**
- * {@inheritDoc}
- */
- public boolean ping( long time,
- TimeUnit unit ) {
- return true;
- }
-
- /**
- * {@inheritDoc}
- */
- public void close() {
- // do nothing
- }
-
- /**
- * {@inheritDoc}
- *
- * @see
org.jboss.dna.graph.connector.RepositoryConnection#execute(org.jboss.dna.graph.ExecutionContext,
- * org.jboss.dna.graph.request.Request)
- */
- public void execute( final ExecutionContext context,
- final Request request ) throws RepositorySourceException {
- Observer observer = source.getObserver();
- RequestProcessor processor = new JBossCacheRequestProcessor(getSourceName(),
context, observer, workspaces,
-
source.getNameOfDefaultWorkspace(),
-
source.isCreatingWorkspacesAllowed());
- try {
- processor.process(request);
- } finally {
- processor.close();
- }
- }
-}
Deleted:
trunk/extensions/dna-connector-jbosscache/src/main/java/org/jboss/dna/connector/jbosscache/JBossCacheLexicon.java
===================================================================
---
trunk/extensions/dna-connector-jbosscache/src/main/java/org/jboss/dna/connector/jbosscache/JBossCacheLexicon.java 2009-06-24
22:14:12 UTC (rev 1064)
+++
trunk/extensions/dna-connector-jbosscache/src/main/java/org/jboss/dna/connector/jbosscache/JBossCacheLexicon.java 2009-06-27
02:54:06 UTC (rev 1065)
@@ -1,45 +0,0 @@
-/*
- * JBoss DNA (
http://www.jboss.org/dna)
- * See the COPYRIGHT.txt file distributed with this work for information
- * regarding copyright ownership. Some portions may be licensed
- * to Red Hat, Inc. under one or more contributor license agreements.
- * See the AUTHORS.txt file in the distribution for a full listing of
- * individual contributors.
- *
- * JBoss DNA is free software. Unless otherwise indicated, all code in JBoss DNA
- * is licensed to you under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation; either version 2.1 of
- * the License, or (at your option) any later version.
- *
- * JBoss DNA is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this software; if not, write to the Free
- * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA, or see the FSF site:
http://www.fsf.org.
- */
-package org.jboss.dna.connector.jbosscache;
-
-import org.jboss.dna.graph.property.Name;
-import org.jboss.dna.graph.property.basic.BasicName;
-
-/**
- * The namespace and property names used within a {@link JBossCacheSource} to store
internal information.
- *
- * @author Randall Hauch
- */
-public class JBossCacheLexicon {
-
- public static class Namespace {
- public static final String URI =
"http://www.jboss.org/dna/connector/jbosscache";
- public static final String PREFIX = "dnajbcc";
- }
-
- public static final Name CHILD_PATH_SEGMENT_LIST = new BasicName(Namespace.URI,
"orderedChildNames");
- public static final Name UUIDS = new BasicName(Namespace.URI, "uuids");
- public static final Name FQN = new BasicName(Namespace.URI, "fqn");
-
-}
Added:
trunk/extensions/dna-connector-jbosscache/src/main/java/org/jboss/dna/connector/jbosscache/JBossCacheRepository.java
===================================================================
---
trunk/extensions/dna-connector-jbosscache/src/main/java/org/jboss/dna/connector/jbosscache/JBossCacheRepository.java
(rev 0)
+++
trunk/extensions/dna-connector-jbosscache/src/main/java/org/jboss/dna/connector/jbosscache/JBossCacheRepository.java 2009-06-27
02:54:06 UTC (rev 1065)
@@ -0,0 +1,79 @@
+package org.jboss.dna.connector.jbosscache;
+
+import java.util.UUID;
+import org.jboss.cache.Cache;
+import org.jboss.cache.Fqn;
+import org.jboss.cache.Node;
+import org.jboss.dna.graph.ExecutionContext;
+import org.jboss.dna.graph.connector.map.AbstractMapWorkspace;
+import org.jboss.dna.graph.connector.map.MapNode;
+import org.jboss.dna.graph.connector.map.MapRepository;
+import org.jboss.dna.graph.connector.map.MapWorkspace;
+
+public class JBossCacheRepository extends MapRepository {
+
+ private final Cache<UUID, MapNode> cache;
+
+ public JBossCacheRepository( String sourceName,
+ UUID rootNodeUuid,
+ Cache<UUID, MapNode> cache ) {
+ super(sourceName, rootNodeUuid, null);
+ assert cache != null;
+ this.cache = cache;
+ initialize();
+ }
+
+ public JBossCacheRepository( String sourceName,
+ UUID rootNodeUuid,
+ String defaultWorkspaceName,
+ Cache<UUID, MapNode> cache ) {
+ super(sourceName, rootNodeUuid, defaultWorkspaceName);
+
+ assert cache != null;
+ this.cache = cache;
+
+ initialize();
+ }
+
+ @Override
+ protected MapWorkspace createWorkspace( ExecutionContext context,
+ String name ) {
+ assert name != null;
+ assert cache != null;
+ Node<UUID, MapNode> newWorkspaceNode =
cache.getRoot().addChild(Fqn.fromElements(name));
+ return new Workspace(this, name, newWorkspaceNode);
+ }
+
+ protected class Workspace extends AbstractMapWorkspace {
+ private final Node<UUID, MapNode> workspaceNode;
+
+ public Workspace( MapRepository repository,
+ String name,
+ Node<UUID, MapNode> workspaceNode ) {
+ super(repository, name);
+
+ this.workspaceNode = workspaceNode;
+ initialize();
+ }
+
+ protected void addNodeToMap( MapNode node ) {
+ assert node != null;
+ workspaceNode.put(node.getUuid(), node);
+ }
+
+ protected MapNode removeNodeFromMap( UUID nodeUuid ) {
+ assert nodeUuid != null;
+ return workspaceNode.remove(nodeUuid);
+ }
+
+ protected void removeAllNodesFromMap() {
+ workspaceNode.clearData();
+ }
+
+ public MapNode getNode( UUID nodeUuid ) {
+ assert nodeUuid != null;
+ return workspaceNode.get(nodeUuid);
+ }
+ }
+
+}
Property changes on:
trunk/extensions/dna-connector-jbosscache/src/main/java/org/jboss/dna/connector/jbosscache/JBossCacheRepository.java
___________________________________________________________________
Name: svn:keywords
+ Id Revision
Name: svn:eol-style
+ LF
Deleted:
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-06-24
22:14:12 UTC (rev 1064)
+++
trunk/extensions/dna-connector-jbosscache/src/main/java/org/jboss/dna/connector/jbosscache/JBossCacheRequestProcessor.java 2009-06-27
02:54:06 UTC (rev 1065)
@@ -1,1032 +0,0 @@
-/*
- * JBoss DNA (
http://www.jboss.org/dna)
- * See the COPYRIGHT.txt file distributed with this work for information
- * regarding copyright ownership. Some portions may be licensed
- * to Red Hat, Inc. under one or more contributor license agreements.
- * See the AUTHORS.txt file in the distribution for a full listing of
- * individual contributors.
- *
- * 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 java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.HashSet;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import java.util.UUID;
-import java.util.concurrent.atomic.AtomicInteger;
-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.connector.UuidAlreadyExistsException;
-import org.jboss.dna.graph.observe.Observer;
-import org.jboss.dna.graph.property.Name;
-import org.jboss.dna.graph.property.Path;
-import org.jboss.dna.graph.property.PathFactory;
-import org.jboss.dna.graph.property.PathNotFoundException;
-import org.jboss.dna.graph.property.Property;
-import org.jboss.dna.graph.property.PropertyFactory;
-import org.jboss.dna.graph.property.UuidFactory;
-import org.jboss.dna.graph.request.CloneWorkspaceRequest;
-import org.jboss.dna.graph.request.CopyBranchRequest;
-import org.jboss.dna.graph.request.CreateNodeRequest;
-import org.jboss.dna.graph.request.CreateWorkspaceRequest;
-import org.jboss.dna.graph.request.DeleteBranchRequest;
-import org.jboss.dna.graph.request.DestroyWorkspaceRequest;
-import org.jboss.dna.graph.request.GetWorkspacesRequest;
-import org.jboss.dna.graph.request.InvalidRequestException;
-import org.jboss.dna.graph.request.InvalidWorkspaceException;
-import org.jboss.dna.graph.request.MoveBranchRequest;
-import org.jboss.dna.graph.request.ReadAllChildrenRequest;
-import org.jboss.dna.graph.request.ReadAllPropertiesRequest;
-import org.jboss.dna.graph.request.Request;
-import org.jboss.dna.graph.request.UpdatePropertiesRequest;
-import org.jboss.dna.graph.request.UuidConflictBehavior;
-import org.jboss.dna.graph.request.VerifyWorkspaceRequest;
-import org.jboss.dna.graph.request.processor.RequestProcessor;
-
-/**
- * A {@link RequestProcessor} implementation that operates upon a {@link Cache JBoss
Cache} instance for each workspace in the
- * {@link JBossCacheSource source}.
- * <p>
- * This processor only uses {@link Location} objects with {@link Location#getPath()
paths}. Even though every node in the cache is
- * automatically assigned a UUID (and all operations properly handle UUIDs), these UUIDs
are not included in the {@link Location}
- * objects because the processor is unable to search the cache to find nodes by UUID.
- * </p>
- */
-public class JBossCacheRequestProcessor extends RequestProcessor {
-
- private final JBossCacheWorkspaces workspaces;
- private final boolean creatingWorkspacesAllowed;
- private final String defaultWorkspaceName;
- private final PathFactory pathFactory;
- private final PropertyFactory propertyFactory;
- private final UuidFactory uuidFactory;
- private Path.Segment dnaUuidsSegment;
-
- /**
- * @param sourceName the name of the source in which this processor is operating
- * @param context the execution context in which this processor operates
- * @param observer the observer to which events should be published; may be null if
the events are not be published
- * @param workspaces the manager for the workspaces
- * @param defaultWorkspaceName the name of the default workspace; never null
- * @param creatingWorkspacesAllowed true if clients can create new workspaces, or
false otherwise
- */
- JBossCacheRequestProcessor( String sourceName,
- ExecutionContext context,
- Observer observer,
- JBossCacheWorkspaces workspaces,
- String defaultWorkspaceName,
- boolean creatingWorkspacesAllowed ) {
- super(sourceName, context, observer);
- assert workspaces != null;
- assert defaultWorkspaceName != null;
- this.workspaces = workspaces;
- this.creatingWorkspacesAllowed = creatingWorkspacesAllowed;
- this.defaultWorkspaceName = defaultWorkspaceName;
- this.pathFactory = context.getValueFactories().getPathFactory();
- this.propertyFactory = context.getPropertyFactory();
- this.uuidFactory = context.getValueFactories().getUuidFactory();
- this.dnaUuidsSegment = pathFactory.createSegment(JBossCacheLexicon.UUIDS);
- }
-
- @Override
- public void process( ReadAllChildrenRequest request ) {
- // Look up the cache and the node ...
- Cache<Name, Object> cache = getCache(request, request.inWorkspace());
- if (cache == null) return;
- Path nodePath = request.of().getPath();
- Node<Name, Object> node = getNode(request, cache, nodePath);
- if (node == null) return;
-
- // Get the names of the children, using the child list ...
- Path.Segment[] childList =
(Path.Segment[])node.get(JBossCacheLexicon.CHILD_PATH_SEGMENT_LIST);
- if (childList != null) {
- for (Path.Segment child : childList) {
- request.addChild(Location.create(pathFactory.create(nodePath, child)));
- }
- }
- request.setActualLocationOfNode(Location.create(nodePath));
- setCacheableInfo(request);
- }
-
- @Override
- public void process( ReadAllPropertiesRequest request ) {
- // Look up the cache and the node ...
- Cache<Name, Object> cache = getCache(request, request.inWorkspace());
- if (cache == null) return;
- Path nodePath = request.at().getPath();
- Node<Name, Object> node = getNode(request, cache, nodePath);
- if (node == null) return;
-
- // Get the properties on the node ...
- Map<Name, Object> dataMap = node.getData();
- for (Map.Entry<Name, Object> data : dataMap.entrySet()) {
- Name propertyName = data.getKey();
- // Don't allow the child list property to be accessed
- if (propertyName.equals(JBossCacheLexicon.CHILD_PATH_SEGMENT_LIST))
continue;
- Object values = data.getValue();
- Property property = propertyFactory.create(propertyName, values);
- request.addProperty(property);
- }
- request.setActualLocationOfNode(Location.create(nodePath));
- setCacheableInfo(request);
- }
-
- @Override
- @SuppressWarnings( "unchecked" )
- public void process( CreateNodeRequest request ) {
- // Look up the cache and the node ...
- Cache<Name, Object> cache = getCache(request, request.inWorkspace());
- if (cache == null) return;
- Path parent = request.under().getPath();
- Node<Name, Object> parentNode = getNode(request, cache, parent);
- if (parentNode == null) return;
-
- // Update the children to account for same-name siblings.
- // This not only updates the FQN of the child nodes, but it also sets the
property that stores the
- // the array of Path.Segment for the children (since the cache doesn't
maintain order).
- Path.Segment newSegment = updateChildList(cache, parentNode, request.named(),
null, getExecutionContext(), true);
- Node<Name, Object> node =
parentNode.addChild(Fqn.fromElements(newSegment));
- assert checkChildren(parentNode);
-
- // Add the UUID property (if required), which may be overwritten by a supplied
property ...
- UUID uuid = uuidFactory.create();
- node.put(DnaLexicon.UUID, uuid);
- // Now add the properties to the supplied node ...
- for (Property property : request.properties()) {
- if (property.size() == 0) continue;
- Name propName = property.getName();
- Object value = null;
- if (property.size() == 1) {
- value = property.iterator().next();
- } else {
- value = property.getValuesAsArray();
- }
- node.put(propName, value);
- }
-
- mapUuid(cache, uuid, node.getFqn());
- Path nodePath = pathFactory.create(parent, newSegment);
- request.setActualLocationOfNode(Location.create(nodePath));
- recordChange(request);
- }
-
- @Override
- public void process( UpdatePropertiesRequest request ) {
- // Look up the cache and the node ...
- Cache<Name, Object> cache = getCache(request, request.inWorkspace());
- if (cache == null) return;
- Path nodePath = request.on().getPath();
- Node<Name, Object> node = getNode(request, cache, nodePath);
- if (node == null) return;
-
- // Now set (or remove) the properties to the supplied node ...
- for (Map.Entry<Name, Property> entry : request.properties().entrySet()) {
- Name propName = entry.getKey();
- // Don't allow the child list property to be removed or changed
- if (propName.equals(JBossCacheLexicon.CHILD_PATH_SEGMENT_LIST)) continue;
-
- Property property = entry.getValue();
- if (property == null) {
- node.remove(propName);
- continue;
- }
- Object value = null;
- if (property.isSingle()) {
- value = property.iterator().next();
- } else {
- value = property.getValuesAsArray();
- }
- node.put(propName, value);
- }
- request.setActualLocationOfNode(Location.create(nodePath));
- recordChange(request);
- }
-
- @Override
- public void process( CopyBranchRequest request ) {
- // Look up the caches ...
- Cache<Name, Object> fromCache = getCache(request,
request.fromWorkspace());
- if (fromCache == null) return;
- Cache<Name, Object> intoCache = getCache(request,
request.intoWorkspace());
- if (intoCache == null) return;
-
- // Look up the current node and the new parent (both of which must exist) ...
- Path nodePath = request.from().getPath();
- Node<Name, Object> node = getNode(request, fromCache, nodePath);
- if (node == null) return;
- Path newParentPath = request.into().getPath();
- Node<Name, Object> newParent = getNode(request, intoCache, newParentPath);
- if (newParent == null) return;
-
- if (UuidConflictBehavior.THROW_EXCEPTION.equals(request.uuidConflictBehavior()))
{
- // Build a list of all the UUIDs in the source branch
- Set<UUID> uuidsFromSource = new HashSet<UUID>();
- LinkedList<Node<Name, Object>> nodesToVisit = new
LinkedList<Node<Name, Object>>();
- nodesToVisit.add(node);
-
- while (!nodesToVisit.isEmpty()) {
- Node<Name, Object> nodeToCheck = nodesToVisit.removeFirst();
- UUID uuid = uuidFactory.create(nodeToCheck.get(DnaLexicon.UUID));
- if (uuid != null) uuidsFromSource.add(uuid);
-
- nodesToVisit.addAll(nodeToCheck.getChildren());
- }
-
- // If any of the UUIDS currently exist in this workspace, throw an exception
- for (UUID uuid : uuidsFromSource) {
- Fqn<Path.Segment> path;
- if (null != (path = getFullyQualifiedName(intoCache, uuid))) {
- String pathAsString = path.toString();
- throw new UuidAlreadyExistsException(this.getSourceName(), uuid,
pathAsString, request.intoWorkspace());
- }
- }
- }
-
- // Copy the branch ...
- Name desiredName = request.desiredName();
- Path.Segment newSegment = copyNode(intoCache,
- node,
- newParent,
- desiredName,
- null,
- true,
- request.uuidConflictBehavior(),
- null,
- getExecutionContext());
-
- mapUuids(intoCache,
Fqn.fromRelativeElements(Fqn.fromList(newParentPath.getSegmentsList()), newSegment));
- Path newPath = pathFactory.create(newParentPath, newSegment);
- request.setActualLocations(Location.create(nodePath), Location.create(newPath));
- recordChange(request);
- }
-
- @SuppressWarnings( "unchecked" )
- private boolean deleteNode( Cache<Name, Object> cache,
- Node<Name, Object> node ) {
- Fqn<Path.Segment> nodeFqn = node.getFqn();
-
- removeUuids(cache, nodeFqn);
- Path.Segment nameOfRemovedNode = (Path.Segment)nodeFqn.getLastElement();
- if (cache.removeNode(node.getFqn())) {
- removeFromChildList(cache, node.getParent(), nameOfRemovedNode,
getExecutionContext());
- return true;
- }
- return false;
- }
-
- @Override
- public void process( DeleteBranchRequest request ) {
- // Look up the cache and the node ...
- Cache<Name, Object> cache = getCache(request, request.inWorkspace());
- if (cache == null) return;
- Path nodePath = request.at().getPath();
- Node<Name, Object> node = getNode(request, cache, nodePath);
- if (node == null) return;
-
- if (deleteNode(cache, node)) {
- request.setActualLocationOfNode(Location.create(nodePath));
- recordChange(request);
- } else {
- String msg =
JBossCacheConnectorI18n.unableToDeleteBranch.text(getSourceName(), request.inWorkspace(),
nodePath);
- request.setError(new RepositorySourceException(msg));
- }
- }
-
- @Override
- @SuppressWarnings( "unchecked" )
- public void process( MoveBranchRequest request ) {
- // Look up the caches ...
- Cache<Name, Object> cache = getCache(request, request.inWorkspace());
- if (cache == null) return;
-
- // Look up the current node and the new parent (both of which must exist) ...
- Path nodePath = request.from().getPath();
- Node<Name, Object> node = getNode(request, cache, nodePath);
- if (node == null) return;
- Path newParentPath;
-
- if (request.into() != null) {
- newParentPath = request.into().getPath();
- } else {
- // into() and before() can't both be null
- assert request.before() != null;
- newParentPath = request.before().getPath().getParent();
- }
-
- Path.Segment beforeNodeName = request.before() != null ?
request.before().getPath().getLastSegment() : null;
- Node<Name, Object> newParent = getNode(request, cache, newParentPath);
- if (newParent == null) return;
-
- removeUuids(cache, node.getFqn());
-
- // Copy the branch and use the same UUIDs ...
- Name desiredName = request.desiredName();
- Path.Segment newSegment = copyNode(cache,
- node,
- newParent,
- desiredName,
- beforeNodeName,
- true,
- UuidConflictBehavior.THROW_EXCEPTION,
- null,
- getExecutionContext());
- mapUuids(cache, node.getFqn());
- // 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));
- recordChange(request);
- }
-
- /**
- * {@inheritDoc}
- *
- * @see
org.jboss.dna.graph.request.processor.RequestProcessor#process(org.jboss.dna.graph.request.VerifyWorkspaceRequest)
- */
- @Override
- public void process( VerifyWorkspaceRequest request ) {
- String workspaceName = request.workspaceName();
- if (workspaceName == null) workspaceName = defaultWorkspaceName;
-
- Cache<Name, Object> cache = workspaces.getWorkspace(workspaceName, false);
- if (cache == null) {
- String msg =
JBossCacheConnectorI18n.workspaceDoesNotExist.text(getSourceName(), workspaceName);
- request.setError(new InvalidWorkspaceException(msg));
- } else {
- Fqn<Path.Segment> rootName = Fqn.root();
- UUID uuid = uuidFactory.create(cache.get(rootName, DnaLexicon.UUID));
- if (uuid == null) {
- uuid = uuidFactory.create();
- cache.put(rootName, DnaLexicon.UUID, uuid);
- }
-
request.setActualRootLocation(Location.create(pathFactory.createRootPath()));
- request.setActualWorkspaceName(workspaceName);
- }
- }
-
- /**
- * {@inheritDoc}
- *
- * @see
org.jboss.dna.graph.request.processor.RequestProcessor#process(org.jboss.dna.graph.request.GetWorkspacesRequest)
- */
- @Override
- public void process( GetWorkspacesRequest request ) {
- request.setAvailableWorkspaceNames(workspaces.getWorkspaceNames());
- }
-
- /**
- * {@inheritDoc}
- *
- * @see
org.jboss.dna.graph.request.processor.RequestProcessor#process(org.jboss.dna.graph.request.CreateWorkspaceRequest)
- */
- @Override
- public void process( CreateWorkspaceRequest request ) {
- String workspaceName = request.desiredNameOfNewWorkspace();
- if (!creatingWorkspacesAllowed) {
- String msg =
JBossCacheConnectorI18n.unableToCreateWorkspaces.text(getSourceName(), workspaceName);
- request.setError(new InvalidRequestException(msg));
- return;
- }
- // Try to create the workspace ...
- Cache<Name, Object> cache = workspaces.getWorkspace(workspaceName,
creatingWorkspacesAllowed);
- if (cache == null) {
- String msg =
JBossCacheConnectorI18n.unableToCreateWorkspace.text(getSourceName(), workspaceName);
- request.setError(new InvalidWorkspaceException(msg));
- return;
- }
- // Make sure the root node has a UUID ...
- Fqn<Path.Segment> rootName = Fqn.root();
- UUID uuid = uuidFactory.create(cache.get(rootName, DnaLexicon.UUID));
- if (uuid == null) {
- uuid = uuidFactory.create();
- cache.put(rootName, DnaLexicon.UUID, uuid);
- mapUuid(cache, uuid, rootName);
- }
- request.setActualRootLocation(Location.create(pathFactory.createRootPath()));
- request.setActualWorkspaceName(workspaceName);
- recordChange(request);
- }
-
- /**
- * {@inheritDoc}
- *
- * @see
org.jboss.dna.graph.request.processor.RequestProcessor#process(org.jboss.dna.graph.request.CloneWorkspaceRequest)
- */
- @Override
- @SuppressWarnings( "unchecked" )
- public void process( CloneWorkspaceRequest request ) {
- String fromWorkspaceName = request.nameOfWorkspaceToBeCloned();
- String toWorkspaceName = request.desiredNameOfTargetWorkspace();
- if (!creatingWorkspacesAllowed) {
- String msg =
JBossCacheConnectorI18n.unableToCloneWorkspaces.text(getSourceName(), fromWorkspaceName,
toWorkspaceName);
- request.setError(new InvalidRequestException(msg));
- return;
- }
- // Make sure there is already a workspace that we're cloning ...
- Cache<Name, Object> fromCache = workspaces.getWorkspace(fromWorkspaceName,
false);
- if (fromCache == null) {
- String msg =
JBossCacheConnectorI18n.workspaceDoesNotExist.text(getSourceName(), fromWorkspaceName);
- request.setError(new InvalidWorkspaceException(msg));
- return;
- }
-
- // Try to create a new workspace with the target name ...
- Cache<Name, Object> intoCache =
workspaces.createWorkspace(toWorkspaceName);
- if (intoCache == null) {
- // Couldn't create it because one already exists ...
- String msg =
JBossCacheConnectorI18n.workspaceAlreadyExists.text(getSourceName(), toWorkspaceName);
- request.setError(new InvalidWorkspaceException(msg));
- return;
- }
-
- // And finally copy the contents ...
- Fqn<Path.Segment> rootName = Fqn.root();
- Node<Name, Object> fromRoot = fromCache.getNode(rootName);
- Node<Name, Object> intoRoot = intoCache.getNode(rootName);
- intoRoot.clearData();
- intoRoot.putAll(fromRoot.getData());
- ExecutionContext context = getExecutionContext();
-
- // Loop over each child and copy it ...
- for (Node<Name, Object> child : fromRoot.getChildren()) {
- copyNode(intoCache, child, intoRoot, null, null, true,
UuidConflictBehavior.THROW_EXCEPTION, null, context);
- }
-
- mapUuids(intoCache, intoRoot.getFqn());
- // Copy the list of child segments in the root (this maintains the order of the
children) ...
- Path.Segment[] childNames =
(Path.Segment[])fromRoot.get(JBossCacheLexicon.CHILD_PATH_SEGMENT_LIST);
- intoRoot.put(JBossCacheLexicon.CHILD_PATH_SEGMENT_LIST, childNames);
- recordChange(request);
- }
-
- /**
- * {@inheritDoc}
- *
- * @see
org.jboss.dna.graph.request.processor.RequestProcessor#process(org.jboss.dna.graph.request.DestroyWorkspaceRequest)
- */
- @Override
- public void process( DestroyWorkspaceRequest request ) {
- Cache<Name, Object> fromCache =
workspaces.getWorkspace(request.workspaceName(), false);
- if (fromCache == null) {
- String msg =
JBossCacheConnectorI18n.workspaceDoesNotExist.text(getSourceName(),
request.workspaceName());
- request.setError(new InvalidWorkspaceException(msg));
- return;
- }
- request.setActualRootLocation(Location.create(pathFactory.createRootPath()));
- recordChange(request);
- }
-
- //
----------------------------------------------------------------------------------------------------------------
- // Utility methods
- //
----------------------------------------------------------------------------------------------------------------
-
- /**
- * Obtain the appropriate cache for the supplied workspace name, or set an error on
the request if the workspace does not
- * exist (and could not or should not be created).
- *
- * @param request the request
- * @param workspaceName the workspace name
- * @return the cache, or null if there is no such workspace
- */
- protected Cache<Name, Object> getCache( Request request,
- String workspaceName ) {
- if (workspaceName == null) workspaceName = defaultWorkspaceName;
- Cache<Name, Object> cache = workspaces.getWorkspace(workspaceName,
creatingWorkspacesAllowed);
- if (cache == null && request != null) {
- String msg =
JBossCacheConnectorI18n.workspaceDoesNotExist.text(getSourceName(), workspaceName);
- request.setError(new InvalidWorkspaceException(msg));
- }
- return cache;
- }
-
- protected Fqn<Path.Segment> getFullyQualifiedName( Path path ) {
- assert path != null;
- return Fqn.fromList(path.getSegmentsList());
- }
-
- /**
- * Get a relative fully-qualified name that consists only of the supplied segment.
- *
- * @param pathSegment the segment from which the fully qualified name is to be
created
- * @return the relative fully-qualified name
- */
- protected Fqn<Path.Segment> getFullyQualifiedName( Path.Segment pathSegment )
{
- assert pathSegment != null;
- return Fqn.fromElements(pathSegment);
- }
-
- @SuppressWarnings( "unchecked" )
- protected Fqn<Path.Segment> getFullyQualifiedName( Cache<Name, Object>
cache,
- UUID uuid ) {
- assert cache != null;
- assert uuid != null;
-
- Fqn<Path.Segment> uuidFqn = Fqn.fromElements(dnaUuidsSegment,
pathFactory.createSegment(uuid.toString()));
-
- return (Fqn<Path.Segment>)cache.get(uuidFqn, JBossCacheLexicon.FQN);
- }
-
- protected Path getPath( PathFactory factory,
- Fqn<Path.Segment> fqn ) {
- List<Path.Segment> segments = fqn.peekElements();
- return factory.create(factory.createRootPath(), segments);
- }
-
- protected void removeUuid( Cache<Name, Object> cache,
- UUID uuid ) {
- assert cache != null;
- assert uuid != null;
-
- Fqn<Path.Segment> uuidFqn =
Fqn.fromElements(pathFactory.createSegment(JBossCacheLexicon.UUIDS),
-
pathFactory.createSegment(uuid.toString()));
-
- removeFromChildList(cache,
- getNode(null, cache,
pathFactory.create(JBossCacheLexicon.UUIDS)),
- pathFactory.createSegment(uuid.toString()),
- getExecutionContext());
- cache.removeNode(uuidFqn);
- }
-
- @SuppressWarnings( "unchecked" )
- protected void mapUuid( Cache<Name, Object> cache,
- UUID uuid,
- Fqn<Path.Segment> path ) {
- assert cache != null;
- assert uuid != null;
-
- Fqn<Path.Segment> uuidsFqn = Fqn.fromElements(this.dnaUuidsSegment);
-
- Node uuidsNode = cache.getNode(uuidsFqn);
- if (uuidsNode == null) {
- uuidsNode = cache.getRoot().addChild(uuidsFqn);
- updateChildList(cache, cache.getRoot(), this.dnaUuidsSegment.getName(), null,
this.getExecutionContext(), true);
- }
-
- assert uuidsNode != null : this.dnaUuidsSegment.getName() + "=" +
uuidsFqn;
- Path.Segment uuidSegment = pathFactory.createSegment(uuid.toString());
-
- if (!uuidsNode.getChildrenNames().contains(uuidSegment)) {
- Path.Segment newSegment = updateChildList(cache,
- uuidsNode,
- uuidSegment.getName(),
- null,
- this.getExecutionContext(),
- true);
- assert newSegment.getIndex() == 1 : "Should not have SNS under uuids
branch";
- }
-
- Fqn<Path.Segment> uuidFqn = Fqn.fromRelativeElements(uuidsFqn,
uuidSegment);
-
- cache.put(uuidFqn, JBossCacheLexicon.FQN, path);
- assert cache.getNode(uuidFqn) != null;
- assert cache.get(uuidFqn, JBossCacheLexicon.FQN) != null;
- assert path.equals(getFullyQualifiedName(cache, uuid)) : path + " =>
" + getFullyQualifiedName(cache, uuid);
- }
-
- protected void mapUuids( Cache<Name, Object> cache,
- Fqn<Path.Segment> path ) {
- Node<Name, Object> node = cache.getNode(path);
- assert node != null : path.toString();
- UUID uuid = (UUID)node.get(DnaLexicon.UUID);
- if (uuid != null) {
- mapUuid(cache, uuid, path);
- assert getFullyQualifiedName(cache, uuid).equals(path);
- }
-
- Path.Segment[] childNamesProperty =
(Path.Segment[])node.get(JBossCacheLexicon.CHILD_PATH_SEGMENT_LIST);
- if (childNamesProperty == null) return;
-
- for (Path.Segment childName : childNamesProperty) {
- Fqn<Path.Segment> childPath = Fqn.fromRelativeElements(path,
childName);
- mapUuids(cache, childPath);
- }
- }
-
- protected void removeUuids( Cache<Name, Object> cache,
- Fqn<Path.Segment> path ) {
- Node<Name, Object> node = cache.getNode(path);
- assert node != null : path.toString();
- UUID uuid = (UUID)node.get(DnaLexicon.UUID);
-
- if (uuid != null) removeUuid(cache, uuid);
-
- Path.Segment[] childNamesProperty =
(Path.Segment[])node.get(JBossCacheLexicon.CHILD_PATH_SEGMENT_LIST);
- if (childNamesProperty == null) return;
-
- for (Path.Segment childName : childNamesProperty) {
- Fqn<Path.Segment> childPath = Fqn.fromRelativeElements(path,
childName);
- removeUuids(cache, childPath);
- }
- }
-
- protected Node<Name, Object> getNode( Request request,
- Cache<Name, Object> cache,
- Path path ) {
- ExecutionContext context = getExecutionContext();
- if (path == null) {
- String msg =
JBossCacheConnectorI18n.locationsMustHavePath.text(getSourceName(), request);
- request.setError(new InvalidRequestException(msg));
- return null;
- }
- // Look up the node with the supplied path ...
- Fqn<Path.Segment> fqn = getFullyQualifiedName(path);
- Node<Name, Object> node = cache.getNode(fqn);
-
- if (node == null) {
- String nodePath = path.getString(context.getNamespaceRegistry());
- Path lowestExisting = null;
- while (fqn != null) {
- fqn = fqn.getParent();
- node = cache.getNode(fqn);
- if (node != null) {
- lowestExisting =
getPath(context.getValueFactories().getPathFactory(), fqn);
- fqn = null;
- }
- }
- request.setError(new PathNotFoundException(Location.create(path),
lowestExisting,
-
JBossCacheConnectorI18n.nodeDoesNotExist.text(nodePath)));
- node = null;
- }
- return node;
-
- }
-
- /**
- * @param newCache the cache into which the node is to be copied
- * @param original the node to be copied
- * @param newParent the new parent of the node to be copied
- * @param desiredName the desired name of the node in the new location
- * @param beforeNodeName the node before which the new node should be placed
- * @param recursive if this is a deep copy
- * @param uuidConflictBehavior indicates whether the original UUIDs should be used
for the copies or new UUIDs should be used
- * @param count the count of nodes affected by the operation
- * @param context the execution context that provides the path factory to be used to
create the new path name
- * @return the path segment that identifies the new node under its new parent
- */
- @SuppressWarnings( "unchecked" )
- protected Path.Segment copyNode( Cache<Name, Object> newCache,
- Node<Name, Object> original,
- Node<Name, Object> newParent,
- Name desiredName,
- Path.Segment beforeNodeName,
- boolean recursive,
- UuidConflictBehavior uuidConflictBehavior,
- AtomicInteger count,
- ExecutionContext context ) {
- assert original != null;
- assert newParent != null;
- // Get or create the new node ...
- Path.Segment name = desiredName != null ?
context.getValueFactories().getPathFactory().createSegment(desiredName) :
(Path.Segment)original.getFqn()
-
.getLastElement();
-
- // Update the children to account for same-name siblings.
- // This not only updates the FQN of the child nodes, but it also sets the
property that stores the
- // the array of Path.Segment for the children (since the cache doesn't
maintain order).
- Path.Segment newSegment = updateChildList(newCache, newParent, name.getName(),
beforeNodeName, context, true);
- Node<Name, Object> copy =
newParent.addChild(getFullyQualifiedName(newSegment));
- assert checkChildren(newParent);
- // Copy the properties ...
- copy.clearData();
- copy.putAll(original.getData());
- copy.remove(JBossCacheLexicon.CHILD_PATH_SEGMENT_LIST); // will be reset later
...
-
- UUID uuid;
- switch (uuidConflictBehavior) {
- case ALWAYS_CREATE_NEW_UUID:
- uuid = UUID.randomUUID();
- break;
- case REPLACE_EXISTING_NODE:
- uuid = uuidFactory.create(original.get(DnaLexicon.UUID));
- Fqn<?> existingPath = getFullyQualifiedName(newCache, uuid);
- if (existingPath != null) {
- Node<Name, Object> existingNode =
newCache.getNode(existingPath);
- deleteNode(newCache, existingNode);
- }
-
- break;
- case THROW_EXCEPTION:
- uuid = uuidFactory.create(original.get(DnaLexicon.UUID));
- break;
- default:
- throw new IllegalStateException("Unexpected UuidConflictBehavior
value: " + uuidConflictBehavior);
- }
- copy.put(DnaLexicon.UUID, uuid);
-
- if (count != null) count.incrementAndGet();
- if (recursive) {
- // Loop over each child and call this method ...
- for (Node<Name, Object> child : original.getChildren()) {
- copyNode(newCache, child, copy, null, null, true, uuidConflictBehavior,
count, context);
- }
- }
- mapUuids(newCache, copy.getFqn());
- assert getFullyQualifiedName(newCache, uuid) != null;
- return newSegment;
- }
-
- /**
- * Update (or create) the array of {@link Path.Segment path segments} for the
children of the supplied node. 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 changedName the name that should be compared to the existing node siblings
to determine whether the same-name
- * sibling indexes should be updated; may not be null
- * @param beforeNodeName the name of the node before which this node should be
placed; null indicates that this node should be
- * added as the last child under the node
- * @param context the execution context; may not be null
- * @param addChildWithName true if a new child with the supplied name is to be added
to the children (but which does not yet
- * exist in the node's children)
- * @return the path segment for the new child, or null if
<code>addChildWithName</code> was false
- */
- protected Path.Segment updateChildList( Cache<Name, Object> cache,
- Node<Name, Object> parent,
- Name changedName,
- Path.Segment beforeNodeName,
- ExecutionContext context,
- boolean addChildWithName ) {
- assert parent != null;
- assert changedName != null;
- assert context != null;
- Set<Node<Name, Object>> children = parent.getChildren();
- if (children.isEmpty() && !addChildWithName) return null;
-
- // Go through the children, looking for any children with the same name as the
'changedName'
- List<ChildInfo> childrenWithChangedName = new
LinkedList<ChildInfo>();
- Path.Segment[] childNames =
(Path.Segment[])parent.get(JBossCacheLexicon.CHILD_PATH_SEGMENT_LIST);
- int index = 0;
- int snsIndex = 0;
- boolean foundBeforeNode = false;
- if (childNames != null) {
- for (Path.Segment childName : childNames) {
- if (childName.equals(beforeNodeName)) {
- foundBeforeNode = true;
- // And add a child info for the new node ...
- ChildInfo info = new ChildInfo(null, snsIndex++);
- childrenWithChangedName.add(info);
- }
- if (childName.getName().equals(changedName)) {
- ChildInfo info = new ChildInfo(childName, snsIndex);
- childrenWithChangedName.add(info);
- }
-
- snsIndex++;
- if (!foundBeforeNode) index++;
- }
-
- }
- if (addChildWithName) {
- // Make room for the new child at the end of the array ...
- if (childNames == null) {
- childNames = new Path.Segment[1];
- } else {
- int numExisting = childNames.length;
- Path.Segment[] newChildNames = new Path.Segment[numExisting + 1];
- System.arraycopy(childNames, 0, newChildNames, 0, index);
-
- if (index != numExisting) {
- System.arraycopy(childNames, index, newChildNames, index + 1,
numExisting - index);
- }
- childNames = newChildNames;
- }
-
- if (!foundBeforeNode) {
- // Make sure that we add a record for the new node if it hasn't
previously been added
- ChildInfo info = new ChildInfo(null, index);
- childrenWithChangedName.add(info);
-
- }
- Path.Segment newSegment =
context.getValueFactories().getPathFactory().createSegment(changedName);
- childNames[index] = newSegment;
- }
- assert childNames != null;
-
- // Now process the children with the same name, which may include a child info
for the new node ...
- assert childrenWithChangedName.isEmpty() == false;
- if (childrenWithChangedName.size() == 1) {
- // The child should have no indexes ...
- ChildInfo child = childrenWithChangedName.get(0);
- if (child.segment != null && child.segment.hasIndex()) {
- // The existing child needs to have a new index ..
- Path.Segment newSegment =
context.getValueFactories().getPathFactory().createSegment(changedName);
- // Replace the child with the correct FQN ...
- changeNodeName(cache, parent, child.segment, newSegment, context);
- // Change the segment in the child list ...
- childNames[child.childIndex] = newSegment;
- }
- } else {
- // There is more than one child with the same name ...
- int i = 0;
- for (ChildInfo child : childrenWithChangedName) {
- if (child.segment != null) {
- // Determine the new name and index ...
- Path.Segment newSegment =
context.getValueFactories().getPathFactory().createSegment(changedName, i + 1);
- // Replace the child with the correct FQN ...
- changeNodeName(cache, parent, child.segment, newSegment, context);
- // Change the segment in the child list ...
- childNames[child.childIndex] = newSegment;
- } else {
- // Determine the new name and index ...
- Path.Segment newSegment =
context.getValueFactories().getPathFactory().createSegment(changedName, i + 1);
- childNames[child.childIndex] = newSegment;
- }
- ++i;
- }
- }
-
- // Record the list of children as a property on the parent ...
- // (Do this last, as it doesn't need to be done if there's an exception
in the above logic)
- context.getLogger(getClass()).trace("Updating child list of {0} to:
{1}", parent.getFqn(), Arrays.asList(childNames));
- parent.put(JBossCacheLexicon.CHILD_PATH_SEGMENT_LIST, childNames); // replaces
any existing value
-
- if (addChildWithName) {
- // Return the segment for the new node ...
- return childNames[index];
- }
- 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();
- boolean result = true;
- if (childNamesProperty.length != childNames.size()) result = false;
- if (!result) throw new IllegalStateException(parent.getFqn().toString());
- for (int i = 0; i != childNamesProperty.length; ++i) {
- if (!childNames.contains(childNamesProperty[i])) result = false;
- }
- if (!result) throw new IllegalStateException(parent.getFqn().toString());
- if (!result) {
- List<Path.Segment> names = new ArrayList<Path.Segment>();
- for (Object name : childNames) {
- assert name instanceof Path.Segment : parent.getFqn().toString() +
"/" + name.toString();
- names.add((Path.Segment)name);
- }
- Collections.sort(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);
- }
- if (!result) throw new IllegalStateException(parent.getFqn().toString());
- return result;
- }
-
- /**
- * Utility class used by the
- * {@link JBossCacheRequestProcessor#updateChildList(Cache, Node, Name,
org.jboss.dna.graph.property.Path.Segment, ExecutionContext, boolean)}
- * method.
- *
- * @author Randall Hauch
- */
- private static class ChildInfo {
- protected final Path.Segment segment;
- protected final int childIndex;
-
- protected ChildInfo( Path.Segment childSegment,
- int childIndex ) {
- this.segment = childSegment;
- this.childIndex = childIndex;
- }
-
- @Override
- public String toString() {
- return (segment != null ? segment.getString() : "null") +
"@" + childIndex;
- }
-
- }
-
- /**
- * Changes the name of the node in the cache (but does not update the list of child
segments stored on the parent).
- *
- * @param cache
- * @param parent
- * @param existing
- * @param newSegment
- * @param context
- */
- @SuppressWarnings( "unchecked" )
- protected void changeNodeName( Cache<Name, Object> cache,
- Node<Name, Object> parent,
- Path.Segment existing,
- Path.Segment newSegment,
- ExecutionContext context ) {
- assert parent != null;
- assert existing != null;
- assert newSegment != null;
- assert context != null;
-
- if (existing.equals(newSegment)) return;
- context.getLogger(getClass()).trace("Renaming {0} to {1} under {2}",
existing, newSegment, parent.getFqn());
- Node<Name, Object> existingChild = parent.getChild(existing);
- assert existingChild != null : parent.getFqn().toString() + "/" +
existing;
-
- // JBoss Cache can move a node from one node to another node, but the move
doesn't change the name;
- // since you provide the FQN of the parent location, the name of the node cannot
be changed.
- // Therefore, to compensate, we need to create a new child, copy all of the data,
move all of the child
- // nodes of the old node, then remove the old node.
-
- // Create the new node ...
- Node<Name, Object> newChild =
parent.addChild(Fqn.fromElements(newSegment));
- Fqn<Path.Segment> newChildFqn = newChild.getFqn();
-
- // Copy the data ...
- newChild.putAll(existingChild.getData());
-
- // Move the children ...
- for (Node<Name, Object> grandChild : existingChild.getChildren()) {
- cache.move(grandChild.getFqn(), newChildFqn);
- }
-
- // Remove the existing ...
- parent.removeChild(existing);
- }
-}
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-06-24
22:14:12 UTC (rev 1064)
+++
trunk/extensions/dna-connector-jbosscache/src/main/java/org/jboss/dna/connector/jbosscache/JBossCacheSource.java 2009-06-27
02:54:06 UTC (rev 1065)
@@ -45,11 +45,14 @@
import javax.naming.Referenceable;
import javax.naming.StringRefAddr;
import javax.naming.spi.ObjectFactory;
+import net.jcip.annotations.GuardedBy;
import net.jcip.annotations.ThreadSafe;
import org.jboss.cache.Cache;
import org.jboss.cache.CacheFactory;
import org.jboss.cache.DefaultCacheFactory;
+import org.jboss.cache.config.ConfigurationException;
import org.jboss.dna.common.i18n.I18n;
+import org.jboss.dna.common.util.Logger;
import org.jboss.dna.common.util.StringUtil;
import org.jboss.dna.graph.DnaLexicon;
import org.jboss.dna.graph.cache.CachePolicy;
@@ -58,8 +61,11 @@
import org.jboss.dna.graph.connector.RepositorySource;
import org.jboss.dna.graph.connector.RepositorySourceCapabilities;
import org.jboss.dna.graph.connector.RepositorySourceException;
+import org.jboss.dna.graph.connector.map.MapNode;
+import org.jboss.dna.graph.connector.map.MapRepositoryConnection;
+import org.jboss.dna.graph.connector.map.MapRepositorySource;
import org.jboss.dna.graph.observe.Observer;
-import org.jboss.dna.graph.property.Name;
+import org.jboss.dna.graph.request.CreateWorkspaceRequest.CreateConflictBehavior;
/**
* A repository source that uses a JBoss Cache instance to manage the content. This
source is capable of using an existing
@@ -79,7 +85,7 @@
* @author Randall Hauch
*/
@ThreadSafe
-public class JBossCacheSource implements RepositorySource, ObjectFactory {
+public class JBossCacheSource implements MapRepositorySource, ObjectFactory {
private static final long serialVersionUID = 2L;
/**
@@ -114,9 +120,10 @@
private volatile String defaultWorkspace;
private volatile String[] predefinedWorkspaces = new String[] {};
private volatile RepositorySourceCapabilities capabilities = new
RepositorySourceCapabilities(true, true, false, true, false);
- private transient JBossCacheWorkspaces workspaces;
+ private transient JBossCacheRepository repository;
private transient Context jndiContext;
private transient RepositoryContext repositoryContext;
+ private final Set<String> repositoryNamesForConfigurationNameProblems = new
HashSet<String>();
/**
* Create a repository source instance.
@@ -435,7 +442,7 @@
I18n msg = JBossCacheConnectorI18n.propertyIsRequired;
throw new RepositorySourceException(getName(), msg.text("name"));
}
- if (this.workspaces == null) {
+ if (this.repository == null) {
Context context = getContext();
if (context == null) {
try {
@@ -446,13 +453,13 @@
}
// Look for a cache factory in JNDI ...
- CacheFactory<Name, Object> cacheFactory = null;
+ CacheFactory<UUID, MapNode> cacheFactory = null;
String jndiName = getCacheFactoryJndiName();
if (jndiName != null && jndiName.trim().length() != 0) {
Object object = null;
try {
object = context.lookup(jndiName);
- if (object != null) cacheFactory = (CacheFactory<Name,
Object>)object;
+ if (object != null) cacheFactory = (CacheFactory<UUID,
MapNode>)object;
} catch (ClassCastException err) {
I18n msg =
JBossCacheConnectorI18n.objectFoundInJndiWasNotCacheFactory;
String className = object != null ? object.getClass().getName() :
"null";
@@ -462,27 +469,65 @@
throw new RepositorySourceException(getName(), err);
}
}
- if (cacheFactory == null) cacheFactory = new DefaultCacheFactory<Name,
Object>();
+ if (cacheFactory == null) cacheFactory = new DefaultCacheFactory<UUID,
MapNode>();
- // Get the default cache configuration name
- String configName = this.getCacheConfigurationName();
+ // Now create the repository ...
+ this.repository = new JBossCacheRepository(getName(), this.rootNodeUuid,
createNewCache(cacheFactory, getName()));
// Create the set of initial names ...
- Set<String> initialNames = new HashSet<String>();
for (String initialName : getPredefinedWorkspaceNames())
- initialNames.add(initialName);
+ repository.createWorkspace(null, initialName,
CreateConflictBehavior.DO_NOT_CREATE);
+
+ }
- // Now create the workspace manager ...
- this.workspaces = new JBossCacheWorkspaces(getName(), cacheFactory,
configName, initialNames, context);
+ return new MapRepositoryConnection(this, this.repository);
+ }
+
+ /**
+ * Method that is responsible for attempting to create a new cache given the supplied
workspace name. Note that this is
+ * probably called at most once for each workspace name (except if this method fails
to create a cache for a given workspace
+ * name).
+ *
+ * @param workspaceName the name of the workspace
+ * @return the new cache that corresponds to the workspace name
+ */
+ @GuardedBy( "writeLock" )
+ protected Cache<UUID, MapNode> createNewCache( CacheFactory<UUID,
MapNode> cacheFactory, String repositoryName ) {
+ assert repositoryName != null;
+ if (cacheFactory == null) return null;
+
+ // Try to create the cache using the workspace name as the configuration ...
+ try {
+ return cacheFactory.createCache(repositoryName);
+ } catch (ConfigurationException error) {
+ // The workspace name is probably not the name of a configuration ...
+ I18n msg = JBossCacheConnectorI18n.workspaceNameWasNotValidConfiguration;
+ Logger.getLogger(getClass()).debug(msg.text(repositoryName,
error.getMessage()));
}
- return new JBossCacheConnection(this, this.workspaces);
+ if (this.cacheConfigurationName != null) {
+ // Try to create the cache using the default configuration name ...
+ try {
+ return cacheFactory.createCache(getCacheConfigurationName());
+ } catch (ConfigurationException error) {
+ // The default configuration name is not valid ...
+ if (this.repositoryNamesForConfigurationNameProblems.add(repositoryName))
{
+ // Log this problem only the first time ...
+ I18n msg =
JBossCacheConnectorI18n.defaultCacheFactoryConfigurationNameWasNotValidConfiguration;
+ Logger.getLogger(getClass()).debug(msg.text(repositoryName));
+ }
+ }
+ }
+
+ // Just create a new cache with the default configuration ...
+ return cacheFactory.createCache();
}
+
/**
* @return repositoryContext
*/
- protected RepositoryContext getRepositoryContext() {
+ public RepositoryContext getRepositoryContext() {
return repositoryContext;
}
Deleted:
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-06-24
22:14:12 UTC (rev 1064)
+++
trunk/extensions/dna-connector-jbosscache/src/main/java/org/jboss/dna/connector/jbosscache/JBossCacheWorkspaces.java 2009-06-27
02:54:06 UTC (rev 1065)
@@ -1,297 +0,0 @@
-/*
- * JBoss DNA (
http://www.jboss.org/dna)
- * See the COPYRIGHT.txt file distributed with this work for information
- * regarding copyright ownership. Some portions may be licensed
- * to Red Hat, Inc. under one or more contributor license agreements.
- * See the AUTHORS.txt file in the distribution for a full listing of
- * individual contributors.
- *
- * 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 java.net.URI;
-import java.net.URISyntaxException;
-import java.util.Collections;
-import java.util.HashSet;
-import java.util.Set;
-import java.util.concurrent.ConcurrentHashMap;
-import java.util.concurrent.locks.Lock;
-import java.util.concurrent.locks.ReentrantLock;
-import javax.naming.Context;
-import net.jcip.annotations.GuardedBy;
-import net.jcip.annotations.ThreadSafe;
-import org.jboss.cache.Cache;
-import org.jboss.cache.CacheFactory;
-import org.jboss.cache.config.ConfigurationException;
-import org.jboss.dna.common.i18n.I18n;
-import org.jboss.dna.common.util.Logger;
-import org.jboss.dna.graph.connector.RepositorySourceException;
-import org.jboss.dna.graph.property.Name;
-
-/**
- * This class represents a set of workspaces used by the {@link JBossCacheSource JBoss
Cache connector}.
- */
-@ThreadSafe
-public class JBossCacheWorkspaces {
-
- private final String sourceName;
- private final ConcurrentHashMap<String, Cache<Name, Object>> caches = new
ConcurrentHashMap<String, Cache<Name, Object>>();
- private final Set<String> initialNames;
- private final CacheFactory<Name, Object> cacheFactory;
- private final String defaultCacheFactoryConfigurationName;
- private final Context jndi;
- private final Set<String> workspaceNamesForJndiClassCastProblems = new
HashSet<String>();
- private final Set<String> workspaceNamesForConfigurationNameProblems = new
HashSet<String>();
- private final Lock writeLock = new ReentrantLock();
-
- /**
- * Create a new instance of the workspace and cache manager for the JBoss Cache
connector.
- *
- * @param sourceName the name of the source that uses this object; may not be null
- * @param cacheFactory the factory that should be used to create new caches; may not
be null
- * @param defaultCacheFactoryConfigurationName the name of the configuration that is
supplied to the {@link CacheFactory cache
- * factory} to {@link CacheFactory#createCache(String) create the new cache}
if the workspace name does not correspond
- * to a configuration; may be null
- * @param initialNames the initial names for the workspaces; may be null or empty
- * @param jndiContext the JNDI context that should be used, or null if JNDI should
not be used at all
- */
- public JBossCacheWorkspaces( String sourceName,
- CacheFactory<Name, Object> cacheFactory,
- String defaultCacheFactoryConfigurationName,
- Set<String> initialNames,
- Context jndiContext ) {
- assert sourceName != null;
- this.sourceName = sourceName;
- if (initialNames == null) initialNames = Collections.emptySet();
- this.initialNames = initialNames;
- this.cacheFactory = cacheFactory;
- this.defaultCacheFactoryConfigurationName =
defaultCacheFactoryConfigurationName;
- this.jndi = jndiContext;
- }
-
- /**
- * Attempt to create a new workspace with the supplied name.
- *
- * @param workspaceName the name of the new workspace, which may be a valid URI if
the cache is to be found in JNDI
- * @return the new workspace, or null if there is already a workspace with the name
- */
- public Cache<Name, Object> createWorkspace( String workspaceName ) {
- try {
- writeLock.lock();
- // First, see if there is already an existing cache ...
- Cache<Name, Object> cache = caches.get(workspaceName);
- if (cache != null) {
- // There is already a workspace, so we can't create ...
- return null;
- }
-
- // There isn't already a cache, but next check the list of initial names
...
- if (initialNames.contains(workspaceName)) {
- // The workspace already exists, but we just haven't accessed it yet
- return null;
- }
-
- // Time to create a new cache. First see if we're supposed to use a cache
already in JNDI ...
- cache = findCacheInJndi(workspaceName);
- if (cache == null) {
- // Try to create one ...
- cache = createNewCache(workspaceName);
- }
-
- if (cache != null) {
- // Manage this cache ...
- Cache<Name, Object> existing = caches.putIfAbsent(workspaceName,
cache);
- if (existing != null) cache = existing;
- }
- return cache; // may still be null if we couldn't create a new cache
-
- } finally {
- writeLock.unlock();
- }
- }
-
- /**
- * Get the cache that corresponds to the supplied workspace name, and optionally
create a new cache if no such cache already
- * exists. This method first checks for {@link Cache} instances previously found for
the same workspace name. If no cache is
- * found, this method then checks whether the supplied workspace name is a valid URI,
and if so the method looks for a
- * {@link Cache} instance in JNDI at that URI. If none is found (or the name is not a
valid URI), this method then creates a
- * new {@link Cache} instance using the {@link CacheFactory} supplied in the
constructor.
- *
- * @param workspaceName the name of the workspace, which may be a valid URI if the
cache is to be found in JNDI
- * @param createIfMissing true if the cache should be created if no such cache
already exists
- * @return the cache that corresponds to the workspace with the supplied name, or
null if there is no cache for that workspace
- * (and one could not be or was not created)
- */
- public Cache<Name, Object> getWorkspace( String workspaceName,
- boolean createIfMissing ) {
- // First, see if there is already an existing cache ...
- Cache<Name, Object> cache = caches.get(workspaceName);
- if (cache != null) return cache;
-
- try {
- writeLock.lock();
- // Ensure one didn't get created while we waited for the lock ...
- cache = caches.get(workspaceName);
- if (cache != null) return cache;
-
- // We've not yet come across the cache for the workspace.
-
- // Check whether the workspace name was one of the initial set of names...
- if (this.initialNames.contains(workspaceName)) {
- // This workspace/cache was one of those defined at startup to be
available,
- // so we really don't consider this to be "creating a new
cache"; it's just the first time we've used it
- // and we're lazily finding the instances. So, just mark
'createIfMissing' to true and continue ...
- createIfMissing = true;
- }
-
- if (!createIfMissing) return null;
-
- // First see if we can find a cache in JNDI ...
- cache = findCacheInJndi(workspaceName);
-
- if (cache == null) {
- // Try to create one ...
- cache = createNewCache(workspaceName);
- }
-
- if (cache != null) {
- Cache<Name, Object> existing = caches.putIfAbsent(workspaceName,
cache);
- if (existing != null) cache = existing;
- }
- return cache; // may still be null if we couldn't create a new cache
- } finally {
- writeLock.unlock();
- }
- }
-
- /**
- * Attempt to find an existing {@link Cache} object in JNDI, using the supplied
workspace name as the JNDI name.
- *
- * @param workspaceName the name of the workspace
- * @return the cache found in JNDI that corresponds to the workspace name
- */
- @SuppressWarnings( "unchecked" )
- @GuardedBy( "writeLock" )
- protected Cache<Name, Object> findCacheInJndi( String workspaceName ) {
- assert workspaceName != null;
- if (jndi == null) return null;
-
- // Try to look up the cache instance in JDNI ...
- workspaceName = workspaceName.trim();
- if (workspaceName.length() != 0) {
- try {
- new URI(workspaceName.trim());
- Object object = null;
- try {
- object = jndi.lookup(workspaceName);
- if (object != null && object instanceof Cache) {
- return (Cache<Name, Object>)object;
- }
- } catch (ClassCastException err) {
- // The object found in JNDI was not a JBoss Cache instance ...
- if (this.workspaceNamesForJndiClassCastProblems.add(workspaceName))
{
- // Log this problem only the first time ...
- String className = object != null ? object.getClass().getName() :
"null";
- I18n msg = JBossCacheConnectorI18n.objectFoundInJndiWasNotCache;
- Logger.getLogger(getClass()).warn(msg, workspaceName, sourceName,
className);
- }
- } catch (Throwable error) {
- // try loading
- if (error instanceof RuntimeException) throw
(RuntimeException)error;
- throw new RepositorySourceException(sourceName, error);
- }
-
- } catch (URISyntaxException err) {
- // Not a valid URI, so just continue ...
- }
- }
- return null;
- }
-
- /**
- * Method that is responsible for attempting to create a new cache given the supplied
workspace name. Note that this is
- * probably called at most once for each workspace name (except if this method fails
to create a cache for a given workspace
- * name).
- *
- * @param workspaceName the name of the workspace
- * @return the new cache that corresponds to the workspace name
- */
- @GuardedBy( "writeLock" )
- protected Cache<Name, Object> createNewCache( String workspaceName ) {
- assert workspaceName != null;
- if (this.cacheFactory == null) return null;
-
- // Try to create the cache using the workspace name as the configuration ...
- try {
- return this.cacheFactory.createCache(workspaceName);
- } catch (ConfigurationException error) {
- // The workspace name is probably not the name of a configuration ...
- I18n msg = JBossCacheConnectorI18n.workspaceNameWasNotValidConfiguration;
- Logger.getLogger(getClass()).debug(msg.text(workspaceName,
error.getMessage()));
- }
-
- if (this.defaultCacheFactoryConfigurationName != null) {
- // Try to create the cache using the default configuration name ...
- try {
- return
this.cacheFactory.createCache(this.defaultCacheFactoryConfigurationName);
- } catch (ConfigurationException error) {
- // The default configuration name is not valid ...
- if (this.workspaceNamesForConfigurationNameProblems.add(workspaceName))
{
- // Log this problem only the first time ...
- I18n msg =
JBossCacheConnectorI18n.defaultCacheFactoryConfigurationNameWasNotValidConfiguration;
- Logger.getLogger(getClass()).debug(msg.text(workspaceName));
- }
- }
- }
-
- // Just create a new cache with the default configuration ...
- return this.cacheFactory.createCache();
- }
-
- /**
- * Return an immutable set of names for the currently available workspaces.
- *
- * @return the immutable set of workspace names; never null
- */
- public Set<String> getWorkspaceNames() {
- Set<String> names = new HashSet<String>();
- if (!initialNames.isEmpty()) names.addAll(initialNames);
- names.addAll(caches.keySet());
- return Collections.unmodifiableSet(names);
- }
-
- /**
- * Remove the cache that corresponds to the supplied workspace name as no longer
being available. This will remove the cache
- * even if the workspace name is one of the "initial names" provided to
this object's constructor.
- *
- * @param workspaceName the name of the existing workspace that is to be removed
- * @return true if there was an existing workspace that was removed by this call, or
false if there was no workspace with the
- * supplied name
- */
- public boolean removeWorkspace( String workspaceName ) {
- try {
- writeLock.lock();
-
- // Remove this from both the cache and initialNames ...
- boolean removed = initialNames.remove(workspaceName);
- if (caches.remove(workspaceName) != null) removed = true;
- return removed;
- } finally {
- writeLock.unlock();
- }
- }
-}
Deleted:
trunk/extensions/dna-connector-jbosscache/src/test/java/org/jboss/dna/connector/jbosscache/JBossCacheRequestProcessorTest.java
===================================================================
---
trunk/extensions/dna-connector-jbosscache/src/test/java/org/jboss/dna/connector/jbosscache/JBossCacheRequestProcessorTest.java 2009-06-24
22:14:12 UTC (rev 1064)
+++
trunk/extensions/dna-connector-jbosscache/src/test/java/org/jboss/dna/connector/jbosscache/JBossCacheRequestProcessorTest.java 2009-06-27
02:54:06 UTC (rev 1065)
@@ -1,120 +0,0 @@
-/*
- * JBoss DNA (
http://www.jboss.org/dna)
- * See the COPYRIGHT.txt file distributed with this work for information
- * regarding copyright ownership. Some portions may be licensed
- * to Red Hat, Inc. under one or more contributor license agreements.
- * See the AUTHORS.txt file in the distribution for a full listing of
- * individual contributors.
- *
- * JBoss DNA is free software. Unless otherwise indicated, all code in JBoss DNA
- * is licensed to you under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation; either version 2.1 of
- * the License, or (at your option) any later version.
- *
- * JBoss DNA is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this software; if not, write to the Free
- * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA, or see the FSF site:
http://www.fsf.org.
- */
-package org.jboss.dna.connector.jbosscache;
-
-import static org.hamcrest.core.Is.is;
-import static org.junit.Assert.assertThat;
-import java.util.HashSet;
-import java.util.Set;
-import javax.naming.Context;
-import org.jboss.cache.CacheFactory;
-import org.jboss.cache.DefaultCacheFactory;
-import org.jboss.cache.Fqn;
-import org.jboss.dna.graph.DnaLexicon;
-import org.jboss.dna.graph.ExecutionContext;
-import org.jboss.dna.graph.property.Name;
-import org.jboss.dna.graph.property.Path;
-import org.jboss.dna.graph.property.PathFactory;
-import org.junit.Before;
-import org.junit.Test;
-import org.mockito.MockitoAnnotations;
-import org.mockito.MockitoAnnotations.Mock;
-
-/**
- * @author Randall Hauch
- */
-public class JBossCacheRequestProcessorTest {
-
- private JBossCacheRequestProcessor processor;
- private JBossCacheWorkspaces workspaces;
- private Set<String> initialWorkspaceNames;
- private String defaultWorkspaceName;
- private String defaultConfigName;
- private CacheFactory<Name, Object> cacheFactory;
- private ExecutionContext context;
- private PathFactory pathFactory;
- @Mock
- private Context jndi;
-
- @Before
- public void beforeEach() throws Exception {
- MockitoAnnotations.initMocks(this);
- context = new ExecutionContext();
- context.getNamespaceRegistry().register(DnaLexicon.Namespace.PREFIX,
DnaLexicon.Namespace.URI);
- context.getNamespaceRegistry().register(JBossCacheLexicon.Namespace.PREFIX,
JBossCacheLexicon.Namespace.URI);
-
- cacheFactory = new DefaultCacheFactory<Name, Object>();
- defaultConfigName = null;
- initialWorkspaceNames = new HashSet<String>();
- initialWorkspaceNames.add("workspace1");
- initialWorkspaceNames.add("workspace2");
- defaultWorkspaceName = initialWorkspaceNames.iterator().next();
- workspaces = new JBossCacheWorkspaces("source", cacheFactory,
defaultConfigName, initialWorkspaceNames, jndi);
- processor = new JBossCacheRequestProcessor("source", context, null,
workspaces, defaultWorkspaceName, true);
-
- pathFactory = context.getValueFactories().getPathFactory();
- }
-
- @Test
- public void shouldCreateFullyQualifiedNodeOfPathSegmentsFromPath() {
- Path path = pathFactory.create("/a/b/c/d");
- Fqn<?> fqn = processor.getFullyQualifiedName(path);
- assertThat(fqn.size(), is(4));
- assertThat(fqn.isRoot(), is(false));
- for (int i = 0; i != path.size(); ++i) {
- assertThat((Path.Segment)fqn.get(i), is(path.getSegment(i)));
- }
- }
-
- @Test
- public void shouldCreateFullyQualifiedNodeOfPathSegmentsFromRootPath() {
- Path path = pathFactory.createRootPath();
- Fqn<?> fqn = processor.getFullyQualifiedName(path);
- assertThat(fqn.size(), is(0));
- assertThat(fqn.isRoot(), is(true));
- }
-
- @Test
- public void shouldCreateFullyQualifiedNodeFromPathSegment() {
- Path.Segment segment = pathFactory.createSegment("a");
- Fqn<?> fqn = processor.getFullyQualifiedName(segment);
- assertThat(fqn.size(), is(1));
- assertThat(fqn.isRoot(), is(false));
- assertThat((Path.Segment)fqn.get(0), is(segment));
- }
-
- @Test
- public void shouldCreatePathFromFullyQualifiedNode() {
- Path path = pathFactory.create("/a/b/c/d");
- Fqn<Path.Segment> fqn = processor.getFullyQualifiedName(path);
- assertThat(processor.getPath(pathFactory, fqn), is(path));
- }
-
- @Test
- public void shouldCreateRootPathFromRootFullyQualifiedNode() {
- Path path = pathFactory.createRootPath();
- Fqn<Path.Segment> fqn = processor.getFullyQualifiedName(path);
- assertThat(processor.getPath(pathFactory, fqn), is(path));
- }
-}