Index: dna-jcr/src/main/java/org/jboss/dna/jcr/AbstractJcrItem.java =================================================================== --- dna-jcr/src/main/java/org/jboss/dna/jcr/AbstractJcrItem.java (revision 829) +++ dna-jcr/src/main/java/org/jboss/dna/jcr/AbstractJcrItem.java (working copy) @@ -82,26 +82,6 @@ /** * {@inheritDoc} * - * @return false - * @see javax.jcr.Item#isModified() - */ - public final boolean isModified() { - return false; - } - - /** - * {@inheritDoc} - * - * @return false - * @see javax.jcr.Item#isNew() - */ - public final boolean isNew() { - return false; - } - - /** - * {@inheritDoc} - * * @see javax.jcr.Item#isSame(javax.jcr.Item) */ public boolean isSame( Item otherItem ) throws RepositoryException { Index: dna-jcr/src/main/java/org/jboss/dna/jcr/AbstractJcrNode.java =================================================================== --- dna-jcr/src/main/java/org/jboss/dna/jcr/AbstractJcrNode.java (revision 829) +++ dna-jcr/src/main/java/org/jboss/dna/jcr/AbstractJcrNode.java (working copy) @@ -1423,6 +1448,34 @@ /** * {@inheritDoc} * + * @see javax.jcr.Item#isModified() + */ + public final boolean isModified() { + try { + return nodeInfo().isModified(); + } + catch (RepositoryException re) { + throw new IllegalStateException(re); + } + } + + /** + * {@inheritDoc} + * + * @see javax.jcr.Item#isNew() + */ + public final boolean isNew() { + try { + return nodeInfo().isNew(); + } + catch (RepositoryException re) { + throw new IllegalStateException(re); + } + } + + /** + * {@inheritDoc} + * * @throws UnsupportedOperationException always * @see javax.jcr.Node#merge(java.lang.String, boolean) */ Index: dna-jcr/src/main/java/org/jboss/dna/jcr/AbstractJcrProperty.java =================================================================== --- dna-jcr/src/main/java/org/jboss/dna/jcr/AbstractJcrProperty.java (revision 829) +++ dna-jcr/src/main/java/org/jboss/dna/jcr/AbstractJcrProperty.java (working copy) @@ -154,6 +154,34 @@ /** * {@inheritDoc} * + * @see javax.jcr.Item#isModified() + */ + public final boolean isModified() { + try { + return propertyInfo().isModified(); + } + catch (RepositoryException re) { + throw new IllegalStateException(re); + } + } + + /** + * {@inheritDoc} + * + * @see javax.jcr.Item#isNew() + */ + public final boolean isNew() { + try { + return propertyInfo().isNew(); + } + catch (RepositoryException re) { + throw new IllegalStateException(re); + } + } + + /** + * {@inheritDoc} + * * @return false * @see javax.jcr.Item#isNode() */ Index: dna-jcr/src/main/java/org/jboss/dna/jcr/cache/ChangedNodeInfo.java =================================================================== --- dna-jcr/src/main/java/org/jboss/dna/jcr/cache/ChangedNodeInfo.java (revision 829) +++ dna-jcr/src/main/java/org/jboss/dna/jcr/cache/ChangedNodeInfo.java (working copy) @@ -84,14 +84,19 @@ */ private NodeDefinitionId changedDefinitionId; + private boolean isNew; + /** * Create an immutable NodeInfo instance. * * @param original the original node information, may not be null + * @param isNew */ - public ChangedNodeInfo( NodeInfo original ) { + public ChangedNodeInfo( NodeInfo original, + boolean isNew ) { assert original != null; this.original = original; + this.isNew = isNew; } /** @@ -379,4 +384,23 @@ changedProperties.put(name, null); return changed; } + + /** + * + * {@inheritDoc} + * + * @see org.jboss.dna.jcr.cache.NodeInfo#isNew() + */ + public boolean isNew() { + return this.isNew; + } + + /** + * {@inheritDoc} + * + * @see org.jboss.dna.jcr.cache.NodeInfo#isModified() + */ + public boolean isModified() { + return !this.isNew; + } } Index: dna-jcr/src/main/java/org/jboss/dna/jcr/cache/ImmutableNodeInfo.java =================================================================== --- dna-jcr/src/main/java/org/jboss/dna/jcr/cache/ImmutableNodeInfo.java (revision 829) +++ dna-jcr/src/main/java/org/jboss/dna/jcr/cache/ImmutableNodeInfo.java (working copy) @@ -179,4 +179,24 @@ public PropertyInfo getProperty( Name name ) { return this.properties.get(name); } + + /** + * + * {@inheritDoc} + * @return {@code false} always as this object represents unmodified nodes only + * @see org.jboss.dna.jcr.cache.NodeInfo#isNew() + */ + public boolean isNew() { + return false; + } + + /** + * + * {@inheritDoc} + * @return {@code false} always as this object represents unmodified nodes only + * @see org.jboss.dna.jcr.cache.NodeInfo#isModified() + */ + public boolean isModified() { + return false; + } } Index: dna-jcr/src/main/java/org/jboss/dna/jcr/cache/NodeInfo.java =================================================================== --- dna-jcr/src/main/java/org/jboss/dna/jcr/cache/NodeInfo.java (revision 829) +++ dna-jcr/src/main/java/org/jboss/dna/jcr/cache/NodeInfo.java (working copy) @@ -104,4 +104,23 @@ * @return the property information, or null if this node has no property with the supplied name */ public PropertyInfo getProperty( Name name ); + + /** + * Indicates whether the node represented by this {@link NodeInfo} is new (i.e., does not yet exist in the persistent + * repository). + * + * @return {@code true} if the node represented by this {@link NodeInfo} has not yet been saved to the persistent repository. + * @see javax.jcr.Item#isNew() + */ + public boolean isNew(); + + /** + * Indicates whether the node represented by this {@link NodeInfo} is modified (i.e., exists in the persistent repository with + * different child items). + * + * @return {@code true} if the immediate child items of the node represented by this {@link NodeInfo} have been modified since + * the last time the node was saved to the persistent repository + * @see javax.jcr.Item#isModified() + */ + public boolean isModified(); } Index: dna-jcr/src/main/java/org/jboss/dna/jcr/cache/PropertyInfo.java =================================================================== --- dna-jcr/src/main/java/org/jboss/dna/jcr/cache/PropertyInfo.java (revision 829) +++ dna-jcr/src/main/java/org/jboss/dna/jcr/cache/PropertyInfo.java (working copy) @@ -48,17 +48,26 @@ private final Property dnaProperty; private final int propertyType; private final boolean multiValued; + private final boolean isNew; + private final boolean isModified; public PropertyInfo( PropertyId propertyId, PropertyDefinitionId definitionId, int propertyType, Property dnaProperty, - boolean multiValued ) { + boolean multiValued, + boolean isNew, + boolean isModified ) { this.propertyId = propertyId; this.definitionId = definitionId; this.propertyType = propertyType; this.dnaProperty = dnaProperty; this.multiValued = multiValued; + this.isNew = isNew; + this.isModified = isModified; + + assert isNew ? !isModified : true; + assert isModified ? !isNew : true; } /** @@ -123,6 +132,27 @@ } /** + * Indicates whether this property/value combination is new (i.e., does not yet exist in the persistent repository). + * + * @return {@code true} if the property has not yet been saved to the persistent repository. + * @see javax.jcr.Item#isNew() + */ + public boolean isNew() { + return this.isNew; + } + + /** + * Indicates whether this property/value combination is modified (i.e., exists in the persistent repository with a different + * value or values). + * + * @return {@code true} if the property has been modified since the last time it was saved to the persistent repository + * @see javax.jcr.Item#isModified() + */ + public boolean isModified() { + return this.isModified; + } + + /** * {@inheritDoc} * * @see java.lang.Object#hashCode() Index: dna-jcr/src/main/java/org/jboss/dna/jcr/SessionCache.java =================================================================== --- dna-jcr/src/main/java/org/jboss/dna/jcr/SessionCache.java (revision 829) +++ dna-jcr/src/main/java/org/jboss/dna/jcr/SessionCache.java (working copy) @@ -513,7 +631,7 @@ cached = loadFromGraph(uuid, null); } // Now put into the changed nodes ... - info = new ChangedNodeInfo(cached); + info = new ChangedNodeInfo(cached, false); changedNodes.put(uuid, info); currentLocation = info.getOriginalLocation(); } else { @@ -611,7 +729,7 @@ Property dnaProp = propertyFactory.create(name, objValue); // Create the property info ... - PropertyInfo newProperty = new PropertyInfo(id, definition.getId(), propertyType, dnaProp, definition.isMultiple()); + PropertyInfo newProperty = new PropertyInfo(id, definition.getId(), propertyType, dnaProp, definition.isMultiple(), existing == null, existing != null); // Finally update the cached information and record the change ... node.setProperty(newProperty, factories()); @@ -724,7 +842,7 @@ Property dnaProp = propertyFactory.create(name, objValues); // Create the property info ... - PropertyInfo newProperty = new PropertyInfo(id, definition.getId(), propertyType, dnaProp, definition.isMultiple()); + PropertyInfo newProperty = new PropertyInfo(id, definition.getId(), propertyType, dnaProp, definition.isMultiple(), existing == null, existing != null); // Finally update the cached information and record the change ... node.setProperty(newProperty, factories()); @@ -908,7 +1042,7 @@ JcrPropertyDefinition defn = (JcrPropertyDefinition)propertyDefinition; org.jboss.dna.graph.property.Property uuidProperty = propertyFactory.create(JcrLexicon.UUID, desiredUuid); PropertyInfo propInfo = new PropertyInfo(propId, defn.getId(), PropertyType.STRING, uuidProperty, - defn.isMultiple()); + defn.isMultiple(), true, false); properties.put(JcrLexicon.UUID, propInfo); } @@ -920,7 +1054,7 @@ false); PropertyDefinitionId primaryTypeDefinitionId = primaryTypeDefn.getId(); PropertyInfo primaryTypeInfo = new PropertyInfo(new PropertyId(desiredUuid, primaryTypeProp.getName()), - primaryTypeDefinitionId, PropertyType.NAME, primaryTypeProp, false); + primaryTypeDefinitionId, PropertyType.NAME, primaryTypeProp, false, true, false); properties.put(primaryTypeProp.getName(), primaryTypeInfo); // Create the property info for the "dna:nodeDefinition" child property ... @@ -933,14 +1067,14 @@ PropertyDefinitionId nodeDefnDefinitionId = nodeDefnDefn.getId(); PropertyInfo nodeDefinitionInfo = new PropertyInfo(new PropertyId(desiredUuid, nodeDefinitionProp.getName()), nodeDefnDefinitionId, PropertyType.STRING, nodeDefinitionProp, - true); + true, true, false); properties.put(nodeDefinitionProp.getName(), nodeDefinitionInfo); } // Now create the child node info, putting it in the changed map (and not the cache map!) ... NodeInfo info = new ImmutableNodeInfo(location, primaryTypeName, null, definition.getId(), node.getUuid(), null, properties); - ChangedNodeInfo changedInfo = new ChangedNodeInfo(info); + ChangedNodeInfo changedInfo = new ChangedNodeInfo(info, true); changedNodes.put(desiredUuid, changedInfo); // --------------------------------------- @@ -1609,7 +1743,7 @@ // Record the property in the node information ... PropertyId propId = new PropertyId(uuid, name); JcrPropertyDefinition defn = (JcrPropertyDefinition)propertyDefinition; - PropertyInfo propInfo = new PropertyInfo(propId, defn.getId(), propertyType, dnaProp, defn.isMultiple()); + PropertyInfo propInfo = new PropertyInfo(propId, defn.getId(), propertyType, dnaProp, defn.isMultiple(), false, false); props.put(name, propInfo); } @@ -1625,7 +1759,7 @@ false); PropertyId propId = new PropertyId(uuid, JcrLexicon.UUID); JcrPropertyDefinition defn = (JcrPropertyDefinition)propertyDefinition; - PropertyInfo propInfo = new PropertyInfo(propId, defn.getId(), PropertyType.STRING, uuidProperty, defn.isMultiple()); + PropertyInfo propInfo = new PropertyInfo(propId, defn.getId(), PropertyType.STRING, uuidProperty, defn.isMultiple(), false, false); props.put(JcrLexicon.UUID, propInfo); } else { // Make sure there is NOT a "jcr:uuid" property ... Index: dna-jcr/src/test/java/org/jboss/dna/jcr/AbstractJcrItemTest.java =================================================================== --- dna-jcr/src/test/java/org/jboss/dna/jcr/AbstractJcrItemTest.java (revision 829) +++ dna-jcr/src/test/java/org/jboss/dna/jcr/AbstractJcrItemTest.java (working copy) @@ -73,6 +73,14 @@ return false; } + public boolean isNew() { + return false; + } + + public boolean isModified() { + return false; + } + public void refresh( boolean keepChanges ) { throw new UnsupportedOperationException(); } Index: dna-jcr/src/test/java/org/jboss/dna/jcr/cache/ChangedNodeInfoTest.java =================================================================== --- dna-jcr/src/test/java/org/jboss/dna/jcr/cache/ChangedNodeInfoTest.java (revision 829) +++ dna-jcr/src/test/java/org/jboss/dna/jcr/cache/ChangedNodeInfoTest.java (working copy) @@ -89,7 +89,7 @@ original = new ImmutableNodeInfo(location, primaryTypeName, mixinTypeNames, definitionId, uuid, children, properties); // Create the changed node representation ... - changes = new ChangedNodeInfo(original); + changes = new ChangedNodeInfo(original, false); } protected Name name( String name ) { Index: dna-jcr/src/test/java/org/jboss/dna/jcr/JcrTckTest.java =================================================================== --- dna-jcr/src/test/java/org/jboss/dna/jcr/JcrTckTest.java (revision 829) +++ dna-jcr/src/test/java/org/jboss/dna/jcr/JcrTckTest.java (working copy) @@ -40,16 +43,25 @@ import org.apache.jackrabbit.test.api.NamespaceRegistryTest; import org.apache.jackrabbit.test.api.NodeAddMixinTest; import org.apache.jackrabbit.test.api.NodeCanAddMixinTest; +import org.apache.jackrabbit.test.api.NodeItemIsModifiedTest; +import org.apache.jackrabbit.test.api.NodeItemIsNewTest; import org.apache.jackrabbit.test.api.NodeRemoveMixinTest; +import org.apache.jackrabbit.test.api.NodeTest; +import org.apache.jackrabbit.test.api.PropertyItemIsModifiedTest; +import org.apache.jackrabbit.test.api.PropertyItemIsNewTest; import org.apache.jackrabbit.test.api.PropertyTest; import org.apache.jackrabbit.test.api.RepositoryLoginTest; +import org.apache.jackrabbit.test.api.SerializationTest; +import org.apache.jackrabbit.test.api.SessionTest; import org.apache.jackrabbit.test.api.SessionUUIDTest; +import org.apache.jackrabbit.test.api.SetPropertyAssumeTypeTest; import org.apache.jackrabbit.test.api.SetPropertyBooleanTest; import org.apache.jackrabbit.test.api.SetPropertyCalendarTest; import org.apache.jackrabbit.test.api.SetPropertyConstraintViolationExceptionTest; import org.apache.jackrabbit.test.api.SetPropertyDoubleTest; import org.apache.jackrabbit.test.api.SetPropertyInputStreamTest; import org.apache.jackrabbit.test.api.SetPropertyLongTest; +import org.apache.jackrabbit.test.api.SetPropertyNodeTest; import org.apache.jackrabbit.test.api.SetPropertyStringTest; import org.apache.jackrabbit.test.api.SetPropertyValueTest; import org.apache.jackrabbit.test.api.SetValueBinaryTest; @@ -69,9 +81,11 @@ import org.apache.jackrabbit.test.api.WorkspaceCopyBetweenWorkspacesReferenceableTest; import org.apache.jackrabbit.test.api.WorkspaceCopyBetweenWorkspacesSameNameSibsTest; import org.apache.jackrabbit.test.api.WorkspaceCopyBetweenWorkspacesTest; -import org.jboss.dna.graph.DnaLexicon; +import org.apache.jackrabbit.test.api.WorkspaceCopyVersionableTest; +import org.apache.jackrabbit.test.api.WorkspaceMoveVersionableTest; import org.jboss.dna.graph.ExecutionContext; import org.jboss.dna.graph.Graph; +import org.jboss.dna.graph.JcrMixLexicon; import org.jboss.dna.graph.JcrNtLexicon; import org.jboss.dna.graph.Location; import org.jboss.dna.graph.connector.RepositoryConnection; @@ -179,9 +193,9 @@ addTestSuite(AddNodeTest.class); addTestSuite(NamespaceRegistryTest.class); // addTestSuite(ReferencesTest.class); // addTestSuite(SessionTest.class); addTestSuite(SessionUUIDTest.class); // addTestSuite(NodeTest.class); // addTestSuite(NodeUUIDTest.class); // addTestSuite(NodeOrderableChildNodesTest.class); addTestSuite(PropertyTest.class); @@ -202,17 +216,17 @@ addTestSuite(SetPropertyDoubleTest.class); addTestSuite(SetPropertyInputStreamTest.class); addTestSuite(SetPropertyLongTest.class); // addTestSuite(SetPropertyNodeTest.class); addTestSuite(SetPropertyStringTest.class); addTestSuite(SetPropertyValueTest.class); addTestSuite(SetPropertyConstraintViolationExceptionTest.class); // addTestSuite(SetPropertyAssumeTypeTest.class); - // - // addTestSuite(NodeItemIsModifiedTest.class); - // addTestSuite(NodeItemIsNewTest.class); - // addTestSuite(PropertyItemIsModifiedTest.class); - // addTestSuite(PropertyItemIsNewTest.class); + addTestSuite(NodeItemIsModifiedTest.class); + addTestSuite(NodeItemIsNewTest.class); + addTestSuite(PropertyItemIsModifiedTest.class); + addTestSuite(PropertyItemIsNewTest.class); + addTestSuite(NodeAddMixinTest.class); addTestSuite(NodeCanAddMixinTest.class); addTestSuite(NodeRemoveMixinTest.class); @@ -228,19 +242,19 @@ // addTestSuite(WorkspaceCopyReferenceableTest.class); // addTestSuite(WorkspaceCopySameNameSibsTest.class); // addTestSuite(WorkspaceCopyTest.class); - // addTestSuite(WorkspaceCopyVersionableTest.class); + addTestSuite(WorkspaceCopyVersionableTest.class); // addTestSuite(WorkspaceMoveReferenceableTest.class); // addTestSuite(WorkspaceMoveSameNameSibsTest.class); // addTestSuite(WorkspaceMoveTest.class); - // addTestSuite(WorkspaceMoveVersionableTest.class); - // + addTestSuite(WorkspaceMoveVersionableTest.class); + addTestSuite(RepositoryLoginTest.class); // addTestSuite(ImpersonateTest.class); // addTestSuite(CheckPermissionTest.class); - // - // addTestSuite(DocumentViewImportTest.class); - // addTestSuite(SerializationTest.class); + //addTestSuite(DocumentViewImportTest.class); + addTestSuite(SerializationTest.class); + addTestSuite(ValueFactoryTest.class); } }