use of org.apache.jackrabbit.core.NodeImpl in project jackrabbit by apache.
the class AddNodeOperation method perform.
public Node perform(SessionContext context) throws RepositoryException {
ItemManager itemMgr = context.getItemManager();
// Get the canonical path of the new node
Path path;
try {
path = PathFactoryImpl.getInstance().create(node.getPrimaryPath(), context.getQPath(relPath), true);
} catch (NameException e) {
throw new RepositoryException("Failed to resolve path " + relPath + " relative to " + node, e);
}
// Check that the last path element is a simple name
if (!path.denotesName() || path.getIndex() != Path.INDEX_UNDEFINED) {
throw new RepositoryException("Invalid last path element for adding node " + relPath + " relative to " + node);
}
// Get the parent node instance
NodeImpl parentNode;
Path parentPath = path.getAncestor(1);
try {
parentNode = itemMgr.getNode(parentPath);
} catch (PathNotFoundException e) {
if (itemMgr.propertyExists(parentPath)) {
throw new ConstraintViolationException("Unable to add a child node to property " + context.getJCRPath(parentPath));
}
throw e;
} catch (AccessDeniedException ade) {
throw new PathNotFoundException("Failed to resolve path " + relPath + " relative to " + node);
}
// Resolve node type name (if any)
Name typeName = null;
if (nodeTypeName != null) {
typeName = context.getQName(nodeTypeName);
}
// Check that the given UUID (if any) does not already exist
NodeId id = null;
if (uuid != null) {
id = new NodeId(uuid);
if (itemMgr.itemExists(id)) {
throw new ItemExistsException("A node with this UUID already exists: " + uuid);
}
}
return parentNode.addNode(path.getName(), typeName, id);
}
use of org.apache.jackrabbit.core.NodeImpl 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 org.apache.jackrabbit.core.NodeImpl in project jackrabbit by apache.
the class SessionImporter method createNode.
protected NodeImpl createNode(NodeImpl parent, Name nodeName, Name nodeTypeName, Name[] mixinNames, NodeId id) throws RepositoryException {
NodeImpl node;
// add node
node = parent.addNode(nodeName, nodeTypeName, id);
// add mixins
if (mixinNames != null) {
for (Name mixinName : mixinNames) {
node.addMixin(mixinName);
}
}
return node;
}
use of org.apache.jackrabbit.core.NodeImpl 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 {
// prevent same-name-sibling (we come here only if !def.allowsSameNameSiblings())
boolean sameId = existing.getId().equals(id);
if (!sameId || // (no other ImportUUIDBehaviour would result in same-name-sibling)
(sameId && uuidBehavior == ImportUUIDBehavior.IMPORT_UUID_CREATE_NEW)) {
throw new ItemExistsException("Same name sibling not allowed for " + existing + " by definition " + def.getName() + " (declaring type " + def.getDeclaringNodeType().getName() + ")");
}
// truth table for previous if statement (we come here only if names are same):
// same id | CREATE_NEW
// false | false => Exception: same name + different id would result in sibling
// false | true => Exception: same name + different id would result in sibling
// true | false => fall through: same name + same id, either replacing or removing original node or throwing exception
// true | true => Exception: same name + same id would result in sibling due to CREATE_NEW
}
}
}
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);
}
use of org.apache.jackrabbit.core.NodeImpl in project jackrabbit by apache.
the class XAEnvironment method removeLockToken.
/**
* Remove lock token from this environment.
* @param session
* @param lt lock token
* @throws RepositoryException
*/
public void removeLockToken(SessionImpl session, String lt) throws RepositoryException {
try {
NodeId id = LockInfo.parseLockToken(lt);
NodeImpl node = (NodeImpl) session.getItemManager().getItem(id);
LockInfo info = getLockInfo(node);
if (info != null) {
if (info.isLockHolder(session)) {
info.setLockHolder(null);
} else if (info.getLockHolder() != null) {
String msg = "Cannot remove lock token: lock held by other session.";
log.warn(msg);
throw new LockException(msg);
}
}
// inform SessionLockManager
getSessionLockManager(session).lockTokenRemoved(lt);
} catch (IllegalArgumentException e) {
String msg = "Bad lock token: " + e.getMessage();
log.warn(msg);
throw new LockException(msg);
}
}
Aggregations