Index: C:/dev/jackrabbit/src/test/java/org/apache/jackrabbit/test/api/ReferencesTest.java
===================================================================
--- C:/dev/jackrabbit/src/test/java/org/apache/jackrabbit/test/api/ReferencesTest.java (revision 481177)
+++ C:/dev/jackrabbit/src/test/java/org/apache/jackrabbit/test/api/ReferencesTest.java (working copy)
@@ -163,4 +163,34 @@
fail("too many referers: " + iter.nextProperty().getPath());
}
}
+
+ /**
+ * Tests getNodeReferences before saving
+ */
+ public void testGetReferences() throws RepositoryException {
+ Node n1 = testRootNode.addNode(nodeName1, testNodeType);
+ n1.addMixin(mixReferenceable);
+ Node n2 = testRootNode.addNode(nodeName2, testNodeType);
+ n2.addMixin(mixReferenceable);
+ // with some impls. the mixin type has only affect upon save
+ testRootNode.save();
+ // create references: n3.p1 -> n1
+ Node n3 = testRootNode.addNode(nodeName3, testNodeType);
+ n3.getSession().save();
+ n3.setProperty(propertyName1, n1);
+ n3.save();
+ PropertyIterator it = n1.getReferences();
+ boolean found = false;
+ while (it.hasNext()) {
+ Property p = it.nextProperty();
+ if (p.getName().equals(propertyName1)) {
+ found = true;
+ }
+ }
+ assertTrue("Unsaved property found in getReferences", found);
+ it = n2.getReferences();
+ assertFalse(it.hasNext());
+ n3.getSession().save();
+ }
+
}
Index: C:/dev/jackrabbit/src/main/java/org/apache/jackrabbit/core/persistence/AbstractPersistenceManager.java
===================================================================
--- C:/dev/jackrabbit/src/main/java/org/apache/jackrabbit/core/persistence/AbstractPersistenceManager.java (revision 481177)
+++ C:/dev/jackrabbit/src/main/java/org/apache/jackrabbit/core/persistence/AbstractPersistenceManager.java (working copy)
@@ -21,7 +21,10 @@
import org.apache.jackrabbit.core.state.ChangeLog;
import org.apache.jackrabbit.core.state.ItemState;
import org.apache.jackrabbit.core.state.ItemStateException;
+import org.apache.jackrabbit.core.state.NoSuchItemStateException;
import org.apache.jackrabbit.core.state.NodeReferences;
+import org.apache.jackrabbit.core.state.NodeReferencesChanges;
+import org.apache.jackrabbit.core.state.NodeReferencesId;
import org.apache.jackrabbit.core.state.NodeState;
import org.apache.jackrabbit.core.state.PropertyState;
@@ -86,7 +89,22 @@
}
iter = changeLog.modifiedRefs();
while (iter.hasNext()) {
- NodeReferences refs = (NodeReferences) iter.next();
+ NodeReferencesChanges changes = (NodeReferencesChanges) iter.next();
+ NodeReferencesId id = changes.getId();
+ // load the list of references
+ // TODO the persistence manager should be able to merge changes itself
+ NodeReferences refs;
+ try {
+ refs = load(id);
+ } catch (NoSuchItemStateException e) {
+ // actually, it would be better if there is a method 'loadIfExists'
+ // that returns null if it does not exist
+ // calling a has... method first would maybe be another network
+ // roundtrip
+ refs = new NodeReferences(id);
+ }
+ // merge the changes
+ refs = refs.merge(changes);
if (refs.hasReferences()) {
store(refs);
} else {
Index: C:/dev/jackrabbit/src/main/java/org/apache/jackrabbit/core/virtual/VirtualItemStateProvider.java
===================================================================
--- C:/dev/jackrabbit/src/main/java/org/apache/jackrabbit/core/virtual/VirtualItemStateProvider.java (revision 481177)
+++ C:/dev/jackrabbit/src/main/java/org/apache/jackrabbit/core/virtual/VirtualItemStateProvider.java (working copy)
@@ -18,9 +18,10 @@
import org.apache.jackrabbit.core.ItemId;
import org.apache.jackrabbit.core.NodeId;
+import org.apache.jackrabbit.core.PropertyId;
import org.apache.jackrabbit.core.state.ItemStateManager;
-import org.apache.jackrabbit.core.state.NodeReferences;
import org.apache.jackrabbit.core.state.ItemStateListener;
+import org.apache.jackrabbit.core.state.NodeReferencesId;
import org.apache.jackrabbit.name.QName;
import javax.jcr.RepositoryException;
@@ -75,14 +76,20 @@
throws RepositoryException;
/**
- * Informs this provider that the node references to one of its states has
- * changed.
+ * Informs this provider that a node references has been added.
*
- * @param refs
- * @return true if the reference target is one of its items.
+ * @param refId
+ * @param sourceId
*/
- boolean setNodeReferences(NodeReferences refs);
+ void addReference(NodeReferencesId refsId, PropertyId sourceId);
+ /**
+ * Informs this provider that a node references has been deleted.
+ *
+ * @param refId
+ * @param sourceId
+ */
+ void deleteReference(NodeReferencesId refId, PropertyId sourceId);
/**
* Add an ItemStateListener
Index: C:/dev/jackrabbit/src/main/java/org/apache/jackrabbit/core/state/LocalItemStateManager.java
===================================================================
--- C:/dev/jackrabbit/src/main/java/org/apache/jackrabbit/core/state/LocalItemStateManager.java (revision 481177)
+++ C:/dev/jackrabbit/src/main/java/org/apache/jackrabbit/core/state/LocalItemStateManager.java (working copy)
@@ -185,20 +185,18 @@
*/
public NodeReferences getNodeReferences(NodeReferencesId id)
throws NoSuchItemStateException, ItemStateException {
-
- // check change log
- NodeReferences refs = changeLog.get(id);
- if (refs != null) {
- return refs;
+ NodeReferences references = sharedStateMgr.getNodeReferences(id);
+ NodeReferencesChanges changes = changeLog.get(id);
+ if (changes != null) {
+ references = references.merge(changes);
}
- return sharedStateMgr.getNodeReferences(id);
+ return references;
}
/**
* {@inheritDoc}
*/
public boolean hasNodeReferences(NodeReferencesId id) {
- // check change log
if (changeLog.get(id) != null) {
return true;
}
Index: C:/dev/jackrabbit/src/main/java/org/apache/jackrabbit/core/state/SharedItemStateManager.java
===================================================================
--- C:/dev/jackrabbit/src/main/java/org/apache/jackrabbit/core/state/SharedItemStateManager.java (revision 481177)
+++ C:/dev/jackrabbit/src/main/java/org/apache/jackrabbit/core/state/SharedItemStateManager.java (working copy)
@@ -18,6 +18,7 @@
import EDU.oswego.cs.dl.util.concurrent.ReadWriteLock;
import EDU.oswego.cs.dl.util.concurrent.ReentrantWriterPreferenceReadWriteLock;
+
import org.apache.jackrabbit.core.ItemId;
import org.apache.jackrabbit.core.NodeId;
import org.apache.jackrabbit.core.PropertyId;
@@ -304,9 +305,16 @@
*/
public NodeReferences getNodeReferences(NodeReferencesId id)
throws NoSuchItemStateException, ItemStateException {
+ NodeReferences result = getNodeReferencesIfExists(id);
+ if (result == null) {
+ throw new NoSuchItemStateException(id.toString());
+ }
+ return result;
+ }
+ private NodeReferences getNodeReferencesIfExists(NodeReferencesId id)
+ throws NoSuchItemStateException, ItemStateException {
acquireReadLock();
-
try {
// check persistence manager
try {
@@ -322,12 +330,10 @@
// ignore
}
}
+ return null;
} finally {
rwLock.readLock().release();
}
-
- // throw
- throw new NoSuchItemStateException(id.toString());
}
/**
@@ -612,9 +618,9 @@
// filter out virtual node references for later processing
// (see comment above)
for (Iterator iter = local.modifiedRefs(); iter.hasNext();) {
- NodeReferences refs = (NodeReferences) iter.next();
+ NodeReferencesChanges refChanges = (NodeReferencesChanges) iter.next();
boolean virtual = false;
- NodeId id = refs.getId().getTargetId();
+ NodeId id = refChanges.getId().getTargetId();
for (int i = 0; i < virtualProviders.length; i++) {
if (virtualProviders[i].hasItemState(id)) {
List virtualRefs = virtualNodeReferences[i];
@@ -622,7 +628,7 @@
virtualRefs = new LinkedList();
virtualNodeReferences[i] = virtualRefs;
}
- virtualRefs.add(refs);
+ virtualRefs.add(refChanges);
virtual = true;
break;
}
@@ -630,7 +636,14 @@
if (!virtual) {
// if target of node reference does not lie in a virtual
// space, add to modified set of normal provider.
- shared.modified(refs);
+ for (Iterator it = refChanges.getAdded(); it.hasNext();) {
+ PropertyId propId = (PropertyId) it.next();
+ shared.referenceAdded(refChanges.getId(), propId);
+ }
+ for (Iterator it = refChanges.getDeleted(); it.hasNext();) {
+ PropertyId propId = (PropertyId) it.next();
+ shared.referenceDeleted(refChanges.getId(), propId);
+ }
}
}
@@ -695,8 +708,18 @@
List virtualRefs = virtualNodeReferences[i];
if (virtualRefs != null) {
for (Iterator iter = virtualRefs.iterator(); iter.hasNext();) {
- NodeReferences refs = (NodeReferences) iter.next();
- virtualProviders[i].setNodeReferences(refs);
+ NodeReferencesChanges refChanges = (NodeReferencesChanges) iter.next();
+ NodeReferencesId refId = refChanges.getId();
+ Iterator it = refChanges.getAdded();
+ while (it.hasNext()) {
+ PropertyId prop = (PropertyId) it.next();
+ virtualProviders[i].addReference(refId, prop);
+ }
+ it = refChanges.getDeleted();
+ while (it.hasNext()) {
+ PropertyId prop = (PropertyId) it.next();
+ virtualProviders[i].deleteReference(refId, prop);
+ }
}
}
}
@@ -1159,12 +1182,8 @@
&& virtualProvider.hasNodeReferences(refsId)) {
continue;
}
- NodeReferences refs =
- getOrCreateNodeReferences(refsId, changes);
- // add reference
- refs.addReference(prop.getPropertyId());
// update change log
- changes.modified(refs);
+ changes.referenceAdded(refsId, prop.getPropertyId());
}
}
}
@@ -1189,16 +1208,8 @@
&& virtualProvider.hasNodeReferences(refsId)) {
continue;
}
- // either get node references from change log or load from
- // persistence manager
- NodeReferences refs = changes.get(refsId);
- if (refs == null) {
- refs = getNodeReferences(refsId);
- }
- // remove reference
- refs.removeReference(oldProp.getPropertyId());
// update change log
- changes.modified(refs);
+ changes.referenceDeleted(refsId, oldProp.getPropertyId());
}
}
// check new type
@@ -1213,12 +1224,8 @@
&& virtualProvider.hasNodeReferences(refsId)) {
continue;
}
- NodeReferences refs =
- getOrCreateNodeReferences(refsId, changes);
- // add reference
- refs.addReference(newProp.getPropertyId());
// update change log
- changes.modified(refs);
+ changes.referenceAdded(refsId, newProp.getPropertyId());
}
}
}
@@ -1240,16 +1247,8 @@
&& virtualProvider.hasNodeReferences(refsId)) {
continue;
}
- // either get node references from change log or
- // load from persistence manager
- NodeReferences refs = changes.get(refsId);
- if (refs == null) {
- refs = getNodeReferences(refsId);
- }
- // remove reference
- refs.removeReference(prop.getPropertyId());
// update change log
- changes.modified(refs);
+ changes.referenceDeleted(refsId, prop.getPropertyId());
}
}
}
@@ -1257,37 +1256,6 @@
}
/**
- * Returns a node references object using the following rules:
NodeReferencesChanges represents changes (additions and removals) of references
+ * (i.e. properties of type REFERENCE) to a particular node (denoted by its uuid).
+ */
+public class NodeReferencesChanges {
+
+ /**
+ * The id of the target node.
+ */
+ private final NodeReferencesId targetNodeId;
+
+ /**
+ * The set of removed properties.
+ */
+ private HashSet deleted = new HashSet();
+
+ /**
+ * The set of added properties.
+ */
+ private HashSet added = new HashSet();
+
+ NodeReferencesChanges(NodeReferencesId targetNodeId) {
+ this.targetNodeId = targetNodeId;
+ }
+
+ /**
+ * Add a reference.
+ * If this property is in the 'delete' set, it is removed there;
+ * otherwise it is added to the 'add' set.
+ * @param sourcePropertyId
+ */
+ public void add(PropertyId sourcePropertyId) {
+ if (!deleted.remove(sourcePropertyId)) {
+ added.add(sourcePropertyId);
+ }
+ }
+
+ /**
+ * Remove a reference.
+ * If this property is in the 'add' set, it is removed there;
+ * otherwise it is added to the 'delete' set.
+ * @param sourcePropertyId
+ */
+ public void delete(PropertyId sourcePropertyId) {
+ if (!added.remove(sourcePropertyId)) {
+ deleted.add(sourcePropertyId);
+ }
+ }
+
+ /**
+ * Get the node references id
+ * @return the id
+ */
+ public NodeReferencesId getId() {
+ return targetNodeId;
+ }
+
+ /**
+ * Get an iterator for the 'add' set.
+ * @return the iterator
+ */
+ public Iterator getAdded() {
+ return added.iterator();
+ }
+
+ /**
+ * Get an iterator for the 'delete' set.
+ * @return the iterator
+ */
+ public Iterator getDeleted() {
+ return deleted.iterator();
+ }
+
+ /**
+ * Get the combined size of both the 'add' and the 'delete' set.
+ * @return the size
+ */
+ public int size() {
+ return deleted.size() + added.size();
+ }
+
+ /**
+ * Get the size of the 'add' set.
+ * @return the size
+ */
+ public int getAddedSize() {
+ return added.size();
+ }
+
+}
Index: C:/dev/jackrabbit/src/main/java/org/apache/jackrabbit/core/state/XAItemStateManager.java
===================================================================
--- C:/dev/jackrabbit/src/main/java/org/apache/jackrabbit/core/state/XAItemStateManager.java (revision 481177)
+++ C:/dev/jackrabbit/src/main/java/org/apache/jackrabbit/core/state/XAItemStateManager.java (working copy)
@@ -274,13 +274,12 @@
return virtualProvider.getNodeReferences(id);
}
ChangeLog changeLog = getChangeLog();
+ NodeReferences refs = super.getNodeReferences(id);
if (changeLog != null) {
- NodeReferences refs = changeLog.get(id);
- if (refs != null) {
- return refs;
- }
+ NodeReferencesChanges changes = changeLog.get(id);
+ refs = refs.merge(changes);
}
- return super.getNodeReferences(id);
+ return refs;
}
/**
@@ -395,14 +394,9 @@
NodeReferencesId refsId)
throws NoSuchItemStateException, ItemStateException {
- NodeReferences refs = virtualProvider.getNodeReferences(refsId);
- if (refs == null && virtualProvider.hasItemState(refsId.getTargetId())) {
- refs = new NodeReferences(refsId);
+ if (!virtualProvider.hasNodeReferences(refsId) && virtualProvider.hasItemState(refsId.getTargetId())) {
+ virtualProvider.addReference(refsId, sourceId);
}
- if (refs != null) {
- refs.addReference(sourceId);
- virtualProvider.setNodeReferences(refs);
- }
}
/**
@@ -416,13 +410,8 @@
NodeReferencesId refsId)
throws NoSuchItemStateException, ItemStateException {
- NodeReferences refs = virtualProvider.getNodeReferences(refsId);
- if (refs == null && virtualProvider.hasItemState(refsId.getTargetId())) {
- refs = new NodeReferences(refsId);
+ if (!virtualProvider.hasNodeReferences(refsId) && virtualProvider.hasItemState(refsId.getTargetId())) {
+ virtualProvider.deleteReference(refsId, sourceId);
}
- if (refs != null) {
- refs.removeReference(sourceId);
- virtualProvider.setNodeReferences(refs);
- }
}
}
Index: C:/dev/jackrabbit/src/main/java/org/apache/jackrabbit/core/state/ChangeLog.java
===================================================================
--- C:/dev/jackrabbit/src/main/java/org/apache/jackrabbit/core/state/ChangeLog.java (revision 481177)
+++ C:/dev/jackrabbit/src/main/java/org/apache/jackrabbit/core/state/ChangeLog.java (working copy)
@@ -18,6 +18,7 @@
import org.apache.commons.collections.map.LinkedMap;
import org.apache.jackrabbit.core.ItemId;
+import org.apache.jackrabbit.core.PropertyId;
import java.util.Iterator;
import java.util.Map;
@@ -90,15 +91,46 @@
}
/**
- * A references has been modified
+ * A reference has been added.
*
- * @param refs refs that has been modified
+ * @param ref the reference that has been added
+ * @param sourcePropertyId the referencing property
*/
- public void modified(NodeReferences refs) {
- modifiedRefs.put(refs.getId(), refs);
+ public void referenceAdded(NodeReferencesId ref, PropertyId sourcePropertyId) {
+ NodeReferencesChanges changes = (NodeReferencesChanges) modifiedRefs.get(ref);
+ if (changes == null) {
+ changes = new NodeReferencesChanges(ref);
+ changes.add(sourcePropertyId);
+ modifiedRefs.put(ref, changes);
+ } else {
+ changes.add(sourcePropertyId);
+ if (changes.size() == 0) {
+ modifiedRefs.remove(ref);
+ }
+ }
}
/**
+ * A reference has been removed.
+ *
+ * @param ref the reference that has been removed
+ * @param sourcePropertyId the referencing property
+ */
+ public void referenceDeleted(NodeReferencesId ref, PropertyId sourcePropertyId) {
+ NodeReferencesChanges changes = (NodeReferencesChanges) modifiedRefs.get(ref);
+ if (changes == null) {
+ changes = new NodeReferencesChanges(ref);
+ changes.delete(sourcePropertyId);
+ modifiedRefs.put(ref, changes);
+ } else {
+ changes.delete(sourcePropertyId);
+ if (changes.size() == 0) {
+ modifiedRefs.remove(ref);
+ }
+ }
+ }
+
+ /**
* Return an item state given its id. Returns null
* if the item state is neither in the added nor in the modified
* section. Throws a NoSuchItemStateException if
@@ -142,14 +174,14 @@
}
/**
- * Return a node references object given its id. Returns
+ * Return a node references changes object given its id. Returns
* null if the node reference is not in the modified
* section.
*
- * @return node references or null
+ * @return node references changes or null
*/
- public NodeReferences get(NodeReferencesId id) {
- return (NodeReferences) modifiedRefs.get(id);
+ public NodeReferencesChanges get(NodeReferencesId id) {
+ return (NodeReferencesChanges) modifiedRefs.get(id);
}
/**
@@ -180,9 +212,9 @@
}
/**
- * Return an iterator over all modified references.
+ * Return an iterator over all references changes.
*
- * @return iterator over all modified references.
+ * @return iterator over all references changes.
*/
public Iterator modifiedRefs() {
return modifiedRefs.values().iterator();
@@ -235,9 +267,22 @@
addedStates.put(state.getId(), state);
}
}
-
- // add refs
- modifiedRefs.putAll(other.modifiedRefs);
+ // changed references
+ iter = other.modifiedRefs.keySet().iterator();
+ while (iter.hasNext()) {
+ NodeReferencesId ref = (NodeReferencesId) iter.next();
+ NodeReferencesChanges changes = other.get(ref);
+ Iterator itAdded = changes.getAdded();
+ while (itAdded.hasNext()) {
+ PropertyId prop = (PropertyId) itAdded.next();
+ referenceAdded(ref, prop);
+ }
+ Iterator itDeleted = changes.getDeleted();
+ while (itDeleted.hasNext()) {
+ PropertyId prop = (PropertyId) itDeleted.next();
+ referenceDeleted(ref, prop);
+ }
+ }
}
/**
Index: C:/dev/jackrabbit/src/main/java/org/apache/jackrabbit/core/state/NodeReferences.java
===================================================================
--- C:/dev/jackrabbit/src/main/java/org/apache/jackrabbit/core/state/NodeReferences.java (revision 481177)
+++ C:/dev/jackrabbit/src/main/java/org/apache/jackrabbit/core/state/NodeReferences.java (working copy)
@@ -22,6 +22,7 @@
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Collections;
+import java.util.Iterator;
import java.util.List;
/**
@@ -123,4 +124,23 @@
public void clearAllReferences() {
references.clear();
}
+
+ public NodeReferences merge(NodeReferencesChanges changes) {
+ if (changes == null || (changes.size() == 0)) {
+ return this;
+ }
+ NodeReferences copy = new NodeReferences(id);
+ copy.references = new ArrayList(references);
+ Iterator it = changes.getAdded();
+ while (it.hasNext()) {
+ PropertyId propId = (PropertyId) it.next();
+ copy.addReference(propId);
+ }
+ it = changes.getDeleted();
+ while (it.hasNext()) {
+ PropertyId propId = (PropertyId) it.next();
+ copy.removeReference(propId);
+ }
+ return copy;
+ }
}
Index: C:/dev/jackrabbit/src/main/java/org/apache/jackrabbit/core/version/VersionManagerImpl.java
===================================================================
--- C:/dev/jackrabbit/src/main/java/org/apache/jackrabbit/core/version/VersionManagerImpl.java (revision 481177)
+++ C:/dev/jackrabbit/src/main/java/org/apache/jackrabbit/core/version/VersionManagerImpl.java (working copy)
@@ -36,6 +36,7 @@
import org.apache.jackrabbit.core.state.ItemStateListener;
import org.apache.jackrabbit.core.state.LocalItemStateManager;
import org.apache.jackrabbit.core.state.NodeReferences;
+import org.apache.jackrabbit.core.state.NodeReferencesChanges;
import org.apache.jackrabbit.core.state.NodeReferencesId;
import org.apache.jackrabbit.core.state.NodeState;
import org.apache.jackrabbit.core.state.PropertyState;
@@ -405,30 +406,39 @@
}
/**
- * Sets and stored the node references from external nodes.
+ * Adds a reference to a node from external nodes.
* @param references
- * @return true if the references could be set.
*/
- public boolean setNodeReferences(NodeReferences references) {
+ public void addReference(NodeReferencesId refsId, PropertyId sourceId) {
acquireWriteLock();
try {
// filter out version storage intern ones
- NodeReferences refs = new NodeReferences(references.getId());
- Iterator iter = references.getReferences().iterator();
- while (iter.hasNext()) {
- PropertyId id = (PropertyId) iter.next();
- if (!hasItem(id.getParentId())) {
- refs.addReference(id);
- }
+ if (!hasItem(sourceId.getParentId())) {
+ ChangeLog log = new ChangeLog();
+ log.referenceAdded(refsId, sourceId);
+ pMgr.store(log);
}
+ } catch (ItemStateException e) {
+ log.error("Error while setting references: " + e.toString());
+ } finally {
+ releaseWriteLock();
+ }
+ }
- ChangeLog log = new ChangeLog();
- log.modified(refs);
- pMgr.store(log);
- return true;
+ /**
+ * {@inheritDoc}
+ */
+ public void deleteReference(NodeReferencesId refsId, PropertyId sourceId) {
+ acquireWriteLock();
+ try {
+ // filter out version storage intern ones
+ if (!hasItem(sourceId.getParentId())) {
+ ChangeLog log = new ChangeLog();
+ log.referenceDeleted(refsId, sourceId);
+ pMgr.store(log);
+ }
} catch (ItemStateException e) {
log.error("Error while setting references: " + e.toString());
- return false;
} finally {
releaseWriteLock();
}
@@ -534,10 +544,11 @@
// check whether targets of modified node references exist
for (Iterator iter = changes.modifiedRefs(); iter.hasNext();) {
- NodeReferences refs = (NodeReferences) iter.next();
- NodeId id = refs.getTargetId();
- // no need to check existence of target if there are no references
- if (refs.hasReferences()) {
+ NodeReferencesChanges refChanges = (NodeReferencesChanges) iter.next();
+ NodeReferencesId refId = refChanges.getId();
+ NodeId id = refId.getTargetId();
+ // no need to check existence of target if there are no added or deleted references
+ if (refChanges.size() > 0) {
if (!changes.has(id) && !hasItemState(id)) {
// remove references
iter.remove();
Index: C:/dev/jackrabbit/src/main/java/org/apache/jackrabbit/core/version/XAVersionManager.java
===================================================================
--- C:/dev/jackrabbit/src/main/java/org/apache/jackrabbit/core/version/XAVersionManager.java (revision 481177)
+++ C:/dev/jackrabbit/src/main/java/org/apache/jackrabbit/core/version/XAVersionManager.java (working copy)
@@ -20,6 +20,7 @@
import org.apache.jackrabbit.core.ItemId;
import org.apache.jackrabbit.core.NodeId;
import org.apache.jackrabbit.core.NodeImpl;
+import org.apache.jackrabbit.core.PropertyId;
import org.apache.jackrabbit.core.SessionImpl;
import org.apache.jackrabbit.core.TransactionContext;
import org.apache.jackrabbit.core.TransactionException;
@@ -33,6 +34,7 @@
import org.apache.jackrabbit.core.state.ItemStateListener;
import org.apache.jackrabbit.core.state.NoSuchItemStateException;
import org.apache.jackrabbit.core.state.NodeReferences;
+import org.apache.jackrabbit.core.state.NodeReferencesChanges;
import org.apache.jackrabbit.core.state.NodeReferencesId;
import org.apache.jackrabbit.core.state.NodeState;
import org.apache.jackrabbit.core.state.XAItemStateManager;
@@ -243,17 +245,25 @@
/**
* {@inheritDoc}
*/
- public boolean setNodeReferences(NodeReferences refs) {
+ public void addReference(NodeReferencesId refsId, PropertyId sourceId) {
ChangeLog changeLog = ((XAItemStateManager) stateMgr).getChangeLog();
if (changeLog != null) {
- changeLog.modified(refs);
- return true;
+ changeLog.referenceAdded(refsId, sourceId);
}
- return false;
}
/**
* {@inheritDoc}
+ */
+ public void deleteReference(NodeReferencesId refId, PropertyId prop) {
+ ChangeLog changeLog = ((XAItemStateManager) stateMgr).getChangeLog();
+ if (changeLog != null) {
+ changeLog.referenceDeleted(refId, prop);
+ }
+ }
+
+ /**
+ * {@inheritDoc}
*
* Return item states for changes only. Global version manager will return
* other items.
@@ -284,11 +294,16 @@
*/
public NodeReferences getNodeReferences(NodeReferencesId id)
throws NoSuchItemStateException, ItemStateException {
-
ChangeLog changeLog = ((XAItemStateManager) stateMgr).getChangeLog();
- if (changeLog != null) {
- return changeLog.get(id);
+ NodeReferencesChanges changes = changeLog.get(id);
+ if (changes == null) {
+ return null;
}
+ NodeReferences refs = stateMgr.getNodeReferences(id);
+ refs = refs.merge(changes);
+ if (refs.getReferences().size() > 0) {
+ return refs;
+ }
return null;
}
@@ -382,11 +397,11 @@
// also put 'successor' and 'predecessor' version items to xaItem sets
InternalVersion v = history.getVersion(name);
InternalVersion[] vs = v.getSuccessors();
- for (int i=0; i