Author: rhauch
Date: 2009-06-19 18:43:42 -0400 (Fri, 19 Jun 2009)
New Revision: 1055
Modified:
trunk/dna-jcr/src/main/java/org/jboss/dna/jcr/JcrWorkspace.java
trunk/dna-jcr/src/main/java/org/jboss/dna/jcr/SessionCache.java
trunk/dna-jcr/src/test/java/org/jboss/dna/jcr/SessionCacheTest.java
Log:
DNA-466 JCR requires connectors to expose UUID as identifier property
Changed the JCR implementation to use the path and UUID when both are known.
Modified: trunk/dna-jcr/src/main/java/org/jboss/dna/jcr/JcrWorkspace.java
===================================================================
--- trunk/dna-jcr/src/main/java/org/jboss/dna/jcr/JcrWorkspace.java 2009-06-19 22:43:29
UTC (rev 1054)
+++ trunk/dna-jcr/src/main/java/org/jboss/dna/jcr/JcrWorkspace.java 2009-06-19 22:43:42
UTC (rev 1055)
@@ -280,13 +280,13 @@
*/
public void copy( String srcWorkspace,
String srcAbsPath,
- String destAbsPath )
- throws ConstraintViolationException, VersionException, AccessDeniedException,
PathNotFoundException, ItemExistsException,
- LockException, RepositoryException {
+ String destAbsPath )
+ throws ConstraintViolationException, VersionException, AccessDeniedException,
PathNotFoundException, ItemExistsException,
+ LockException, RepositoryException {
CheckArg.isNotNull(srcWorkspace, "source workspace name");
CheckArg.isNotNull(srcAbsPath, "source path");
CheckArg.isNotNull(destAbsPath, "destination path");
-
+
if (!graph.getWorkspaces().contains(srcWorkspace)) {
throw new
NoSuchWorkspaceException(JcrI18n.workspaceNameIsInvalid.text(graph.getSourceName(),
this.name));
}
@@ -313,8 +313,7 @@
try {
this.session.checkPermission(destPath.getParent(), "add_node");
- }
- catch (AccessControlException ace) {
+ } catch (AccessControlException ace) {
throw new AccessDeniedException(ace);
}
@@ -325,7 +324,7 @@
NodeInfo cacheParent = cache.findNodeInfo(null, destPath.getParent());
// Skip the cache and load the latest parent info directly from the graph
- NodeInfo parent = cache.loadFromGraph(cacheParent.getUuid(), null);
+ NodeInfo parent = cache.loadFromGraph(destPath.getParent(),
cacheParent.getUuid());
Name newNodeName = destPath.getLastSegment().getName();
String parentPath =
destPath.getParent().getString(this.context.getNamespaceRegistry());
@@ -334,18 +333,24 @@
Property primaryTypeProp =
graph.getNodeAt(srcPath).getProperty(JcrLexicon.PRIMARY_TYPE);
Property uuidProp = graph.getNodeAt(srcPath).getProperty(DnaLexicon.UUID);
graph.useWorkspace(this.name);
-
+
assert primaryTypeProp != null : "Cannot have a node in a JCR repository
with no jcr:primaryType property";
assert uuidProp != null : "Cannot have a node in a JCR repository with no
UUID";
NameFactory nameFactory = this.context.getValueFactories().getNameFactory();
- this.session.cache().findBestNodeDefinition(parent, parentPath, newNodeName,
nameFactory.create(primaryTypeProp.getFirstValue()));
+ this.session.cache().findBestNodeDefinition(parent,
+ parentPath,
+ newNodeName,
+
nameFactory.create(primaryTypeProp.getFirstValue()));
// Perform the copy operation, but use the "to" form (not the
"into", which takes the parent) ...
graph.copy(srcPath).fromWorkspace(srcWorkspace).to(destPath);
-
+
// Load the node that we just copied
- cache.compensateForWorkspaceChildChange(cacheParent.getUuid(), null,
UUID.fromString(uuidProp.getFirstValue().toString()), newNodeName);
+ cache.compensateForWorkspaceChildChange(cacheParent.getUuid(),
+ null,
+
UUID.fromString(uuidProp.getFirstValue().toString()),
+ newNodeName);
}
/**
@@ -432,8 +437,7 @@
try {
this.session.checkPermission(srcAbsPath.substring(0,
srcAbsPath.lastIndexOf('/')), "remove");
this.session.checkPermission(destAbsPath, "add_node");
- }
- catch (AccessControlException ace) {
+ } catch (AccessControlException ace) {
throw new AccessDeniedException(ace);
}
@@ -446,7 +450,7 @@
NodeInfo oldParent = cache.findNodeInfo(null, srcPath.getParent());
// Skip the cache and load the latest parent info directly from the graph
- NodeInfo parent = cache.loadFromGraph(cacheParent.getUuid(), null);
+ NodeInfo parent = cache.loadFromGraph(destPath.getParent(),
cacheParent.getUuid());
Name newNodeName = destPath.getLastSegment().getName();
String parentPath =
destPath.getParent().getString(this.context.getNamespaceRegistry());
Modified: trunk/dna-jcr/src/main/java/org/jboss/dna/jcr/SessionCache.java
===================================================================
--- trunk/dna-jcr/src/main/java/org/jboss/dna/jcr/SessionCache.java 2009-06-19 22:43:29
UTC (rev 1054)
+++ trunk/dna-jcr/src/main/java/org/jboss/dna/jcr/SessionCache.java 2009-06-19 22:43:42
UTC (rev 1055)
@@ -156,6 +156,7 @@
protected final HashMap<UUID, ImmutableNodeInfo> cachedNodes;
protected final HashMap<UUID, ChangedNodeInfo> changedNodes;
protected final HashMap<UUID, NodeInfo> deletedNodes;
+ protected final Map<UUID, Path> pathCache;
private LinkedList<Request> requests;
private BatchRequestBuilder requestBuilder;
@@ -191,6 +192,7 @@
this.cachedNodes = new HashMap<UUID, ImmutableNodeInfo>();
this.changedNodes = new HashMap<UUID, ChangedNodeInfo>();
this.deletedNodes = new HashMap<UUID, NodeInfo>();
+ this.pathCache = new HashMap<UUID, Path>();
// Create the batch operations ...
this.requests = new LinkedList<Request>();
@@ -1002,7 +1004,7 @@
// Or in the cache ...
NodeInfo cached = cachedNodes.get(uuid);
if (cached == null) {
- cached = loadFromGraph(uuid, null);
+ cached = loadFromGraph(null, uuid);
}
// Now put into the changed nodes ...
info = new ChangedNodeInfo(cached);
@@ -1400,6 +1402,9 @@
public void orderChildBefore( Path.Segment childToBeMoved,
Path.Segment before ) {
+ // Clear the path cache ...
+ SessionCache.this.pathCache.clear();
+
PathFactory pathFactory = SessionCache.this.pathFactory;
Path thisPath = this.currentLocation.getPath();
UUID fromUuid = this.node.getChildren().getChild(childToBeMoved).getUuid();
@@ -1477,6 +1482,9 @@
}
}
+ // Clear the path cache ...
+ SessionCache.this.pathCache.clear();
+
// Remove the node from the current parent and add it to this ...
ChangedNodeInfo newChildInfo = newChildEditor.node;
UUID existingParent = newChildInfo.getParent();
@@ -1874,7 +1882,7 @@
NodeInfo info = findNodeInfoInCache(uuid);
if (info == null) {
// Nope, so go ahead and load it ...
- info = loadFromGraph(uuid, null);
+ info = loadFromGraph(null, uuid);
}
SessionCache.this.checkPermission(info, JcrSession.JCR_READ_PERMISSION);
@@ -1919,7 +1927,7 @@
NodeInfo findNodeInfoForRoot() throws RepositoryException {
if (root == null) {
// We haven't found the root yet ...
- NodeInfo info = loadFromGraph(this.rootPath, null);
+ NodeInfo info = loadFromGraph(this.rootPath, (NodeInfo)null);
root = info.getUuid();
this.jcrNodes.put(root, new JcrRootNode(this, root));
return info;
@@ -2082,23 +2090,36 @@
}
Path getPathFor( UUID uuid ) throws ItemNotFoundException, InvalidItemStateException,
RepositoryException {
- if (uuid == root) return rootPath;
+ if (uuid.equals(root)) return rootPath;
return getPathFor(findNodeInfo(uuid));
}
Path getPathFor( NodeInfo info ) throws ItemNotFoundException,
InvalidItemStateException, RepositoryException {
- if (info != null && info.getUuid() == root) return rootPath;
- LinkedList<Path.Segment> segments = new LinkedList<Path.Segment>();
- while (info != null) {
+ if (info == null) {
+ return pathFactory.createRootPath();
+ }
+ UUID uuid = info.getUuid();
+ if (uuid.equals(root)) return rootPath;
+
+ // This isn't the root node ...
+ Path result = pathCache.get(uuid);
+ if (result == null) {
+ // We need to build a path using the parent path ...
UUID parent = info.getParent();
- if (parent == null) break;
- NodeInfo parentInfo = findNodeInfo(parent);
- ChildNode child = parentInfo.getChildren().getChild(info.getUuid());
- if (child == null) break;
- segments.addFirst(child.getSegment());
- info = parentInfo;
+ if (parent == null) {
+ // Then this node is the root ...
+ root = info.getUuid();
+ result = rootPath;
+ } else {
+ NodeInfo parentInfo = findNodeInfo(parent);
+ Path parentPath = getPathFor(parentInfo);
+ ChildNode child = parentInfo.getChildren().getChild(info.getUuid());
+ result = pathFactory.create(parentPath, child.getSegment());
+ }
+ pathCache.put(uuid, result);
}
- return pathFactory.createAbsolutePath(segments);
+ assert result != null;
+ return result;
}
Path getPathFor( PropertyInfo propertyInfo ) throws ItemNotFoundException,
RepositoryException {
@@ -2138,18 +2159,20 @@
* Note that this method does not check the cache before loading from the repository
graph.
* </p>
*
- * @param uuid the UUID of the node; may not be null
- * @param parentInfo the parent information; may be null if not known
+ * @param path the path of the node, if known; may be null only if the UUID is
supplied
+ * @param uuid the UUID of the node, if known; may be null only if the path is
supplied
* @return the information for the node
* @throws ItemNotFoundException if the node does not exist in the repository
* @throws RepositoryException if there was an error obtaining this information from
the repository
*/
- protected ImmutableNodeInfo loadFromGraph( UUID uuid,
- NodeInfo parentInfo ) throws
ItemNotFoundException, RepositoryException {
+ protected ImmutableNodeInfo loadFromGraph( Path path,
+ UUID uuid ) throws ItemNotFoundException,
RepositoryException {
// Load the node information from the store ...
try {
- org.jboss.dna.graph.Node node = store.getNodeAt(uuid);
- ImmutableNodeInfo info = createNodeInfoFrom(node, parentInfo);
+ // See if there is a path for this uuid ...
+ Location location = Location.create(path, uuid);
+ org.jboss.dna.graph.Node node = store.getNodeAt(location);
+ ImmutableNodeInfo info = createNodeInfoFrom(node, null);
this.cachedNodes.put(info.getUuid(), info);
return info;
} catch (org.jboss.dna.graph.property.PathNotFoundException e) {
@@ -2540,6 +2563,9 @@
// Whether or not we found an info, add it to the deleted map ...
this.deletedNodes.put(toDelete, info);
+ // Remove it from the path cache ...
+ this.pathCache.remove(toDelete);
+
if (info != null) {
// Get all the children and add them to the queue ...
for (ChildNode child : info.getChildren()) {
Modified: trunk/dna-jcr/src/test/java/org/jboss/dna/jcr/SessionCacheTest.java
===================================================================
--- trunk/dna-jcr/src/test/java/org/jboss/dna/jcr/SessionCacheTest.java 2009-06-19
22:43:29 UTC (rev 1054)
+++ trunk/dna-jcr/src/test/java/org/jboss/dna/jcr/SessionCacheTest.java 2009-06-19
22:43:42 UTC (rev 1055)
@@ -373,7 +373,7 @@
sw.stop();
assertThat(nodeInfo, is(sameInstance(cache.findNodeInfo(rootUuid))));
}
- System.out.println(pad(sourceName) + " ==> " +
sw.getSimpleStatistics());
+ // System.out.println(pad(sourceName) + " ==> " +
sw.getSimpleStatistics());
}
@Test
@@ -391,7 +391,7 @@
sw.stop();
assertThat(rootInfo, is(notNullValue()));
}
- System.out.println(pad(sourceName) + " ==> " +
sw.getSimpleStatistics());
+ // System.out.println(pad(sourceName) + " ==> " +
sw.getSimpleStatistics());
}
@Test
@@ -409,7 +409,7 @@
sw.stop();
assertThat(rootInfo, is(notNullValue()));
}
- System.out.println(pad(sourceName) + " ==> " +
sw.getSimpleStatistics());
+ // System.out.println(pad(sourceName) + " ==> " +
sw.getSimpleStatistics());
}
@Test
@@ -437,7 +437,7 @@
sw.stop();
assertThat(lr3.getUuid(), is(lr3Node.getLocation().getUuid()));
assertSameProperties(lr3, lr3Node);
- System.out.println(pad(sourceName) + " ==> " +
sw.getSimpleStatistics());
+ // System.out.println(pad(sourceName) + " ==> " +
sw.getSimpleStatistics());
// Verify that this loaded all the intermediate nodes, by walking up ...
NodeInfo info = lr3;
@@ -761,16 +761,18 @@
@Test
public void shouldFindInfoForAllNodesInGraph() throws Exception {
- Stopwatch sw = new Stopwatch();
+ for (int i = 0; i != 3; ++i) {
+ Stopwatch sw = new Stopwatch();
- // Get the root ...
- sw.start();
- NodeInfo root = cache.findNodeInfoForRoot();
- cache.getPathFor(root);
- sw.stop();
+ // Get the root ...
+ sw.start();
+ NodeInfo root = cache.findNodeInfoForRoot();
+ cache.getPathFor(root);
+ sw.stop();
- // Walk the infos for nodes under the root (this is recursive) ...
- walkInfosForNodesUnder(root, sw);
- System.out.println("Statistics for walking nodes using SessionCache: "
+ sw.getSimpleStatistics());
+ // Walk the infos for nodes under the root (this is recursive) ...
+ walkInfosForNodesUnder(root, sw);
+ System.out.println("Statistics for walking nodes using SessionCache:
" + sw.getSimpleStatistics());
+ }
}
}