use of org.apache.jackrabbit.spi.QNodeDefinition in project jackrabbit by apache.
the class EffectiveNodeType method getApplicableChildNodeDef.
/**
* Returns the applicable child node definition for a child node with the
* specified name and node type. If there are multiple applicable definitions
* named definitions will take precedence over residual definitions.
*
* @param name
* @param nodeTypeName
* @param ntReg
* @return
* @throws NoSuchNodeTypeException
* @throws ConstraintViolationException if no applicable child node definition
* could be found
*/
public QNodeDefinition getApplicableChildNodeDef(Name name, Name nodeTypeName, NodeTypeRegistry ntReg) throws NoSuchNodeTypeException, ConstraintViolationException {
EffectiveNodeType entTarget;
if (nodeTypeName != null) {
entTarget = ntReg.getEffectiveNodeType(nodeTypeName);
} else {
entTarget = null;
}
// try named node definitions first
QItemDefinition[] defs = getNamedItemDefs(name);
for (QItemDefinition def : defs) {
if (def.definesNode()) {
QNodeDefinition nd = (QNodeDefinition) def;
Name[] types = nd.getRequiredPrimaryTypes();
// node definition with that name exists
if (entTarget != null && types != null) {
// check 'required primary types' constraint
if (entTarget.includesNodeTypes(types)) {
// found named node definition
return nd;
}
} else if (nd.getDefaultPrimaryType() != null) {
// found node definition with default node type
return nd;
}
}
}
// no item with that name defined;
// try residual node definitions
QNodeDefinition[] nda = getUnnamedNodeDefs();
for (QNodeDefinition nd : nda) {
if (entTarget != null && nd.getRequiredPrimaryTypes() != null) {
// check 'required primary types' constraint
if (!entTarget.includesNodeTypes(nd.getRequiredPrimaryTypes())) {
continue;
}
// found residual node definition
return nd;
} else {
// it must be determined from the default node type;
if (nd.getDefaultPrimaryType() != null) {
// found residual node definition with default node type
return nd;
}
}
}
// no applicable definition found
throw new ConstraintViolationException("no matching child node definition found for " + name);
}
use of org.apache.jackrabbit.spi.QNodeDefinition in project jackrabbit by apache.
the class NodeTypeRegistryImpl method getEffectiveNodeType.
/**
* @see EffectiveNodeTypeProvider#getEffectiveNodeType(QNodeTypeDefinition, Map)
*/
public EffectiveNodeType getEffectiveNodeType(QNodeTypeDefinition ntd, Map<Name, QNodeTypeDefinition> ntdMap) throws ConstraintViolationException, NoSuchNodeTypeException {
TreeSet<Name> mergedNodeTypes = new TreeSet<Name>();
TreeSet<Name> inheritedNodeTypes = new TreeSet<Name>();
TreeSet<Name> allNodeTypes = new TreeSet<Name>();
Map<Name, List<QItemDefinition>> namedItemDefs = new HashMap<Name, List<QItemDefinition>>();
List<QItemDefinition> unnamedItemDefs = new ArrayList<QItemDefinition>();
Set<Name> supportedMixins = null;
Name ntName = ntd.getName();
// prepare new instance
mergedNodeTypes.add(ntName);
allNodeTypes.add(ntName);
Name[] smixins = ntd.getSupportedMixinTypes();
if (smixins != null) {
supportedMixins = new HashSet<Name>();
supportedMixins.addAll(Arrays.asList(smixins));
}
// 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> itemDefIds = new HashSet<QItemDefinition>();
for (QNodeDefinition nd : ntd.getChildNodeDefs()) {
// this node type definition
if (itemDefIds.contains(nd)) {
// conflict
String msg;
if (nd.definesResidual()) {
msg = ntName + " contains ambiguous residual child node definitions";
} else {
msg = ntName + " contains ambiguous definitions for child node named " + nd.getName();
}
log.debug(msg);
throw new ConstraintViolationException(msg);
} else {
itemDefIds.add(nd);
}
if (nd.definesResidual()) {
// residual node definition
unnamedItemDefs.add(nd);
} else {
// named node definition
Name name = nd.getName();
List<QItemDefinition> defs = namedItemDefs.get(name);
if (defs == null) {
defs = new ArrayList<QItemDefinition>();
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 qDef : defs) {
if (nd.isAutoCreated() || qDef.isAutoCreated()) {
// conflict
String msg = "There are more than one 'auto-create' item definitions for '" + name + "' in node type '" + ntName + "'";
log.debug(msg);
throw new ConstraintViolationException(msg);
}
}
}
defs.add(nd);
}
}
for (QPropertyDefinition pd : ntd.getPropertyDefs()) {
// this node type definition
if (itemDefIds.contains(pd)) {
// conflict
String msg;
if (pd.definesResidual()) {
msg = ntName + " contains ambiguous residual property definitions";
} else {
msg = ntName + " contains ambiguous definitions for property named " + pd.getName();
}
log.debug(msg);
throw new ConstraintViolationException(msg);
} else {
itemDefIds.add(pd);
}
if (pd.definesResidual()) {
// residual property definition
unnamedItemDefs.add(pd);
} else {
// named property definition
Name name = pd.getName();
List<QItemDefinition> defs = namedItemDefs.get(name);
if (defs == null) {
defs = new ArrayList<QItemDefinition>();
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 qDef : defs) {
if (pd.isAutoCreated() || qDef.isAutoCreated()) {
// conflict
String msg = "There are more than one 'auto-create' item definitions for '" + name + "' in node type '" + ntName + "'";
log.debug(msg);
throw new ConstraintViolationException(msg);
}
}
}
defs.add(pd);
}
}
// create empty effective node type instance
EffectiveNodeTypeImpl ent = new EffectiveNodeTypeImpl(mergedNodeTypes, inheritedNodeTypes, allNodeTypes, namedItemDefs, unnamedItemDefs, supportedMixins);
// resolve supertypes recursively
Name[] supertypes = ntd.getSupertypes();
if (supertypes.length > 0) {
EffectiveNodeTypeImpl effSuperType = (EffectiveNodeTypeImpl) getEffectiveNodeType(supertypes, ntdMap);
ent.internalMerge(effSuperType, true);
}
return ent;
}
use of org.apache.jackrabbit.spi.QNodeDefinition in project jackrabbit by apache.
the class NodeTypeDefinitionFactory method create.
/**
* Create a new JCR node type definition from the given
* <code>QNodeTypeDefinition</code>.
*
* @param qNtd A SPI node type definition.
* @return the corresponding JCR node type definition.
* @throws RepositoryException if an error occurs.
*/
@SuppressWarnings("unchecked")
public NodeTypeDefinition create(QNodeTypeDefinition qNtd) throws RepositoryException {
NodeTypeTemplate nt = ntMgr.createNodeTypeTemplate();
nt.setName(getJCRName(qNtd.getName()));
nt.setDeclaredSuperTypeNames(getJCRNames(qNtd.getSupertypes()));
nt.setAbstract(qNtd.isAbstract());
nt.setMixin(qNtd.isMixin());
nt.setOrderableChildNodes(qNtd.hasOrderableChildNodes());
nt.setPrimaryItemName(getJCRName(qNtd.getPrimaryItemName()));
nt.setQueryable(qNtd.isQueryable());
List nodeDefs = nt.getNodeDefinitionTemplates();
for (QNodeDefinition qNd : qNtd.getChildNodeDefs()) {
nodeDefs.add(create(qNd));
}
List propDefs = nt.getPropertyDefinitionTemplates();
for (QPropertyDefinition qPd : qNtd.getPropertyDefs()) {
propDefs.add(create(qPd));
}
return nt;
}
use of org.apache.jackrabbit.spi.QNodeDefinition in project jackrabbit by apache.
the class NodeState method retrieveDefinition.
private QNodeDefinition retrieveDefinition() throws RepositoryException {
QNodeDefinition def;
if (isRoot()) {
def = definitionProvider.getRootNodeDefinition();
} else {
/*
Don't use getAllNodeTypeNames() to retrieve the definition:
for NEW-states the definition is always set upon creation.
for all other states the definition must be retrieved only taking
the effective nodetypes present on the parent into account
any kind of transiently added mixins must not have an effect
on the definition retrieved for an state that has been persisted
before. The effective NT must be evaluated as if it had been
evaluated upon creating the workspace state.
*/
NodeState parent = getParent();
NodeId wspId = (NodeId) getWorkspaceId();
def = definitionProvider.getQNodeDefinition(parent.getNodeTypeNames(), getName(), getNodeTypeName(), wspId);
}
return def;
}
use of org.apache.jackrabbit.spi.QNodeDefinition in project jackrabbit by apache.
the class SessionItemStateManager method addNodeState.
private List<ItemState> addNodeState(NodeState parent, Name nodeName, Name nodeTypeName, String uuid, QNodeDefinition definition, int options) throws RepositoryException, ConstraintViolationException, AccessDeniedException, UnsupportedRepositoryOperationException, NoSuchNodeTypeException, ItemExistsException, VersionException {
// check if add node is possible. note, that the options differ if
// the 'addNode' is called from inside a regular add-node to create
// autocreated child nodes that may be 'protected'.
validator.checkAddNode(parent, nodeName, nodeTypeName, options);
// a new NodeState doesn't have mixins defined yet -> ent is ent of primarytype
EffectiveNodeType ent = mgrProvider.getEffectiveNodeTypeProvider().getEffectiveNodeType(nodeTypeName);
if (nodeTypeName == null) {
// no primary node type specified,
// try default primary type from definition
nodeTypeName = definition.getDefaultPrimaryType();
if (nodeTypeName == null) {
String msg = "No applicable node type could be determined for " + nodeName;
log.debug(msg);
throw new ConstraintViolationException(msg);
}
}
List<ItemState> addedStates = new ArrayList<ItemState>();
// create new nodeState. NOTE, that the uniqueID is not added to the
// state for consistency between 'addNode' and importXML
NodeState nodeState = transientStateMgr.createNewNodeState(nodeName, null, nodeTypeName, definition, parent);
addedStates.add(nodeState);
if (uuid != null) {
QValue[] value = getQValues(uuid, qValueFactory);
ItemDefinitionProvider defProvider = mgrProvider.getItemDefinitionProvider();
QPropertyDefinition pDef = defProvider.getQPropertyDefinition(NameConstants.MIX_REFERENCEABLE, NameConstants.JCR_UUID, PropertyType.STRING, false);
addedStates.add(addPropertyState(nodeState, NameConstants.JCR_UUID, PropertyType.STRING, value, pDef, 0));
}
// add 'auto-create' properties defined in node type
for (QPropertyDefinition pd : ent.getAutoCreateQPropertyDefinitions()) {
if (!nodeState.hasPropertyName(pd.getName())) {
QValue[] autoValue = computeSystemGeneratedPropertyValues(nodeState, pd);
if (autoValue != null) {
int propOptions = ItemStateValidator.CHECK_NONE;
// execute 'addProperty' without adding operation.
addedStates.add(addPropertyState(nodeState, pd.getName(), pd.getRequiredType(), autoValue, pd, propOptions));
}
}
}
// recursively add 'auto-create' child nodes defined in node type
for (QNodeDefinition nd : ent.getAutoCreateQNodeDefinitions()) {
// execute 'addNode' without adding the operation.
int opt = ItemStateValidator.CHECK_LOCK | ItemStateValidator.CHECK_COLLISION;
addedStates.addAll(addNodeState(nodeState, nd.getName(), nd.getDefaultPrimaryType(), null, nd, opt));
}
return addedStates;
}
Aggregations