use of org.apache.jackrabbit.spi.QNodeDefinition in project jackrabbit by apache.
the class EffectiveNodeType method create.
/**
* Package private factory method.
* <p>
* Creates an effective node type representation of a node type definition.
* Note that the definitions of all referenced node types must be contained
* in <code>ntdCache</code>.
*
* @param ntd node type definition
* @param entCache cache of already-built effective node types
* @param ntdCache cache of node type definitions, used to resolve dependencies
* @return an effective node type representation of the given node type definition.
* @throws NodeTypeConflictException if the node type definition is invalid,
* e.g. due to ambiguous child definitions.
* @throws NoSuchNodeTypeException if a node type reference (e.g. a supertype)
* could not be resolved.
*/
static EffectiveNodeType create(QNodeTypeDefinition ntd, EffectiveNodeTypeCache entCache, Map<Name, QNodeTypeDefinition> ntdCache) throws NodeTypeConflictException, NoSuchNodeTypeException {
// create empty effective node type instance
EffectiveNodeType ent = new EffectiveNodeType();
Name ntName = ntd.getName();
// prepare new instance
ent.mergedNodeTypes.add(ntName);
ent.allNodeTypes.add(ntName);
// map of all item definitions (maps id to definition)
// used to effectively detect ambiguous child definitions where
// ambiguity is defined in terms of definition identity
Set<QItemDefinition> itemDefs = new HashSet<QItemDefinition>();
QNodeDefinition[] cnda = ntd.getChildNodeDefs();
for (QNodeDefinition aCnda : cnda) {
// this node type definition
if (itemDefs.contains(aCnda)) {
// conflict
String msg;
if (aCnda.definesResidual()) {
msg = ntName + " contains ambiguous residual child node definitions";
} else {
msg = ntName + " contains ambiguous definitions for child node named " + aCnda.getName();
}
log.debug(msg);
throw new NodeTypeConflictException(msg);
} else {
itemDefs.add(aCnda);
}
if (aCnda.definesResidual()) {
// residual node definition
ent.unnamedItemDefs.add(aCnda);
} else {
// named node definition
Name name = aCnda.getName();
List<QItemDefinition> defs = ent.namedItemDefs.get(name);
if (defs == null) {
defs = new ArrayList<QItemDefinition>();
ent.namedItemDefs.put(name, defs);
}
if (defs.size() > 0) {
/**
* there already exists at least one definition with that
* name; make sure none of them is auto-create
*/
for (QItemDefinition def : defs) {
if (aCnda.isAutoCreated() || def.isAutoCreated()) {
// conflict
String msg = "There are more than one 'auto-create' item definitions for '" + name + "' in node type '" + ntName + "'";
log.debug(msg);
throw new NodeTypeConflictException(msg);
}
}
}
defs.add(aCnda);
}
}
QPropertyDefinition[] pda = ntd.getPropertyDefs();
for (QPropertyDefinition aPda : pda) {
// this node type definition
if (itemDefs.contains(aPda)) {
// conflict
String msg;
if (aPda.definesResidual()) {
msg = ntName + " contains ambiguous residual property definitions";
} else {
msg = ntName + " contains ambiguous definitions for property named " + aPda.getName();
}
log.debug(msg);
throw new NodeTypeConflictException(msg);
} else {
itemDefs.add(aPda);
}
if (aPda.definesResidual()) {
// residual property definition
ent.unnamedItemDefs.add(aPda);
} else {
// named property definition
Name name = aPda.getName();
List<QItemDefinition> defs = ent.namedItemDefs.get(name);
if (defs == null) {
defs = new ArrayList<QItemDefinition>();
ent.namedItemDefs.put(name, defs);
}
if (defs.size() > 0) {
/**
* there already exists at least one definition with that
* name; make sure none of them is auto-create
*/
for (QItemDefinition def : defs) {
if (aPda.isAutoCreated() || def.isAutoCreated()) {
// conflict
String msg = "There are more than one 'auto-create' item definitions for '" + name + "' in node type '" + ntName + "'";
log.debug(msg);
throw new NodeTypeConflictException(msg);
}
}
}
defs.add(aPda);
}
}
// resolve supertypes recursively
Name[] supertypes = ntd.getSupertypes();
if (supertypes.length > 0) {
EffectiveNodeType base = NodeTypeRegistry.getEffectiveNodeType(supertypes, entCache, ntdCache);
ent.internalMerge(base, true);
}
// resolve 'orderable child nodes' attribute value (JCR-1947)
if (ntd.hasOrderableChildNodes()) {
ent.orderableChildNodes = true;
} else {
Name[] nta = ent.getInheritedNodeTypes();
for (Name aNta : nta) {
QNodeTypeDefinition def = ntdCache.get(aNta);
if (def.hasOrderableChildNodes()) {
ent.orderableChildNodes = true;
break;
}
}
}
// resolve 'primary item' attribute value (JCR-1947)
if (ntd.getPrimaryItemName() != null) {
ent.primaryItemName = ntd.getPrimaryItemName();
} else {
Name[] nta = ent.getInheritedNodeTypes();
for (Name aNta : nta) {
QNodeTypeDefinition def = ntdCache.get(aNta);
if (def.getPrimaryItemName() != null) {
ent.primaryItemName = def.getPrimaryItemName();
break;
}
}
}
// we're done
return ent;
}
use of org.apache.jackrabbit.spi.QNodeDefinition in project jackrabbit by apache.
the class EffectiveNodeType method getNamedNodeDefs.
public QNodeDefinition[] getNamedNodeDefs(Name name) {
List<QItemDefinition> list = namedItemDefs.get(name);
if (list == null || list.size() == 0) {
return QNodeDefinition.EMPTY_ARRAY;
}
ArrayList<QNodeDefinition> defs = new ArrayList<QNodeDefinition>(list.size());
for (QItemDefinition def : list) {
if (def.definesNode()) {
defs.add((QNodeDefinition) def);
}
}
if (defs.size() == 0) {
return QNodeDefinition.EMPTY_ARRAY;
}
return defs.toArray(new QNodeDefinition[defs.size()]);
}
use of org.apache.jackrabbit.spi.QNodeDefinition 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 org.apache.jackrabbit.spi.QNodeDefinition in project jackrabbit by apache.
the class NodeImpl method createNode.
// ---------------------------------------------< private implementation >---
/**
* Create a new <code>NodeState</code> and subsequently retrieves the
* corresponding <code>Node</code> object.
*
* @param nodeName name of the new node
* @param nodeTypeName name of the new node's node type or <code>null</code>
* if it should be determined automatically
* @return the newly added node
* @throws ItemExistsException
* @throws NoSuchNodeTypeException
* @throws VersionException
* @throws ConstraintViolationException
* @throws LockException
* @throws RepositoryException
*/
private synchronized Node createNode(Name nodeName, Name nodeTypeName) throws ItemExistsException, NoSuchNodeTypeException, VersionException, ConstraintViolationException, LockException, RepositoryException {
QNodeDefinition definition = session.getItemDefinitionProvider().getQNodeDefinition(getNodeState().getAllNodeTypeNames(), nodeName, nodeTypeName);
if (nodeTypeName == null) {
// use default node type
nodeTypeName = definition.getDefaultPrimaryType();
}
// validation check are performed by item state manager
// NOTE: uuid is generated while creating new state.
Operation an = AddNode.create(getNodeState(), nodeName, nodeTypeName, null);
session.getSessionItemStateManager().execute(an);
// finally retrieve the new node
List<ItemState> addedStates = ((AddNode) an).getAddedStates();
ItemState nState = addedStates.get(0);
return (Node) getItemManager().getItem(nState.getHierarchyEntry());
}
use of org.apache.jackrabbit.spi.QNodeDefinition in project jackrabbit by apache.
the class NodeImpl method getDefinition.
/**
* @see Node#getDefinition()
*/
public NodeDefinition getDefinition() throws RepositoryException {
checkStatus();
QNodeDefinition qnd = getNodeState().getDefinition();
return session.getNodeTypeManager().getNodeDefinition(qnd);
}
Aggregations