use of javax.jcr.ItemExistsException in project jackrabbit by apache.
the class WorkspaceImporter method processProperty.
protected void processProperty(NodeState node, PropInfo pInfo) throws RepositoryException {
PropertyState prop;
QPropertyDefinition def;
Name name = pInfo.getName();
int type = pInfo.getType();
if (node.hasPropertyName(name)) {
// a property with that name already exists...
PropertyId idExisting = new PropertyId(node.getNodeId(), name);
prop = (PropertyState) itemOps.getItemState(idExisting);
def = itemOps.findApplicablePropertyDefinition(prop.getName(), prop.getType(), prop.isMultiValued(), node);
if (def.isProtected()) {
// skip protected property
log.debug("skipping protected property " + itemOps.safeGetJCRPath(idExisting));
return;
}
if (!def.isAutoCreated() || (prop.getType() != type && type != PropertyType.UNDEFINED) || def.isMultiple() != prop.isMultiValued()) {
throw new ItemExistsException(itemOps.safeGetJCRPath(prop.getPropertyId()));
}
} else {
// there's no property with that name,
// find applicable definition
def = pInfo.getApplicablePropertyDef(itemOps.getEffectiveNodeType(node));
if (def.isProtected()) {
// skip protected property
log.debug("skipping protected property " + name);
return;
}
// create new property
prop = itemOps.createPropertyState(node, name, type, def);
}
// check multi-valued characteristic
TextValue[] values = pInfo.getTextValues();
if (values.length != 1 && !def.isMultiple()) {
throw new ConstraintViolationException(itemOps.safeGetJCRPath(prop.getPropertyId()) + " is not multi-valued");
}
// convert serialized values to InternalValue objects
int targetType = pInfo.getTargetType(def);
InternalValue[] iva = new InternalValue[values.length];
for (int i = 0; i < values.length; i++) {
iva[i] = values[i].getInternalValue(targetType);
}
// set values
prop.setValues(iva);
// make sure property is valid according to its definition
itemOps.validate(prop);
if (prop.getType() == PropertyType.REFERENCE || prop.getType() == PropertyType.WEAKREFERENCE) {
// store reference for later resolution
refTracker.processedReference(prop);
}
// store property
itemOps.store(prop);
}
use of javax.jcr.ItemExistsException in project jackrabbit by apache.
the class SessionImporter method resolveUUIDConflict.
protected NodeImpl resolveUUIDConflict(NodeImpl parent, NodeId conflictingId, NodeInfo nodeInfo) throws RepositoryException {
NodeImpl node;
NodeImpl conflicting;
try {
conflicting = session.getNodeById(conflictingId);
} catch (ItemNotFoundException infe) {
// conflicting node can't be read,
// most likely due to lack of read permission
conflicting = null;
}
if (uuidBehavior == ImportUUIDBehavior.IMPORT_UUID_CREATE_NEW) {
// create new with new uuid
checkPermission(parent, nodeInfo.getName());
node = createNode(parent, nodeInfo.getName(), nodeInfo.getNodeTypeName(), nodeInfo.getMixinNames(), null);
// remember uuid mapping
if (node.isNodeType(NameConstants.MIX_REFERENCEABLE)) {
refTracker.mappedId(nodeInfo.getId(), node.getNodeId());
}
} else if (uuidBehavior == ImportUUIDBehavior.IMPORT_UUID_COLLISION_THROW) {
// if conflicting node is shareable, then clone it
if (conflicting != null && conflicting.isNodeType(NameConstants.MIX_SHAREABLE)) {
parent.clone(conflicting, nodeInfo.getName());
return null;
}
String msg = "a node with uuid " + nodeInfo.getId() + " already exists!";
log.debug(msg);
throw new ItemExistsException(msg);
} else if (uuidBehavior == ImportUUIDBehavior.IMPORT_UUID_COLLISION_REMOVE_EXISTING) {
if (conflicting == null) {
// since the conflicting node can't be read,
// we can't remove it
String msg = "node with uuid " + conflictingId + " cannot be removed";
log.debug(msg);
throw new RepositoryException(msg);
}
// make sure conflicting node is not importTargetNode or an ancestor thereof
if (importTargetNode.getPath().startsWith(conflicting.getPath())) {
String msg = "cannot remove ancestor node";
log.debug(msg);
throw new ConstraintViolationException(msg);
}
// remove conflicting
conflicting.remove();
// create new with given uuid
checkPermission(parent, nodeInfo.getName());
node = createNode(parent, nodeInfo.getName(), nodeInfo.getNodeTypeName(), nodeInfo.getMixinNames(), nodeInfo.getId());
} else if (uuidBehavior == ImportUUIDBehavior.IMPORT_UUID_COLLISION_REPLACE_EXISTING) {
if (conflicting == null) {
// since the conflicting node can't be read,
// we can't replace it
String msg = "node with uuid " + conflictingId + " cannot be replaced";
log.debug(msg);
throw new RepositoryException(msg);
}
if (conflicting.getDepth() == 0) {
String msg = "root node cannot be replaced";
log.debug(msg);
throw new RepositoryException(msg);
}
// 'replace' current parent with parent of conflicting
parent = (NodeImpl) conflicting.getParent();
// replace child node
checkPermission(parent, nodeInfo.getName());
node = parent.replaceChildNode(nodeInfo.getId(), nodeInfo.getName(), nodeInfo.getNodeTypeName(), nodeInfo.getMixinNames());
} else {
String msg = "unknown uuidBehavior: " + uuidBehavior;
log.debug(msg);
throw new RepositoryException(msg);
}
return node;
}
use of javax.jcr.ItemExistsException in project jackrabbit by apache.
the class WorkspaceImporter method startNode.
/**
* {@inheritDoc}
*/
public void startNode(NodeInfo nodeInfo, List<PropInfo> propInfos) throws RepositoryException {
if (aborted) {
// the import has been aborted, get outta here...
return;
}
boolean succeeded = false;
NodeState parent;
try {
// check sanity of workspace/session first
wsp.sanityCheck();
parent = parents.peek();
// process node
NodeState node = null;
NodeId id = nodeInfo.getId();
Name nodeName = nodeInfo.getName();
Name ntName = nodeInfo.getNodeTypeName();
Name[] mixins = nodeInfo.getMixinNames();
if (parent == null) {
// parent node was skipped, skip this child node too
// push null onto stack for skipped node
parents.push(null);
succeeded = true;
log.debug("skipping node " + nodeName);
return;
}
if (parent.hasChildNodeEntry(nodeName)) {
// a node with that name already exists...
ChildNodeEntry entry = parent.getChildNodeEntry(nodeName, 1);
NodeId idExisting = entry.getId();
NodeState existing = (NodeState) itemOps.getItemState(idExisting);
QNodeDefinition def = itemOps.findApplicableNodeDefinition(nodeName, existing.getNodeTypeName(), parent);
if (!def.allowsSameNameSiblings()) {
// existing doesn't allow same-name siblings,
// check for potential conflicts
EffectiveNodeType entExisting = itemOps.getEffectiveNodeType(existing);
if (def.isProtected() && entExisting.includesNodeType(ntName)) {
// skip protected node
// push null onto stack for skipped node
parents.push(null);
succeeded = true;
log.debug("skipping protected node " + itemOps.safeGetJCRPath(existing.getNodeId()));
return;
}
if (def.isAutoCreated() && entExisting.includesNodeType(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 (!(idExisting.equals(id) && (uuidBehavior == ImportUUIDBehavior.IMPORT_UUID_COLLISION_REMOVE_EXISTING || uuidBehavior == ImportUUIDBehavior.IMPORT_UUID_COLLISION_REPLACE_EXISTING))) {
throw new ItemExistsException(itemOps.safeGetJCRPath(existing.getNodeId()));
}
// fall through
}
}
}
if (node == null) {
// there's no node with that name...
if (id == null) {
// no potential uuid conflict, always create new node
QNodeDefinition def = itemOps.findApplicableNodeDefinition(nodeName, ntName, parent);
if (def.isProtected()) {
// skip protected node
// push null onto stack for skipped node
parents.push(null);
succeeded = true;
log.debug("skipping protected node " + nodeName);
return;
}
// check if new node can be added (check access rights &
// node type constraints only, assume locking & versioning status
// and retention/hold has already been checked on ancestor)
itemOps.checkAddNode(parent, nodeName, ntName, BatchedItemOperations.CHECK_ACCESS | BatchedItemOperations.CHECK_CONSTRAINTS);
// do create new node
node = itemOps.createNodeState(parent, nodeName, ntName, mixins, null, def);
} else {
// potential uuid conflict
try {
NodeState conflicting = itemOps.getNodeState(id);
// resolve uuid conflict
node = resolveUUIDConflict(parent, conflicting, nodeInfo);
if (node == null) {
// no new node has been created, so skip this node
// push null onto stack for skipped node
parents.push(null);
succeeded = true;
log.debug("skipping existing node: " + nodeName);
return;
}
} catch (ItemNotFoundException e) {
// create new with given uuid
QNodeDefinition def = itemOps.findApplicableNodeDefinition(nodeName, ntName, parent);
if (def.isProtected()) {
// skip protected node
// push null onto stack for skipped node
parents.push(null);
succeeded = true;
log.debug("skipping protected node " + nodeName);
return;
}
// check if new node can be added (check access rights &
// node type constraints only, assume locking & versioning status
// and retention/hold has already been checked on ancestor)
itemOps.checkAddNode(parent, nodeName, ntName, BatchedItemOperations.CHECK_ACCESS | BatchedItemOperations.CHECK_CONSTRAINTS);
// do create new node
node = itemOps.createNodeState(parent, nodeName, ntName, mixins, id, def);
}
}
}
// process properties
for (PropInfo propInfo : propInfos) {
processProperty(node, propInfo);
}
// store affected nodes
itemOps.store(node);
itemOps.store(parent);
// push current node onto stack of parents
parents.push(node);
succeeded = true;
} finally {
if (!succeeded) {
// update operation failed, cancel all modifications
aborted = true;
itemOps.cancel();
}
}
}
use of javax.jcr.ItemExistsException in project jackrabbit by apache.
the class LockTest method testUnlockSameNameSibling.
/**
* Tests if unlocking the first of two locked same-name sibling nodes does
* not unlock the second (JIRA issue JCR-284).
*/
public void testUnlockSameNameSibling() throws RepositoryException, NotExecutableException {
Session session = testRootNode.getSession();
Node n1, n2;
try {
// create two same-name sibling nodes
n1 = testRootNode.addNode(nodeName1, testNodeType);
n2 = testRootNode.addNode(nodeName1, testNodeType);
session.save();
} catch (ItemExistsException ex) {
throw new NotExecutableException("Node does not seem to allow same name siblings");
}
ensureMixinType(n1, mixLockable);
ensureMixinType(n2, mixLockable);
session.save();
// lock both nodes
n1.lock(true, true);
n2.lock(true, true);
// assert: both nodes are locked
assertTrue("First node locked: ", n1.isLocked());
assertTrue("Second node locked: ", n2.isLocked());
// unlock first sibling
n1.unlock();
// assert: first node unlocked, second node still locked
assertFalse("First node unlocked: ", n1.isLocked());
assertTrue("Second node locked: ", n2.isLocked());
}
use of javax.jcr.ItemExistsException in project jackrabbit by apache.
the class BatchedItemOperations method checkAddNode.
//--------------------------------------< misc. high-level helper methods >
/**
* Checks if adding a child node called <code>nodeName</code> of node type
* <code>nodeTypeName</code> to the given parent node is allowed in the
* current context.
*
* @param parentState
* @param nodeName
* @param nodeTypeName
* @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 & write access on
* parent 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_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 ItemExistsException
* @throws RepositoryException
*/
public void checkAddNode(NodeState parentState, Name nodeName, Name nodeTypeName, int options) throws ConstraintViolationException, AccessDeniedException, VersionException, LockException, ItemNotFoundException, ItemExistsException, RepositoryException {
Path parentPath = hierMgr.getPath(parentState.getNodeId());
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) {
AccessManager accessMgr = context.getAccessManager();
// make sure current session is granted read access on parent node
if (!accessMgr.isGranted(parentPath, Permission.READ)) {
throw new ItemNotFoundException(safeGetJCRPath(parentState.getNodeId()));
}
// make sure current session is granted write access on parent node
if (!accessMgr.isGranted(parentPath, nodeName, Permission.ADD_NODE)) {
throw new AccessDeniedException(safeGetJCRPath(parentState.getNodeId()) + ": not allowed to add child node");
}
// specified node type (and ev. mixins)
if (!accessMgr.isGranted(parentPath, nodeName, Permission.NODE_TYPE_MNGMT)) {
throw new AccessDeniedException(safeGetJCRPath(parentState.getNodeId()) + ": not allowed to add child node");
}
}
if ((options & CHECK_CONSTRAINTS) == CHECK_CONSTRAINTS) {
QItemDefinition parentDef = context.getItemManager().getDefinition(parentState).unwrap();
// make sure parent node is not protected
if (parentDef.isProtected()) {
throw new ConstraintViolationException(safeGetJCRPath(parentState.getNodeId()) + ": cannot add child node to protected parent node");
}
// make sure there's an applicable definition for new child node
EffectiveNodeType entParent = getEffectiveNodeType(parentState);
entParent.checkAddNodeConstraints(nodeName, nodeTypeName, context.getNodeTypeRegistry());
QNodeDefinition newNodeDef = findApplicableNodeDefinition(nodeName, nodeTypeName, parentState);
// check for name collisions
if (parentState.hasChildNodeEntry(nodeName)) {
// there's already a node with that name...
// get definition of existing conflicting node
ChildNodeEntry entry = parentState.getChildNodeEntry(nodeName, 1);
NodeState conflictingState;
NodeId conflictingId = entry.getId();
try {
conflictingState = (NodeState) stateMgr.getItemState(conflictingId);
} catch (ItemStateException ise) {
String msg = "internal error: failed to retrieve state of " + safeGetJCRPath(conflictingId);
log.debug(msg);
throw new RepositoryException(msg, ise);
}
QNodeDefinition conflictingTargetDef = context.getItemManager().getDefinition(conflictingState).unwrap();
// check same-name sibling setting of both target and existing node
if (!conflictingTargetDef.allowsSameNameSiblings() || !newNodeDef.allowsSameNameSiblings()) {
throw new ItemExistsException("cannot add child node '" + nodeName.getLocalName() + "' to " + safeGetJCRPath(parentState.getNodeId()) + ": colliding with same-named existing node");
}
}
}
RetentionRegistry retentionReg = context.getSessionImpl().getRetentionRegistry();
if ((options & CHECK_HOLD) == CHECK_HOLD) {
if (retentionReg.hasEffectiveHold(parentPath, false)) {
throw new RepositoryException("Unable to add node. Parent is affected by a hold.");
}
}
if ((options & CHECK_RETENTION) == CHECK_RETENTION) {
if (retentionReg.hasEffectiveRetention(parentPath, false)) {
throw new RepositoryException("Unable to add node. Parent is affected by a retention.");
}
}
}
Aggregations