Author: dpfister
Date: Thu Apr 21 07:58:18 2005
New Revision: 164071
URL: http://svn.apache.org/viewcvs?rev=164071&view=rev
Log:
Added ItemStateManager#hasNodeReferences()
Added check for targets of modified node references in XAResource#prepare
Removed duplicated checkLock() in NodeImpl#addMixin
Modified:
incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/ItemImpl.java
incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/NodeImpl.java
incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/WorkspaceImpl.java
incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/observation/ChangeLogBasedHierarchyMgr.java
incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/state/ChangeLog.java
incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/state/ItemStateManager.java
incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/state/LocalItemStateManager.java
incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/state/SessionItemStateManager.java
incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/state/SharedItemStateManager.java
incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/state/TransactionalItemStateManager.java
incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/state/TransientItemStateManager.java
incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/version/VersionItemStateProvider.java
incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/virtual/AbstractVISProvider.java
Modified: incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/ItemImpl.java
URL: http://svn.apache.org/viewcvs/incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/ItemImpl.java?rev=164071&r1=164070&r2=164071&view=diff
==============================================================================
--- incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/ItemImpl.java (original)
+++ incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/ItemImpl.java Thu Apr 21
07:58:18 2005
@@ -625,6 +625,21 @@
}
}
+ /**
+ * Get or create a node references object for a given target id.
+ * @param id target id
+ * @return node references object
+ * @throws ItemStateException if an error occurs
+ */
+ protected NodeReferences getOrCreateNodeReferences(NodeReferencesId id)
+ throws ItemStateException {
+
+ if (stateMgr.hasNodeReferences(id)) {
+ return stateMgr.getNodeReferences(id);
+ }
+ return new NodeReferences(id);
+ }
+
private Collection checkReferences(Iterator iterDirty, Iterator iterRemoved)
throws ReferentialIntegrityException, RepositoryException {
@@ -656,7 +671,7 @@
refs = (NodeReferences) dirtyNodeRefs.get(id);
} else {
try {
- refs = stateMgr.getNodeReferences(id);
+ refs = getOrCreateNodeReferences(id);
} catch (ItemStateException e) {
String msg = itemMgr.safeGetJCRPath(id)
+ ": failed to load node references";
@@ -710,7 +725,7 @@
refs = (NodeReferences) dirtyNodeRefs.get(refsId);
} else {
try {
- refs = stateMgr.getNodeReferences(refsId);
+ refs = getOrCreateNodeReferences(refsId);
} catch (ItemStateException e) {
String msg = itemMgr.safeGetJCRPath(targetId)
+ ": failed to load node references";
@@ -750,7 +765,7 @@
refs = (NodeReferences) dirtyNodeRefs.get(id);
} else {
try {
- refs = stateMgr.getNodeReferences(id);
+ refs = getOrCreateNodeReferences(id);
} catch (ItemStateException e) {
String msg = itemMgr.safeGetJCRPath(id)
+ ": failed to load node references";
@@ -774,12 +789,14 @@
NodeState nodeState = (NodeState) iter.next();
// check if node is referenced
NodeReferencesId id = new NodeReferencesId(nodeState.getUUID());
- NodeReferences refs;
+ NodeReferences refs = null;
if (dirtyNodeRefs.containsKey(id)) {
refs = (NodeReferences) dirtyNodeRefs.get(id);
} else {
try {
- refs = stateMgr.getNodeReferences(id);
+ if (stateMgr.hasNodeReferences(id)) {
+ refs = stateMgr.getNodeReferences(id);
+ }
} catch (ItemStateException e) {
String msg = itemMgr.safeGetJCRPath(id)
+ ": failed to load node references";
@@ -787,7 +804,7 @@
throw new RepositoryException(msg, e);
}
}
- if (refs.hasReferences()) {
+ if (refs != null && refs.hasReferences()) {
String msg = nodeState.getId()
+ ": the node cannot be removed because it is being referenced.";
log.warn(msg);
Modified: incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/NodeImpl.java
URL: http://svn.apache.org/viewcvs/incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/NodeImpl.java?rev=164071&r1=164070&r2=164071&view=diff
==============================================================================
--- incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/NodeImpl.java (original)
+++ incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/NodeImpl.java Thu Apr 21
07:58:18 2005
@@ -905,7 +905,7 @@
throws RepositoryException {
try {
NodeReferencesId targetId = new NodeReferencesId(((NodeId) id).getUUID());
- NodeReferences refs = stateMgr.getNodeReferences(targetId);
+ NodeReferences refs = getOrCreateNodeReferences(targetId);
// refs.getReferences returns a list of PropertyId's
List idList = refs.getReferences();
return new LazyItemIterator(itemMgr, idList, skipInexistent);
@@ -934,9 +934,6 @@
log.debug(msg);
throw new VersionException(msg);
}
-
- // check lock status
- checkLock();
// check protected flag
if (definition.isProtected()) {
Modified: incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/WorkspaceImpl.java
URL: http://svn.apache.org/viewcvs/incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/WorkspaceImpl.java?rev=164071&r1=164070&r2=164071&view=diff
==============================================================================
--- incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/WorkspaceImpl.java (original)
+++ incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/WorkspaceImpl.java Thu
Apr 21 07:58:18 2005
@@ -623,18 +623,21 @@
if ((options & CHECK_REFERENCES) == CHECK_REFERENCES) {
EffectiveNodeType ent = getEffectiveNodeType(targetState);
if (ent.includesNodeType(MIX_REFERENCEABLE)) {
- try {
- NodeReferencesId refsId = new NodeReferencesId(targetState.getUUID());
- NodeReferences refs = stateMgr.getNodeReferences(refsId);
- if (refs.hasReferences()) {
- throw new ReferentialIntegrityException(hierMgr.safeGetJCRPath(targetId)
- + ": cannot remove node with references");
+ NodeReferencesId refsId = new NodeReferencesId(targetState.getUUID());
+ if (stateMgr.hasNodeReferences(refsId)) {
+ try {
+ NodeReferences refs = stateMgr.getNodeReferences(refsId);
+ if (refs.hasReferences()) {
+ throw new ReferentialIntegrityException(
+ hierMgr.safeGetJCRPath(targetId) +
+ ": cannot remove node with references");
+ }
+ } catch (ItemStateException ise) {
+ String msg = "internal error: failed to check references on "
+ + hierMgr.safeGetJCRPath(targetId);
+ log.error(msg, ise);
+ throw new RepositoryException(msg, ise);
}
- } catch (ItemStateException ise) {
- String msg = "internal error: failed to check references on "
- + hierMgr.safeGetJCRPath(targetId);
- log.error(msg, ise);
- throw new RepositoryException(msg, ise);
}
}
}
Modified: incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/observation/ChangeLogBasedHierarchyMgr.java
URL: http://svn.apache.org/viewcvs/incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/observation/ChangeLogBasedHierarchyMgr.java?rev=164071&r1=164070&r2=164071&view=diff
==============================================================================
--- incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/observation/ChangeLogBasedHierarchyMgr.java
(original)
+++ incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/observation/ChangeLogBasedHierarchyMgr.java
Thu Apr 21 07:58:18 2005
@@ -140,6 +140,13 @@
throws NoSuchItemStateException, ItemStateException {
throw new UnsupportedOperationException();
}
+
+ /**
+ * {@inheritDoc}
+ */
+ public boolean hasNodeReferences(NodeReferencesId id) {
+ return false;
+ }
}
/**
@@ -202,6 +209,13 @@
public NodeReferences getNodeReferences(NodeReferencesId id)
throws NoSuchItemStateException, ItemStateException {
throw new UnsupportedOperationException();
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public boolean hasNodeReferences(NodeReferencesId id) {
+ return false;
}
}
}
Modified: incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/state/ChangeLog.java
URL: http://svn.apache.org/viewcvs/incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/state/ChangeLog.java?rev=164071&r1=164070&r2=164071&view=diff
==============================================================================
--- incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/state/ChangeLog.java (original)
+++ incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/state/ChangeLog.java Thu
Apr 21 07:58:18 2005
@@ -117,6 +117,18 @@
}
/**
+ * Return a flag indicating whether a given item state exists.
+ * @return <code>true</code> if item state exists within this
+ * log; <code>false</code> otherwise
+ */
+ public boolean has(ItemId id) {
+ if (addedStates.containsKey(id) || modifiedStates.containsKey(id)) {
+ return true;
+ }
+ return false;
+ }
+
+ /**
* Return a node references object given its id. Returns
* <code>null</code> if the node reference is not in the modified
* section.
Modified: incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/state/ItemStateManager.java
URL: http://svn.apache.org/viewcvs/incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/state/ItemStateManager.java?rev=164071&r1=164070&r2=164071&view=diff
==============================================================================
--- incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/state/ItemStateManager.java
(original)
+++ incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/state/ItemStateManager.java
Thu Apr 21 07:58:18 2005
@@ -51,4 +51,13 @@
*/
NodeReferences getNodeReferences(NodeReferencesId id)
throws NoSuchItemStateException, ItemStateException;
+
+ /**
+ * Return a flag indicating whether a node references object
+ * for a given target id exists.
+ * @param id target id
+ * @return <code>true</code> if an item state exists,
+ * otherwise <code>false</code>
+ */
+ boolean hasNodeReferences(NodeReferencesId id);
}
Modified: incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/state/LocalItemStateManager.java
URL: http://svn.apache.org/viewcvs/incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/state/LocalItemStateManager.java?rev=164071&r1=164070&r2=164071&view=diff
==============================================================================
--- incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/state/LocalItemStateManager.java
(original)
+++ incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/state/LocalItemStateManager.java
Thu Apr 21 07:58:18 2005
@@ -208,9 +208,20 @@
if (refs != null) {
return refs;
}
-
return sharedStateMgr.getNodeReferences(id);
}
+
+ /**
+ * {@inheritDoc}
+ */
+ public boolean hasNodeReferences(NodeReferencesId id) {
+ // check change log
+ if (changeLog.get(id) != null) {
+ return true;
+ }
+ return sharedStateMgr.hasNodeReferences(id);
+ }
+
//--------------------------------------------< UpdatableItemStateManager >
/**
Modified: incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/state/SessionItemStateManager.java
URL: http://svn.apache.org/viewcvs/incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/state/SessionItemStateManager.java?rev=164071&r1=164070&r2=164071&view=diff
==============================================================================
--- incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/state/SessionItemStateManager.java
(original)
+++ incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/state/SessionItemStateManager.java
Thu Apr 21 07:58:18 2005
@@ -199,6 +199,13 @@
return persistentStateMgr.getNodeReferences(id);
}
+ /**
+ * {@inheritDoc}
+ */
+ public boolean hasNodeReferences(NodeReferencesId id) {
+ return persistentStateMgr.hasNodeReferences(id);
+ }
+
//--------------------------------------------< UpdatableItemStateManager >
/**
* {@inheritDoc}
Modified: incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/state/SharedItemStateManager.java
URL: http://svn.apache.org/viewcvs/incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/state/SharedItemStateManager.java?rev=164071&r1=164070&r2=164071&view=diff
==============================================================================
--- incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/state/SharedItemStateManager.java
(original)
+++ incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/state/SharedItemStateManager.java
Thu Apr 21 07:58:18 2005
@@ -331,8 +331,31 @@
// ignore
}
}
- // create new one
- return new NodeReferences(id);
+
+ // throw
+ throw new NoSuchItemStateException(id.toString());
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public boolean hasNodeReferences(NodeReferencesId id) {
+
+ // check persistence manager
+ try {
+ if (persistMgr.exists(id)) {
+ return true;
+ }
+ } catch (ItemStateException e) {
+ // ignore
+ }
+ // check virtual providers
+ for (int i = 0; i < virtualProviders.length; i++) {
+ if (virtualProviders[i].hasNodeReferences(id)) {
+ return true;
+ }
+ }
+ return false;
}
//-------------------------------------------------------- other operations
@@ -404,6 +427,34 @@
}
/**
+ * Check targets of modified node references exist.
+ * @param log change log
+ * @throws ItemStateException if some target was not found
+ */
+ protected void checkTargetsExist(ChangeLog log) throws ItemStateException {
+ Iterator iter = log.modifiedRefs();
+ while (iter.hasNext()) {
+ NodeReferences refs = (NodeReferences) iter.next();
+ NodeId id = new NodeId(refs.getUUID());
+
+ for (int i = 0; i < virtualProviders.length; i++) {
+ VirtualItemStateProvider provider = virtualProviders[i];
+ if (provider.hasItemState(id)) {
+ refs = null;
+ break;
+ }
+ }
+ if (refs != null && refs.hasReferences()) {
+ if (!log.has(id) && !hasItemState(id)) {
+ String msg = "Target node " + id
+ + " of REFERENCE property does not exist";
+ throw new ItemStateException(msg);
+ }
+ }
+ }
+ }
+
+ /**
* Store modifications registered in a <code>ChangeLog</code>. The items
* contained in the <tt>ChangeLog</tt> are not states returned by this
* item state manager but rather must be reconnected to items provided
@@ -448,11 +499,7 @@
}
if (refs != null) {
if (refs.hasReferences()) {
- try {
- if (local.get(id) == null && !hasItemState(id)) {
- throw new NoSuchItemStateException();
- }
- } catch (NoSuchItemStateException e) {
+ if (!local.has(id) && !hasItemState(id)) {
String msg = "Target node " + id
+ " of REFERENCE property does not exist";
throw new ItemStateException(msg);
Modified: incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/state/TransactionalItemStateManager.java
URL: http://svn.apache.org/viewcvs/incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/state/TransactionalItemStateManager.java?rev=164071&r1=164070&r2=164071&view=diff
==============================================================================
--- incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/state/TransactionalItemStateManager.java
(original)
+++ incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/state/TransactionalItemStateManager.java
Thu Apr 21 07:58:18 2005
@@ -79,6 +79,25 @@
}
/**
+ * Prepare a transaction
+ *
+ * @param tx transaction context
+ * @throws TransactionException if an error occurs
+ */
+ public void prepare(TransactionContext tx) throws TransactionException {
+ ChangeLog changeLog = (ChangeLog) tx.getAttribute(ATTRIBUTE_CHANGE_LOG);
+ if (changeLog != null) {
+ try {
+ sharedStateMgr.checkTargetsExist(changeLog);
+ } catch (ItemStateException e) {
+ log.error(e);
+ changeLog.undo(sharedStateMgr);
+ throw new TransactionException("Unable to prepare transaction.", e);
+ }
+ }
+ }
+
+ /**
* Commit changes made within a transaction
*
* @param tx transaction context
@@ -94,7 +113,7 @@
} catch (ItemStateException e) {
log.error(e);
changeLog.undo(sharedStateMgr);
- throw new TransactionException("Unable to end update.", e);
+ throw new TransactionException("Unable to commit transaction.", e);
} finally {
((CommitLog) commitLog.get()).setChanges(null);
}
@@ -205,6 +224,30 @@
}
}
return super.getNodeReferences(id);
+ }
+
+ /**
+ * {@inheritDoc}
+ * <p/>
+ * If this state manager is committing changes, this method first
+ * checks the commitLog ThreadLocal. Else if associated to a transaction
+ * check the transactional change log. Fallback is always the call to
+ * the base class.
+ */
+ public boolean hasNodeReferences(NodeReferencesId id) {
+ ChangeLog changeLog = ((CommitLog) commitLog.get()).getChanges();
+ if (changeLog != null) {
+ // check commit log
+ if (changeLog.get(id) != null) {
+ return true;
+ }
+ } else if (txLog != null) {
+ // check change log
+ if (txLog.get(id) != null) {
+ return true;
+ }
+ }
+ return super.hasNodeReferences(id);
}
/**
Modified: incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/state/TransientItemStateManager.java
URL: http://svn.apache.org/viewcvs/incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/state/TransientItemStateManager.java?rev=164071&r1=164070&r2=164071&view=diff
==============================================================================
--- incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/state/TransientItemStateManager.java
(original)
+++ incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/state/TransientItemStateManager.java
Thu Apr 21 07:58:18 2005
@@ -91,6 +91,13 @@
throw new ItemStateException("getNodeReferences() not implemented");
}
+ /**
+ * {@inheritDoc}
+ */
+ public boolean hasNodeReferences(NodeReferencesId id) {
+ return false;
+ }
+
//------------------< methods for listing & querying state of cache/attic >
/**
@@ -355,6 +362,13 @@
throws NoSuchItemStateException, ItemStateException {
throw new ItemStateException("getNodeReferences() not implemented");
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public boolean hasNodeReferences(NodeReferencesId id) {
+ return false;
}
}
}
Modified: incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/version/VersionItemStateProvider.java
URL: http://svn.apache.org/viewcvs/incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/version/VersionItemStateProvider.java?rev=164071&r1=164070&r2=164071&view=diff
==============================================================================
--- incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/version/VersionItemStateProvider.java
(original)
+++ incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/version/VersionItemStateProvider.java
Thu Apr 21 07:58:18 2005
@@ -156,6 +156,13 @@
/**
* {@inheritDoc}
*/
+ public boolean hasNodeReferences(NodeReferencesId id) {
+ return vMgr.hasItem(id.getUUID());
+ }
+
+ /**
+ * {@inheritDoc}
+ */
protected boolean internalHasNodeState(NodeId id) {
return vMgr.hasItem(id.getUUID());
}
Modified: incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/virtual/AbstractVISProvider.java
URL: http://svn.apache.org/viewcvs/incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/virtual/AbstractVISProvider.java?rev=164071&r1=164070&r2=164071&view=diff
==============================================================================
--- incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/virtual/AbstractVISProvider.java
(original)
+++ incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/virtual/AbstractVISProvider.java
Thu Apr 21 07:58:18 2005
@@ -139,6 +139,13 @@
throw new NoSuchItemStateException(id.getUUID());
}
+ /**
+ * {@inheritDoc}
+ */
+ public boolean hasNodeReferences(NodeReferencesId id) {
+ return false;
+ }
+
//-------------------------------------------< VirtualItemStateProvider >---
/**
|