use of javax.jcr.ItemExistsException in project jackrabbit by apache.
the class SessionMoveOperation method perform.
public Object perform(SessionContext context) throws RepositoryException {
// Get node instances
NodeImpl targetNode = getNode(context, srcPath, srcAbsPath);
NodeImpl srcParentNode = getNode(context, srcPath.getAncestor(1), srcAbsPath);
NodeImpl destParentNode = getNode(context, destPath.getAncestor(1), destAbsPath);
if (context.getHierarchyManager().isShareAncestor(targetNode.getNodeId(), destParentNode.getNodeId())) {
throw new RepositoryException("Move not possible because of a share cycle between " + srcAbsPath + " and " + destAbsPath);
}
// check for name collisions
NodeImpl existing = null;
try {
existing = context.getItemManager().getNode(destPath);
// check same-name sibling setting of existing node
if (!existing.getDefinition().allowsSameNameSiblings()) {
throw new ItemExistsException("Same name siblings are not allowed: " + existing);
}
} catch (AccessDeniedException ade) {
// FIXME by throwing ItemExistsException we're disclosing too much information
throw new ItemExistsException(destAbsPath);
} catch (PathNotFoundException pnfe) {
// no name collision, fall through
}
// verify that the targetNode can be removed
int options = ItemValidator.CHECK_HOLD | ItemValidator.CHECK_RETENTION;
context.getItemValidator().checkRemove(targetNode, options, Permission.NONE);
// verify for both source and destination parent nodes that
// - they are checked-out
// - are not protected neither by node type constraints nor by retention/hold
options = ItemValidator.CHECK_CHECKED_OUT | ItemValidator.CHECK_LOCK | ItemValidator.CHECK_CONSTRAINTS | ItemValidator.CHECK_HOLD | ItemValidator.CHECK_RETENTION;
context.getItemValidator().checkModify(srcParentNode, options, Permission.NONE);
context.getItemValidator().checkModify(destParentNode, options, Permission.NONE);
// check constraints
// get applicable definition of target node at new location
NodeTypeImpl nt = (NodeTypeImpl) targetNode.getPrimaryNodeType();
org.apache.jackrabbit.spi.commons.nodetype.NodeDefinitionImpl newTargetDef;
try {
newTargetDef = destParentNode.getApplicableChildNodeDefinition(destPath.getName(), nt.getQName());
} catch (RepositoryException re) {
String msg = destAbsPath + ": no definition found in parent node's node type for new node";
log.debug(msg);
throw new ConstraintViolationException(msg, re);
}
// necessarily have identical definitions
if (existing != null && !newTargetDef.allowsSameNameSiblings()) {
throw new ItemExistsException("Same name siblings not allowed: " + existing);
}
NodeId targetId = targetNode.getNodeId();
// check permissions
AccessManager acMgr = context.getAccessManager();
if (!(acMgr.isGranted(srcPath, Permission.REMOVE_NODE) && acMgr.isGranted(destPath, Permission.ADD_NODE | Permission.NODE_TYPE_MNGMT))) {
String msg = "Not allowed to move node " + srcAbsPath + " to " + destAbsPath;
log.debug(msg);
throw new AccessDeniedException(msg);
}
if (srcParentNode.isSame(destParentNode)) {
// change definition of target
targetNode.onRedefine(newTargetDef.unwrap());
// do rename
destParentNode.renameChildNode(targetId, destPath.getName(), false);
} else {
// check shareable case
if (targetNode.getNodeState().isShareable()) {
String msg = "Moving a shareable node is not supported.";
log.debug(msg);
throw new UnsupportedRepositoryOperationException(msg);
}
// change definition of target
targetNode.onRedefine(newTargetDef.unwrap());
// Get the transient states
NodeState srcParentState = (NodeState) srcParentNode.getOrCreateTransientItemState();
NodeState targetState = (NodeState) targetNode.getOrCreateTransientItemState();
NodeState destParentState = (NodeState) destParentNode.getOrCreateTransientItemState();
// 1. remove child node entry from old parent
if (srcParentState.removeChildNodeEntry(targetId)) {
// 2. re-parent target node
targetState.setParentId(destParentNode.getNodeId());
// 3. add child node entry to new parent
destParentState.addChildNodeEntry(destPath.getName(), targetId);
}
}
return this;
}
use of javax.jcr.ItemExistsException in project jackrabbit by apache.
the class WorkspaceMoveSameNameSibsTest method testMoveNodesNodeExistsAtDestPath.
/**
* An ItemExistsException is thrown if a node or property already exists at
* destAbsPath.
* <ul>
* <li>{@code sameNameSibsFalseNodeType} name of a node type that does not
* allows same name siblings.
* <li>{@code nodeName3} name of a child node that does not allow same name
* siblings..
* </ul>
*/
public void testMoveNodesNodeExistsAtDestPath() throws RepositoryException {
// create a parent node where allowSameNameSiblings are set to false
Node snsfNode = testRootNode.addNode(nodeName3, sameNameSibsFalseNodeType.getName());
testRootNode.getSession().save();
String dstAbsPath = snsfNode.getPath() + "/" + node1.getName();
workspace.copy(node1.getPath(), dstAbsPath);
// property already exist
try {
workspace.move(node1.getPath(), dstAbsPath);
fail("Node exists below '" + dstAbsPath + "'. Test should fail.");
} catch (ItemExistsException e) {
// successful
}
}
use of javax.jcr.ItemExistsException in project jackrabbit by apache.
the class WorkspaceCopyBetweenWorkspacesSameNameSibsTest method testCopyNodesNodeExistsAtDestPath.
/**
* An ItemExistsException is thrown if a node or property already exists at
* destAbsPath.
* <ul>
* <li>{@code sameNameSibsFalseNodeType} name of a node type that does not
* allows same name siblings.
* <li>{@code nodeName3} name of a child node that does not allow same name
* siblings..
* </ul>
*/
public void testCopyNodesNodeExistsAtDestPath() throws RepositoryException {
// create a parent node where allowSameNameSiblings are set to false
Node snsfNode = testRootNodeW2.addNode(nodeName3, sameNameSibsFalseNodeType.getName());
testRootNodeW2.save();
String dstAbsPath = snsfNode.getPath() + "/" + node1.getName();
workspaceW2.copy(node1.getPath(), dstAbsPath);
// property already exist
try {
workspaceW2.copy(workspace.getName(), node1.getPath(), dstAbsPath);
fail("Node exists below '" + dstAbsPath + "'. Test should fail.");
} catch (ItemExistsException e) {
// successful
}
}
use of javax.jcr.ItemExistsException in project jackrabbit by apache.
the class WorkspaceCopySameNameSibsTest method testCopyNodesNodeExistsAtDestPath.
/**
* An ItemExistsException is thrown if a node or property already exists at
* destAbsPath.
* <ul>
* <li>{@code sameNameSibsFalseNodeType} name of a node type that does not
* allows same name siblings.
* <li>{@code nodeName3} name of a child node that does not allow same name
* siblings..
* </ul>
*/
public void testCopyNodesNodeExistsAtDestPath() throws RepositoryException {
// create a parent node where allowSameNameSiblings are set to false
Node snsfNode = testRootNode.addNode(nodeName3, sameNameSibsFalseNodeType.getName());
testRootNode.getSession().save();
String dstAbsPath = snsfNode.getPath() + "/" + node1.getName();
workspace.copy(node1.getPath(), dstAbsPath);
// try to copy again the node to same destAbsPath where node already exists
try {
workspace.copy(node1.getPath(), dstAbsPath);
fail("Node exists below '" + dstAbsPath + "'. Test should fail.");
} catch (ItemExistsException e) {
// successful
}
}
use of javax.jcr.ItemExistsException in project jackrabbit by apache.
the class SessionImporter method startNode.
/**
* {@inheritDoc}
*/
public void startNode(NodeInfo nodeInfo, List<PropInfo> propInfos) throws RepositoryException {
NodeImpl parent = parents.peek();
// process node
NodeImpl node = null;
NodeId id = nodeInfo.getId();
Name nodeName = nodeInfo.getName();
Name ntName = nodeInfo.getNodeTypeName();
Name[] mixins = nodeInfo.getMixinNames();
if (parent == null) {
log.debug("Skipping node: " + nodeName);
// parent node was skipped, skip this child node too
// push null onto stack for skipped node
parents.push(null);
// notify the p-i-importer
if (pnImporter != null) {
pnImporter.startChildInfo(nodeInfo, propInfos);
}
return;
}
if (parent.getDefinition().isProtected()) {
// skip protected node
parents.push(null);
log.debug("Skipping protected node: " + nodeName);
if (pnImporter != null) {
// pnImporter was already started (current nodeInfo is a sibling)
// notify it about this child node.
pnImporter.startChildInfo(nodeInfo, propInfos);
} else {
// potentially is able to deal with it, notify it about the child node.
for (ProtectedItemImporter pni : pItemImporters) {
if (pni instanceof ProtectedNodeImporter && ((ProtectedNodeImporter) pni).start(parent)) {
log.debug("Protected node -> delegated to ProtectedNodeImporter");
pnImporter = (ProtectedNodeImporter) pni;
pnImporter.startChildInfo(nodeInfo, propInfos);
break;
}
/* else: p-i-Importer isn't able to deal with the protected tree.
try next. and if none can handle the passed parent the
tree below will be skipped */
}
}
return;
}
if (parent.hasNode(nodeName)) {
// a node with that name already exists...
NodeImpl existing = parent.getNode(nodeName);
NodeDefinition def = existing.getDefinition();
if (!def.allowsSameNameSiblings()) {
// check for potential conflicts
if (def.isProtected() && existing.isNodeType(ntName)) {
/*
use the existing node as parent for the possible subsequent
import of a protected tree, that the protected node importer
may or may not be able to deal with.
-> upon the next 'startNode' the check for the parent being
protected will notify the protected node importer.
-> if the importer is able to deal with that node it needs
to care of the complete subtree until it is notified
during the 'endNode' call.
-> if the import can't deal with that node or if that node
is the a leaf in the tree to be imported 'end' will
not have an effect on the importer, that was never started.
*/
log.debug("Skipping protected node: " + existing);
parents.push(existing);
return;
}
if (def.isAutoCreated() && existing.isNodeType(ntName)) {
// this node has already been auto-created, no need to create it
node = existing;
} else {
// (see http://issues.apache.org/jira/browse/JCR-1128)
if (!(existing.getId().equals(id) && (uuidBehavior == ImportUUIDBehavior.IMPORT_UUID_COLLISION_REMOVE_EXISTING || uuidBehavior == ImportUUIDBehavior.IMPORT_UUID_COLLISION_REPLACE_EXISTING))) {
throw new ItemExistsException("Node with the same UUID exists:" + existing);
}
// fall through
}
}
}
if (node == null) {
// create node
if (id == null) {
// no potential uuid conflict, always add new node
checkPermission(parent, nodeName);
node = createNode(parent, nodeName, ntName, mixins, null);
} else {
// potential uuid conflict
boolean isConflicting;
try {
// the following is a fail-fast test whether
// an item exists (regardless of access control)
session.getHierarchyManager().getName(id);
isConflicting = true;
} catch (ItemNotFoundException infe) {
isConflicting = false;
}
if (isConflicting) {
// resolve uuid conflict
node = resolveUUIDConflict(parent, id, nodeInfo);
if (node == null) {
// no new node has been created, so skip this node
// push null onto stack for skipped node
parents.push(null);
log.debug("Skipping existing node " + nodeInfo.getName());
return;
}
} else {
// create new with given uuid
checkPermission(parent, nodeName);
node = createNode(parent, nodeName, ntName, mixins, id);
}
}
}
for (PropInfo pi : propInfos) {
// find applicable definition
QPropertyDefinition def = pi.getApplicablePropertyDef(node.getEffectiveNodeType());
if (def.isProtected()) {
// skip protected property
log.debug("Skipping protected property " + pi.getName());
// notify the ProtectedPropertyImporter.
for (ProtectedItemImporter ppi : pItemImporters) {
if (ppi instanceof ProtectedPropertyImporter && ((ProtectedPropertyImporter) ppi).handlePropInfo(node, pi, def)) {
log.debug("Protected property -> delegated to ProtectedPropertyImporter");
break;
}
/* else: p-i-Importer isn't able to deal with this property.
try next pp-importer */
}
} else {
// regular property -> create the property
createProperty(node, pi, def);
}
}
parents.push(node);
}
Aggregations