[dna-commits] DNA SVN: r1087 - in trunk: dna-jcr/src/main/java/org/jboss/dna/jcr and 1 other directories.

dna-commits at lists.jboss.org dna-commits at lists.jboss.org
Thu Jul 9 17:56:42 EDT 2009


Author: rhauch
Date: 2009-07-09 17:56:41 -0400 (Thu, 09 Jul 2009)
New Revision: 1087

Modified:
   trunk/dna-graph/src/main/java/org/jboss/dna/graph/session/GraphSession.java
   trunk/dna-jcr/src/main/java/org/jboss/dna/jcr/JcrContentHandler.java
   trunk/dna-jcr/src/main/java/org/jboss/dna/jcr/JcrSession.java
   trunk/dna-jcr/src/main/java/org/jboss/dna/jcr/SessionCache.java
   trunk/dna-jcr/src/test/java/org/jboss/dna/jcr/ImportExportTest.java
Log:
DNA-479 Workspace import does not work

Changed the JcrContentHandler implementation to use its own SessionCache object if it is a workspace import, or to use the JcrSession's existing cache if it is a session import. Several test cases were uncommented, though the import/export related TCK unit tests do not all pass and remain commented out.  A bug was found in the way that SessionCache was creating child nodes: the property payloads were not getting populated for the few mandatory properties that exist upon creation.  This bug was fixed, and it also cleans up a bit of the JCR-specific logic.

Modified: trunk/dna-graph/src/main/java/org/jboss/dna/graph/session/GraphSession.java
===================================================================
--- trunk/dna-graph/src/main/java/org/jboss/dna/graph/session/GraphSession.java	2009-07-09 20:43:56 UTC (rev 1086)
+++ trunk/dna-graph/src/main/java/org/jboss/dna/graph/session/GraphSession.java	2009-07-09 21:56:41 UTC (rev 1087)
@@ -2290,6 +2290,7 @@
             // Set the properties on the new node, but in a private backdoor way ...
             assert child.properties == null;
             child.properties = newProperties;
+            child.childrenByName = cache.NO_CHILDREN;
 
             try {
                 // The node has been changed, so try notifying before we record the creation (which can't be undone) ...
@@ -2745,7 +2746,6 @@
         COPIED;
     }
 
-    @Immutable
     public static final class PropertyInfo<PropertyPayload> {
         private final Property property;
         private final Status status;

Modified: trunk/dna-jcr/src/main/java/org/jboss/dna/jcr/JcrContentHandler.java
===================================================================
--- trunk/dna-jcr/src/main/java/org/jboss/dna/jcr/JcrContentHandler.java	2009-07-09 20:43:56 UTC (rev 1086)
+++ trunk/dna-jcr/src/main/java/org/jboss/dna/jcr/JcrContentHandler.java	2009-07-09 21:56:41 UTC (rev 1087)
@@ -24,22 +24,29 @@
 package org.jboss.dna.jcr;
 
 import java.io.ByteArrayInputStream;
+import java.io.InputStream;
 import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
 import java.util.Stack;
+import java.util.UUID;
 import javax.jcr.ImportUUIDBehavior;
+import javax.jcr.ItemExistsException;
+import javax.jcr.ItemNotFoundException;
 import javax.jcr.PathNotFoundException;
 import javax.jcr.PropertyType;
 import javax.jcr.RepositoryException;
 import javax.jcr.Value;
+import javax.jcr.ValueFactory;
 import javax.jcr.ValueFormatException;
+import javax.jcr.nodetype.ConstraintViolationException;
 import net.jcip.annotations.NotThreadSafe;
 import org.jboss.dna.common.text.TextDecoder;
 import org.jboss.dna.common.text.XmlNameEncoder;
 import org.jboss.dna.common.util.Base64;
-import org.jboss.dna.graph.Graph;
+import org.jboss.dna.graph.ExecutionContext;
+import org.jboss.dna.graph.Location;
 import org.jboss.dna.graph.property.Name;
 import org.jboss.dna.graph.property.NameFactory;
 import org.jboss.dna.graph.property.NamespaceRegistry;
@@ -72,8 +79,10 @@
     protected static final TextDecoder DOCUMENT_VIEW_NAME_DECODER = new JcrDocumentViewExporter.JcrDocumentViewPropertyEncoder();
 
     private final NameFactory nameFactory;
-
-    protected final JcrSession session;
+    private final NamespaceRegistry namespaces;
+    private final ValueFactory jcrValueFactory;
+    private final JcrNodeTypeManager nodeTypes;
+    private final javax.jcr.NamespaceRegistry jcrNamespaceRegistry;
     protected final int uuidBehavior;
 
     protected final String primaryTypeName;
@@ -83,7 +92,7 @@
     private AbstractJcrNode currentNode;
     private ContentHandler delegate;
 
-    private Graph.Batch pendingOperations;
+    private SessionCache cache;
 
     enum SaveMode {
         WORKSPACE,
@@ -101,36 +110,58 @@
                || uuidBehavior == ImportUUIDBehavior.IMPORT_UUID_COLLISION_REPLACE_EXISTING
                || uuidBehavior == ImportUUIDBehavior.IMPORT_UUID_COLLISION_THROW;
 
-        this.session = session;
-        this.nameFactory = session.getExecutionContext().getValueFactories().getNameFactory();
-        this.currentNode = session.getNode(parentPath);
+        ExecutionContext context = session.getExecutionContext();
+        this.namespaces = context.getNamespaceRegistry();
+        this.nameFactory = context.getValueFactories().getNameFactory();
         this.uuidBehavior = uuidBehavior;
 
-        if (saveMode == SaveMode.WORKSPACE) {
-            this.pendingOperations = session.createBatch();
+        switch (saveMode) {
+            case SESSION:
+                cache = session.cache();
+                break;
+            case WORKSPACE:
+                cache = new SessionCache(session);
+                break;
         }
+        assert cache != null;
 
-        this.primaryTypeName = JcrLexicon.PRIMARY_TYPE.getString(this.session.namespaces());
-        this.mixinTypesName = JcrLexicon.MIXIN_TYPES.getString(this.session.namespaces());
-        this.uuidName = JcrLexicon.UUID.getString(this.session.namespaces());
+        this.currentNode = cache.findJcrNode(null, parentPath);
+        this.jcrValueFactory = session.getValueFactory();
+        this.nodeTypes = session.nodeTypeManager();
+        this.jcrNamespaceRegistry = session.workspace().getNamespaceRegistry();
+
+        this.primaryTypeName = JcrLexicon.PRIMARY_TYPE.getString(this.namespaces);
+        this.mixinTypesName = JcrLexicon.MIXIN_TYPES.getString(this.namespaces);
+        this.uuidName = JcrLexicon.UUID.getString(this.namespaces);
     }
 
+    protected final NamespaceRegistry namespaces() {
+        return namespaces;
+    }
+
+    protected final JcrNodeTypeManager nodeTypes() {
+        return nodeTypes;
+    }
+
+    protected final JcrNodeType nodeTypeFor( String name ) {
+        return nodeTypes.getNodeType(nameFor(name));
+    }
+
     protected final Name nameFor( String name ) {
         return nameFactory.create(name);
     }
 
     protected final Value valueFor( String value,
                                     int type ) throws ValueFormatException {
-        return session.getValueFactory().createValue(value, type);
-        // return new JcrValue(session.getExecutionContext().getValueFactories(), cache(), type, value);
+        return jcrValueFactory.createValue(value, type);
     }
 
-    protected final SessionCache cache() {
-        return session.cache();
+    protected final Value valueFor( InputStream stream ) {
+        return jcrValueFactory.createValue(stream);
     }
 
-    protected final Graph.Batch operations() {
-        return pendingOperations;
+    protected final SessionCache cache() {
+        return cache;
     }
 
     /**
@@ -153,10 +184,11 @@
      */
     @Override
     public void endDocument() throws SAXException {
-        if (pendingOperations != null) {
-            pendingOperations.execute();
+        try {
+            cache.save();
+        } catch (RepositoryException e) {
+            throw new EnclosingSAXException(e);
         }
-
         super.endDocument();
     }
 
@@ -209,21 +241,17 @@
                                     String uri ) throws SAXException {
         try {
             // Read from the workspace's DNA registry, as its semantics are more friendly
-            NamespaceRegistry registry = session.workspace().context().getNamespaceRegistry();
+            String existingUri = namespaces.getNamespaceForPrefix(prefix);
 
-            String existingUri = registry.getNamespaceForPrefix(prefix);
-
             if (existingUri != null) {
                 if (existingUri.equals(uri)) {
                     // prefix/uri mapping is already in registry
                     return;
                 }
-
                 throw new RepositoryException("Prefix " + prefix + " is already permanently mapped");
             }
-
             // Register through the JCR workspace to ensure consistency
-            session.getWorkspace().getNamespaceRegistry().registerNamespace(prefix, uri);
+            this.jcrNamespaceRegistry.registerNamespace(prefix, uri);
         } catch (RepositoryException re) {
             throw new EnclosingSAXException(re);
         }
@@ -269,8 +297,8 @@
             this.currentProps = new HashMap<String, List<Value>>();
             this.valueBuffer = new StringBuffer();
 
-            this.svNameName = JcrSvLexicon.NAME.getString(session.namespaces());
-            this.svTypeName = JcrSvLexicon.TYPE.getString(session.namespaces());
+            this.svNameName = JcrSvLexicon.NAME.getString(namespaces());
+            this.svTypeName = JcrSvLexicon.TYPE.getString(namespaces());
         }
 
         /**
@@ -300,58 +328,55 @@
         }
 
         private void addNodeIfPending() throws SAXException {
-            // if (currentNodeName != null) {
-            // try {
-            // AbstractJcrNode parentNode = parentStack.peek();
-            //
-            // UUID uuid = null;
-            // List<Value> rawUuid = currentProps.get(uuidName);
-            //
-            // if (rawUuid != null) {
-            // assert rawUuid.size() == 1;
-            // uuid = UUID.fromString(rawUuid.get(0).getString());
-            // }
-            //
-            // String typeName = currentProps.get(primaryTypeName).get(0).getString();
-            // AbstractJcrNode newNode =
-            // cache().findJcrNode(parentNode.editorFor(operations()).createChild(nameFor(currentNodeName),
-            // uuid,
-            // nameFor(typeName)).getUuid());
-            //
-            // for (Map.Entry<String, List<Value>> entry : currentProps.entrySet()) {
-            // if (entry.getKey().equals(primaryTypeName)) {
-            // continue;
-            // }
-            //
-            // if (entry.getKey().equals(mixinTypesName)) {
-            // for (Value value : entry.getValue()) {
-            // JcrNodeType mixinType = session.workspace().nodeTypeManager().getNodeType(nameFor(value.getString()));
-            // newNode.editorFor(operations()).addMixin(mixinType);
-            // }
-            // continue;
-            // }
-            //
-            // if (entry.getKey().equals(uuidName)) {
-            // continue;
-            // }
-            //
-            // List<Value> values = entry.getValue();
-            //
-            // if (values.size() == 1) {
-            // newNode.editorFor(operations()).setProperty(nameFor(entry.getKey()), (JcrValue)values.get(0));
-            // } else {
-            // newNode.editorFor(operations()).setProperty(nameFor(entry.getKey()),
-            // values.toArray(new Value[values.size()]),
-            // PropertyType.UNDEFINED);
-            // }
-            // }
-            //
-            // parentStack.push(newNode);
-            // currentProps.clear();
-            // } catch (RepositoryException re) {
-            // throw new EnclosingSAXException(re);
-            // }
-            // }
+            if (currentNodeName != null) {
+                try {
+                    AbstractJcrNode parentNode = parentStack.peek();
+
+                    UUID uuid = null;
+                    List<Value> rawUuid = currentProps.get(uuidName);
+
+                    if (rawUuid != null) {
+                        assert rawUuid.size() == 1;
+                        uuid = UUID.fromString(rawUuid.get(0).getString());
+                    }
+
+                    String typeName = currentProps.get(primaryTypeName).get(0).getString();
+                    AbstractJcrNode newNode = parentNode.editor().createChild(nameFor(currentNodeName), uuid, nameFor(typeName));
+
+                    for (Map.Entry<String, List<Value>> entry : currentProps.entrySet()) {
+                        if (entry.getKey().equals(primaryTypeName)) {
+                            continue;
+                        }
+
+                        if (entry.getKey().equals(mixinTypesName)) {
+                            for (Value value : entry.getValue()) {
+                                JcrNodeType mixinType = nodeTypeFor(value.getString());
+                                newNode.editor().addMixin(mixinType);
+                            }
+                            continue;
+                        }
+
+                        if (entry.getKey().equals(uuidName)) {
+                            continue;
+                        }
+
+                        List<Value> values = entry.getValue();
+
+                        if (values.size() == 1) {
+                            newNode.editor().setProperty(nameFor(entry.getKey()), (JcrValue)values.get(0));
+                        } else {
+                            newNode.editor().setProperty(nameFor(entry.getKey()),
+                                                         values.toArray(new Value[values.size()]),
+                                                         PropertyType.UNDEFINED);
+                        }
+                    }
+
+                    parentStack.push(newNode);
+                    currentProps.clear();
+                } catch (RepositoryException re) {
+                    throw new EnclosingSAXException(re);
+                }
+            }
         }
 
         @Override
@@ -367,11 +392,9 @@
                 try {
                     if (currentPropType == PropertyType.BINARY) {
                         ByteArrayInputStream is = new ByteArrayInputStream(Base64.decode(s, Base64.URL_SAFE));
-                        currentProps.get(currentPropName).add(session.getValueFactory().createValue(is));
+                        currentProps.get(currentPropName).add(valueFor(is));
                     } else {
-                        currentProps.get(currentPropName).add(session.getValueFactory()
-                                                                     .createValue(SYSTEM_VIEW_NAME_DECODER.decode(s),
-                                                                                  currentPropType));
+                        currentProps.get(currentPropName).add(valueFor(SYSTEM_VIEW_NAME_DECODER.decode(s), currentPropType));
                     }
                 } catch (RepositoryException re) {
                     throw new EnclosingSAXException(re);
@@ -417,70 +440,66 @@
                                   String localName,
                                   String name,
                                   Attributes atts ) throws SAXException {
-            // try {
-            // String primaryTypeName = atts.getValue(JcrContentHandler.this.primaryTypeName);
-            // String rawUuid = atts.getValue(uuidName);
-            // UUID uuid = (rawUuid != null ? UUID.fromString(rawUuid) : null);
-            // AbstractJcrNode parentNode = parentStack.peek();
-            //
-            // if (uuid != null) {
-            // AbstractJcrNode existingNodeWithUuid = (AbstractJcrNode)session.getNodeByUUID(rawUuid);
-            // if (existingNodeWithUuid != null) {
-            // switch (uuidBehavior) {
-            // case ImportUUIDBehavior.IMPORT_UUID_COLLISION_REPLACE_EXISTING:
-            // parentNode = existingNodeWithUuid.getParent();
-            // parentNode.editorFor(operations()).destroyChild(uuid);
-            // break;
-            // case ImportUUIDBehavior.IMPORT_UUID_CREATE_NEW:
-            // uuid = UUID.randomUUID();
-            // break;
-            // case ImportUUIDBehavior.IMPORT_UUID_COLLISION_REMOVE_EXISTING:
-            // if (existingNodeWithUuid.path().isAtOrAbove(parentStack.firstElement().path())) {
-            // throw new ConstraintViolationException();
-            // }
-            // AbstractJcrNode temp = existingNodeWithUuid.getParent();
-            // temp.editorFor(operations()).destroyChild(uuid);
-            // break;
-            // case ImportUUIDBehavior.IMPORT_UUID_COLLISION_THROW:
-            // throw new ItemExistsException();
-            // }
-            // }
-            // }
-            //
-            // name = DOCUMENT_VIEW_NAME_DECODER.decode(name);
-            // AbstractJcrNode currentNode = cache().findJcrNode(parentNode.editorFor(operations()).createChild(nameFor(name),
-            // uuid,
-            // nameFor(primaryTypeName)).getUuid());
-            //
-            // for (int i = 0; i < atts.getLength(); i++) {
-            // if (JcrContentHandler.this.primaryTypeName.equals(atts.getQName(i))) {
-            // continue;
-            // }
-            //
-            // if (mixinTypesName.equals(atts.getQName(i))) {
-            // JcrNodeType mixinType = session.workspace().nodeTypeManager().getNodeType(nameFor(atts.getValue(i)));
-            // currentNode.editorFor(operations()).addMixin(mixinType);
-            // continue;
-            // }
-            //
-            // if (uuidName.equals(atts.getQName(i))) {
-            // continue;
-            // }
-            //
-            // // We may want to use the workspace context here so that we only use the permanent namespace mappings
-            // // Name propName = session.executionContext.getValueFactories().getNameFactory().create(atts.getQName(i));
-            // // String value = DOCUMENT_VIEW_NAME_DECODER.decode(atts.getValue(i));
-            // String value = atts.getValue(i);
-            // String propertyName = DOCUMENT_VIEW_NAME_DECODER.decode(atts.getQName(i));
-            // currentNode.editorFor(operations()).setProperty(nameFor(propertyName),
-            // (JcrValue)valueFor(value, PropertyType.STRING));
-            // }
-            //
-            // parentStack.push(currentNode);
-            // } catch (RepositoryException re) {
-            // throw new EnclosingSAXException(re);
-            // }
+            try {
+                String primaryTypeName = atts.getValue(JcrContentHandler.this.primaryTypeName);
+                String rawUuid = atts.getValue(uuidName);
+                UUID uuid = (rawUuid != null ? UUID.fromString(rawUuid) : null);
+                AbstractJcrNode parentNode = parentStack.peek();
 
+                if (uuid != null) {
+                    try {
+                        AbstractJcrNode existingNodeWithUuid = cache().findJcrNode(Location.create(uuid));
+                        switch (uuidBehavior) {
+                            case ImportUUIDBehavior.IMPORT_UUID_COLLISION_REPLACE_EXISTING:
+                                existingNodeWithUuid.editor().destroy();
+                                break;
+                            case ImportUUIDBehavior.IMPORT_UUID_CREATE_NEW:
+                                uuid = UUID.randomUUID();
+                                break;
+                            case ImportUUIDBehavior.IMPORT_UUID_COLLISION_REMOVE_EXISTING:
+                                if (existingNodeWithUuid.path().isAtOrAbove(parentStack.firstElement().path())) {
+                                    throw new ConstraintViolationException();
+                                }
+                                existingNodeWithUuid.editor().destroy();
+                                break;
+                            case ImportUUIDBehavior.IMPORT_UUID_COLLISION_THROW:
+                                throw new ItemExistsException();
+                        }
+                    } catch (ItemNotFoundException e) {
+                        // don't care
+                    }
+                }
+
+                name = DOCUMENT_VIEW_NAME_DECODER.decode(name);
+                AbstractJcrNode currentNode = parentNode.editor().createChild(nameFor(name), uuid, nameFor(primaryTypeName));
+
+                for (int i = 0; i < atts.getLength(); i++) {
+                    if (JcrContentHandler.this.primaryTypeName.equals(atts.getQName(i))) {
+                        continue;
+                    }
+
+                    if (mixinTypesName.equals(atts.getQName(i))) {
+                        JcrNodeType mixinType = nodeTypeFor(atts.getValue(i));
+                        currentNode.editor().addMixin(mixinType);
+                        continue;
+                    }
+
+                    if (uuidName.equals(atts.getQName(i))) {
+                        continue;
+                    }
+
+                    // We may want to use the workspace context here so that we only use the permanent namespace mappings
+                    // Name propName = session.executionContext.getValueFactories().getNameFactory().create(atts.getQName(i));
+                    // String value = DOCUMENT_VIEW_NAME_DECODER.decode(atts.getValue(i));
+                    String value = atts.getValue(i);
+                    String propertyName = DOCUMENT_VIEW_NAME_DECODER.decode(atts.getQName(i));
+                    currentNode.editor().setProperty(nameFor(propertyName), (JcrValue)valueFor(value, PropertyType.STRING));
+                }
+
+                parentStack.push(currentNode);
+            } catch (RepositoryException re) {
+                throw new EnclosingSAXException(re);
+            }
         }
 
         @Override
@@ -499,20 +518,16 @@
         public void characters( char[] ch,
                                 int start,
                                 int length ) throws SAXException {
-            // try {
-            // AbstractJcrNode parentNode = parentStack.peek();
-            // AbstractJcrNode currentNode =
-            // cache().findJcrNode(parentNode.editorFor(operations()).createChild(JcrLexicon.XMLTEXT,
-            // null,
-            // JcrNtLexicon.UNSTRUCTURED).getUuid());
-            //
-            // String s = new String(ch, start, length);
-            // currentNode.editorFor(operations()).setProperty(JcrLexicon.XMLCHARACTERS,
-            // (JcrValue)valueFor(s, PropertyType.STRING));
-            //
-            // } catch (RepositoryException re) {
-            // throw new EnclosingSAXException(re);
-            // }
+            try {
+                AbstractJcrNode parentNode = parentStack.peek();
+                AbstractJcrNode currentNode = parentNode.editor()
+                                                        .createChild(JcrLexicon.XMLTEXT, null, JcrNtLexicon.UNSTRUCTURED);
+                String s = new String(ch, start, length);
+                currentNode.editor().setProperty(JcrLexicon.XMLCHARACTERS, (JcrValue)valueFor(s, PropertyType.STRING));
+
+            } catch (RepositoryException re) {
+                throw new EnclosingSAXException(re);
+            }
         }
     }
 }

Modified: trunk/dna-jcr/src/main/java/org/jboss/dna/jcr/JcrSession.java
===================================================================
--- trunk/dna-jcr/src/main/java/org/jboss/dna/jcr/JcrSession.java	2009-07-09 20:43:56 UTC (rev 1086)
+++ trunk/dna-jcr/src/main/java/org/jboss/dna/jcr/JcrSession.java	2009-07-09 21:56:41 UTC (rev 1087)
@@ -158,8 +158,7 @@
                                   this.executionContext);
         this.graph.useWorkspace(workspace.getName());
 
-        this.cache = new SessionCache(this, workspace.getName(), this.executionContext, this.workspace.nodeTypeManager(),
-                                      this.graph);
+        this.cache = new SessionCache(this);
         this.isLive = true;
 
         assert this.sessionAttributes != null;
@@ -200,6 +199,10 @@
         return graph.batch();
     }
 
+    Graph graph() {
+        return graph;
+    }
+
     String sourceName() {
         return this.repository.getRepositorySourceName();
     }

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-07-09 20:43:56 UTC (rev 1086)
+++ trunk/dna-jcr/src/main/java/org/jboss/dna/jcr/SessionCache.java	2009-07-09 21:56:41 UTC (rev 1087)
@@ -141,6 +141,10 @@
 
     private GraphSession<JcrNodePayload, JcrPropertyPayload> graphSession;
 
+    public SessionCache( JcrSession session ) {
+        this(session, session.workspace().getName(), session.getExecutionContext(), session.nodeTypeManager(), session.graph());
+    }
+
     public SessionCache( JcrSession session,
                          String workspaceName,
                          ExecutionContext context,
@@ -202,6 +206,10 @@
         return nameFactory;
     }
 
+    ValueFactory<String> stringFactory() {
+        return factories.getStringFactory();
+    }
+
     JcrNodeTypeManager nodeTypes() {
         return session.nodeTypeManager();
     }
@@ -1375,7 +1383,6 @@
                 // Create the initial properties ...
                 Property primaryTypeProp = propertyFactory.create(JcrLexicon.PRIMARY_TYPE, primaryTypeName);
                 Property nodeDefinitionProp = propertyFactory.create(DnaIntLexicon.NODE_DEFINITON, definition.getId().getString());
-                List<Name> mixinTypeNames = null;
 
                 // Now add the "jcr:uuid" property if and only if referenceable ...
                 Node<JcrNodePayload, JcrPropertyPayload> result = null;
@@ -1388,13 +1395,10 @@
                 } else {
                     result = node.createChild(name, primaryTypeProp, nodeDefinitionProp);
                 }
-                // Now create the payload ...
-                JcrNodePayload newPayload = new JcrNodePayload(SessionCache.this, result, primaryTypeName, mixinTypeNames,
-                                                               definition.getId());
-                result.setPayload(newPayload);
+                // The postCreateChild hook impl should populate the payloads
+
                 // Finally, return the jcr node ...
-                assert result.getPayload() == newPayload;
-                return (JcrNode)newPayload.getJcrNode();
+                return (JcrNode)result.getPayload().getJcrNode();
             } catch (ValidationException e) {
                 throw new ConstraintViolationException(e.getMessage(), e.getCause());
             } catch (RepositorySourceException e) {
@@ -1423,6 +1427,22 @@
             }
             return true;
         }
+
+        /**
+         * Convenience method that destroys this node.
+         * 
+         * @return true if this node was successfully removed
+         * @throws AccessDeniedException if the current session does not have the requisite privileges to perform this task
+         * @throws RepositoryException if any other error occurs
+         */
+        public boolean destroy() throws AccessDeniedException, RepositoryException {
+            try {
+                node.destroy();
+            } catch (AccessControlException e) {
+                throw new AccessDeniedException(e.getMessage(), e.getCause());
+            }
+            return true;
+        }
     }
 
     /**
@@ -1971,7 +1991,7 @@
                                                                          PropertyInfo<JcrPropertyPayload> existing ) {
         // Create (or reuse) the JCR Property object ...
         AbstractJcrProperty jcrProp = null;
-        if (existing != null) {
+        if (existing != null && existing.getPayload() != null) {
             jcrProp = existing.getPayload().getJcrProperty();
         } else {
             AbstractJcrNode jcrNode = nodePayload.getJcrNode();
@@ -1985,7 +2005,6 @@
         JcrPropertyPayload propPayload = new JcrPropertyPayload(definition.getId(), propertyType, jcrProp);
         Status status = existing != null ? Status.CHANGED : Status.NEW;
         return new GraphSession.PropertyInfo<JcrPropertyPayload>(dnaProp, definition.isMultiple(), status, propPayload);
-
     }
 
     @Immutable
@@ -2401,6 +2420,60 @@
             }
         }
 
+        /**
+         * {@inheritDoc}
+         * 
+         * @see org.jboss.dna.graph.session.GraphSession.NodeOperations#postCreateChild(org.jboss.dna.graph.session.GraphSession.Node,
+         *      org.jboss.dna.graph.session.GraphSession.Node, java.util.Map)
+         */
+        @Override
+        public void postCreateChild( Node<JcrNodePayload, JcrPropertyPayload> parent,
+                                     Node<JcrNodePayload, JcrPropertyPayload> child,
+                                     Map<Name, PropertyInfo<JcrPropertyPayload>> properties ) throws ValidationException {
+            super.postCreateChild(parent, child, properties);
+            // Populate the node and properties with the payloads ...
+
+            // Get the 2 properties that WILL be here ...
+            PropertyInfo<JcrPropertyPayload> primaryTypeInfo = properties.get(JcrLexicon.PRIMARY_TYPE);
+            PropertyInfo<JcrPropertyPayload> nodeDefnInfo = properties.get(DnaIntLexicon.NODE_DEFINITON);
+            Name primaryTypeName = nameFactory().create(primaryTypeInfo.getProperty().getFirstValue());
+            String nodeDefnIdStr = stringFactory().create(nodeDefnInfo.getProperty().getFirstValue());
+            NodeDefinitionId nodeDefnId = NodeDefinitionId.fromString(nodeDefnIdStr, nameFactory);
+
+            // Now create the payload ...
+            JcrNodePayload nodePayload = new JcrNodePayload(SessionCache.this, child, primaryTypeName, null, nodeDefnId);
+            child.setPayload(nodePayload);
+
+            // Now update the property infos for the two mandatory properties ...
+            JcrNodeType ntBase = nodeTypes().getNodeType(JcrNtLexicon.BASE);
+            assert ntBase != null;
+            primaryTypeInfo = createPropertyInfo(parent.getPayload(),
+                                                 primaryTypeInfo.getProperty(),
+                                                 ntBase.allPropertyDefinitions(JcrLexicon.PRIMARY_TYPE).iterator().next(),
+                                                 PropertyType.NAME,
+                                                 primaryTypeInfo);
+            properties.put(primaryTypeInfo.getName(), primaryTypeInfo);
+            nodeDefnInfo = createPropertyInfo(parent.getPayload(),
+                                              nodeDefnInfo.getProperty(),
+                                              ntBase.allPropertyDefinitions(DnaIntLexicon.NODE_DEFINITON).iterator().next(),
+                                              PropertyType.STRING,
+                                              nodeDefnInfo);
+            properties.put(nodeDefnInfo.getName(), nodeDefnInfo);
+
+            // The UUID property is optional ...
+            PropertyInfo<JcrPropertyPayload> uuidInfo = properties.get(JcrLexicon.UUID);
+            if (uuidInfo != null) {
+                JcrNodeType mixRef = nodeTypes().getNodeType(JcrMixLexicon.REFERENCEABLE);
+                assert mixRef != null;
+                uuidInfo = createPropertyInfo(parent.getPayload(),
+                                              uuidInfo.getProperty(),
+                                              mixRef.allPropertyDefinitions(JcrLexicon.UUID).iterator().next(),
+                                              PropertyType.STRING,
+                                              uuidInfo);
+                properties.put(uuidInfo.getName(), uuidInfo);
+            }
+        }
+
         protected final Set<Name> getSingleMultiPropertyNames( Property dnaProperty,
                                                                Location location ) {
             Set<Name> multiValuedPropertyNames = new HashSet<Name>();

Modified: trunk/dna-jcr/src/test/java/org/jboss/dna/jcr/ImportExportTest.java
===================================================================
--- trunk/dna-jcr/src/test/java/org/jboss/dna/jcr/ImportExportTest.java	2009-07-09 20:43:56 UTC (rev 1086)
+++ trunk/dna-jcr/src/test/java/org/jboss/dna/jcr/ImportExportTest.java	2009-07-09 21:56:41 UTC (rev 1087)
@@ -128,7 +128,6 @@
         session.importXML(targetPath, bais, ImportUUIDBehavior.IMPORT_UUID_CREATE_NEW);
     }
 
-    @Ignore( "dna-466" )
     @Test
     public void shouldImportExportEscapedXmlCharactersInSystemView() throws Exception {
         String testName = "importExportEscapedXmlCharacters";




More information about the dna-commits mailing list