use of javax.jcr.ReferentialIntegrityException in project jackrabbit by apache.
the class RemoveVersionTest method testReferentialIntegrityException.
/**
* Checks if {@link javax.jcr.version.VersionHistory#removeVersion(String)}
* throws a {@link javax.jcr.ReferentialIntegrityException} if the named
* version is still referenced by another node.
* <ul>
* <li>{@code nodetype} name of a node type that supports a reference
* property.
* <li>{@code nodename4} name of the node created with <code>nodetype</code>.
* <li>{@code propertyname1} a single value reference property available
* in <code>nodetype</code>.
* </ul>
*/
public void testReferentialIntegrityException() throws RepositoryException, NotExecutableException {
// create reference: n1.p1 -> version
Node n1 = testRootNode.addNode(nodeName4, testNodeType);
Value refValue = superuser.getValueFactory().createValue(version);
ensureCanSetProperty(n1, propertyName1, refValue);
n1.setProperty(propertyName1, refValue);
testRootNode.getSession().save();
try {
vHistory.removeVersion(version.getName());
fail("Method removeVersion() must throw a ReferentialIntegrityException " + "if the version is the target of a REFERENCE property and the current " + "Session has read access to that REFERENCE property");
} catch (ReferentialIntegrityException e) {
// success
}
}
use of javax.jcr.ReferentialIntegrityException in project jackrabbit-oak by apache.
the class ReferencesTest method testRecreateNonReferenceable.
public void testRecreateNonReferenceable() throws RepositoryException {
Node ref = testRootNode.addNode(nodeName1, testNodeType);
ref.addMixin(mixReferenceable);
superuser.save();
Node n1 = testRootNode.addNode(nodeName2, testNodeType);
n1.setProperty("ref", ref);
assertEquals(PropertyType.REFERENCE, n1.getProperty("ref").getType());
superuser.save();
// recreate
ref.remove();
testRootNode.addNode(nodeName1, testNodeType);
try {
superuser.save();
fail("must fail with ReferentialIntegrityException");
} catch (ReferentialIntegrityException e) {
// expected
}
}
use of javax.jcr.ReferentialIntegrityException in project jackrabbit-oak by apache.
the class ReferencesTest method testRemoveReferenced2.
public void testRemoveReferenced2() throws RepositoryException {
Node ref = testRootNode.addNode(nodeName1, testNodeType);
ref.addMixin(mixReferenceable);
superuser.save();
Node n1 = testRootNode.addNode(nodeName2, testNodeType);
n1.setProperty("ref", ref);
assertEquals(PropertyType.REFERENCE, n1.getProperty("ref").getType());
Node n2 = testRootNode.addNode(nodeName3, testNodeType);
n2.setProperty("ref", ref);
assertEquals(PropertyType.REFERENCE, n2.getProperty("ref").getType());
superuser.save();
ref.remove();
n1.remove();
try {
superuser.save();
fail("must fail with ReferentialIntegrityException");
} catch (ReferentialIntegrityException e) {
// expected
}
}
use of javax.jcr.ReferentialIntegrityException in project jackrabbit by apache.
the class SessionUUIDTest method testSaveReferentialIntegrityException.
/**
* Tries to remove a node that is a reference target using {@link Session#save()}.
* <p>
* Procedure:
* <ul>
* <li>Creates two nodes with same session</li>
* <li>One has a referencing property pointing to the other node</li>
* <li>Target node gets removed</li>
* </ul>
* <p>
* This should generate a {@link javax.jcr.ReferentialIntegrityException} upon save.
* <p>
* Prerequisites:
* <ul>
* <li><code>javax.jcr.tck.SessionUUIDTest.nodetype</code> must allow a property of type {@link javax.jcr.PropertyType#REFERENCE}</li>
* <li><code>javax.jcr.tck.SessionUUIDTest.propertyname1</code> name of the property of type {@link javax.jcr.PropertyType#REFERENCE}</li>
* <li><code>javax.jcr.tck.SessionUUIDTest.nodetype2</code> must have the mixin type <code>mix:referenceable</code> assigned.</li>
* </ul>
*/
public void testSaveReferentialIntegrityException() throws RepositoryException, NotExecutableException {
// get default workspace test root node using superuser session
Node defaultRootNode = (Node) superuser.getItem(testRootNode.getPath());
// create a node with a property of type PropertyType.REFERENCE
Node referencingNode = defaultRootNode.addNode(nodeName1, testNodeType);
// create a node with a jcr:uuid property to serve as target
Node refTargetNode = defaultRootNode.addNode(nodeName2, getProperty("nodetype2"));
// implementations may only have the mix:referenceable active upon save
defaultRootNode.save();
if (!refTargetNode.isNodeType(mixReferenceable)) {
throw new NotExecutableException("Cannot test referential integrity. Node is not referenceable.");
}
// abort test if the repository does not allow setting
// reference properties on this node
ensureCanSetProperty(referencingNode, propertyName1, referencingNode.getSession().getValueFactory().createValue(refTargetNode));
// set the reference
referencingNode.setProperty(propertyName1, refTargetNode);
// save the new nodes
superuser.save();
// remove the referenced node
refTargetNode.remove();
// try to save
try {
superuser.save();
fail("Saving a deleted node using Session.save() that is a reference target should throw ReferentialIntegrityException");
} catch (ReferentialIntegrityException e) {
// ok, works as expected
}
}
use of javax.jcr.ReferentialIntegrityException in project jackrabbit by apache.
the class BatchedItemOperations method checkRemoveNode.
/**
* Checks if removing the given target node from the specifed parent
* is allowed in the current context.
*
* @param targetState
* @param parentId
* @param options bit-wise OR'ed flags specifying the checks that should be
* performed; any combination of the following constants:
* <ul>
* <li><code>{@link #CHECK_ACCESS}</code>: make sure
* current session is granted read access on parent
* and remove privilege on target node</li>
* <li><code>{@link #CHECK_LOCK}</code>: make sure
* there's no foreign lock on parent node</li>
* <li><code>{@link #CHECK_CHECKED_OUT}</code>: make sure
* parent node is checked-out</li>
* <li><code>{@link #CHECK_CONSTRAINTS}</code>:
* make sure no node type constraints would be violated</li>
* <li><code>{@link #CHECK_REFERENCES}</code>:
* make sure no references exist on target node</li>
* <li><code>{@link #CHECK_HOLD}</code>: check for effective holds preventing the add operation</li>
* <li><code>{@link #CHECK_RETENTION}</code>: check for effective retention policy preventing the add operation</li>
* </ul>
* @throws ConstraintViolationException
* @throws AccessDeniedException
* @throws VersionException
* @throws LockException
* @throws ItemNotFoundException
* @throws ReferentialIntegrityException
* @throws RepositoryException
*/
public void checkRemoveNode(NodeState targetState, NodeId parentId, int options) throws ConstraintViolationException, AccessDeniedException, VersionException, LockException, ItemNotFoundException, ReferentialIntegrityException, RepositoryException {
if (targetState.getParentId() == null) {
// root or orphaned node
throw new ConstraintViolationException("cannot remove root node");
}
Path targetPath = hierMgr.getPath(targetState.getNodeId());
NodeState parentState = getNodeState(parentId);
Path parentPath = hierMgr.getPath(parentId);
if ((options & CHECK_LOCK) == CHECK_LOCK) {
// make sure there's no foreign lock on parent node
verifyUnlocked(parentPath);
}
if ((options & CHECK_CHECKED_OUT) == CHECK_CHECKED_OUT) {
// make sure parent node is checked-out
verifyCheckedOut(parentPath);
}
if ((options & CHECK_ACCESS) == CHECK_ACCESS) {
try {
AccessManager accessMgr = context.getAccessManager();
// make sure current session is granted read access on parent node
if (!accessMgr.isGranted(targetPath, Permission.READ)) {
throw new PathNotFoundException(safeGetJCRPath(targetPath));
}
// make sure current session is allowed to remove target node
if (!accessMgr.isGranted(targetPath, Permission.REMOVE_NODE)) {
throw new AccessDeniedException(safeGetJCRPath(targetPath) + ": not allowed to remove node");
}
} catch (ItemNotFoundException infe) {
String msg = "internal error: failed to check access rights for " + safeGetJCRPath(targetPath);
log.debug(msg);
throw new RepositoryException(msg, infe);
}
}
if ((options & CHECK_CONSTRAINTS) == CHECK_CONSTRAINTS) {
QItemDefinition parentDef = context.getItemManager().getDefinition(parentState).unwrap();
if (parentDef.isProtected()) {
throw new ConstraintViolationException(safeGetJCRPath(parentId) + ": cannot remove child node of protected parent node");
}
QItemDefinition targetDef = context.getItemManager().getDefinition(targetState).unwrap();
if (targetDef.isMandatory()) {
throw new ConstraintViolationException(safeGetJCRPath(targetPath) + ": cannot remove mandatory node");
}
if (targetDef.isProtected()) {
throw new ConstraintViolationException(safeGetJCRPath(targetPath) + ": cannot remove protected node");
}
}
if ((options & CHECK_REFERENCES) == CHECK_REFERENCES) {
EffectiveNodeType ent = getEffectiveNodeType(targetState);
if (ent.includesNodeType(NameConstants.MIX_REFERENCEABLE)) {
NodeId targetId = targetState.getNodeId();
if (stateMgr.hasNodeReferences(targetId)) {
try {
NodeReferences refs = stateMgr.getNodeReferences(targetId);
if (refs.hasReferences()) {
throw new ReferentialIntegrityException(safeGetJCRPath(targetPath) + ": cannot remove node with references");
}
} catch (ItemStateException ise) {
String msg = "internal error: failed to check references on " + safeGetJCRPath(targetPath);
log.error(msg, ise);
throw new RepositoryException(msg, ise);
}
}
}
}
RetentionRegistry retentionReg = context.getSessionImpl().getRetentionRegistry();
if ((options & CHECK_HOLD) == CHECK_HOLD) {
if (retentionReg.hasEffectiveHold(targetPath, true)) {
throw new RepositoryException("Unable to perform removal. Node is affected by a hold.");
}
}
if ((options & CHECK_RETENTION) == CHECK_RETENTION) {
if (retentionReg.hasEffectiveRetention(targetPath, true)) {
throw new RepositoryException("Unable to perform removal. Node is affected by a retention.");
}
}
}
Aggregations