Search in sources :

Example 11 with QNodeDefinition

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);
}
Also used : ConstraintViolationException(javax.jcr.nodetype.ConstraintViolationException) QItemDefinition(org.apache.jackrabbit.spi.QItemDefinition) QNodeDefinition(org.apache.jackrabbit.spi.QNodeDefinition) Name(org.apache.jackrabbit.spi.Name)

Example 12 with QNodeDefinition

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;
}
Also used : HashMap(java.util.HashMap) ArrayList(java.util.ArrayList) QItemDefinition(org.apache.jackrabbit.spi.QItemDefinition) QNodeDefinition(org.apache.jackrabbit.spi.QNodeDefinition) Name(org.apache.jackrabbit.spi.Name) TreeSet(java.util.TreeSet) QPropertyDefinition(org.apache.jackrabbit.spi.QPropertyDefinition) ConstraintViolationException(javax.jcr.nodetype.ConstraintViolationException) ArrayList(java.util.ArrayList) List(java.util.List) HashSet(java.util.HashSet)

Example 13 with QNodeDefinition

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;
}
Also used : NodeTypeTemplate(javax.jcr.nodetype.NodeTypeTemplate) QPropertyDefinition(org.apache.jackrabbit.spi.QPropertyDefinition) ArrayList(java.util.ArrayList) List(java.util.List) QNodeDefinition(org.apache.jackrabbit.spi.QNodeDefinition)

Example 14 with QNodeDefinition

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;
}
Also used : NodeId(org.apache.jackrabbit.spi.NodeId) QNodeDefinition(org.apache.jackrabbit.spi.QNodeDefinition)

Example 15 with QNodeDefinition

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;
}
Also used : QValue(org.apache.jackrabbit.spi.QValue) ArrayList(java.util.ArrayList) QNodeDefinition(org.apache.jackrabbit.spi.QNodeDefinition) EffectiveNodeType(org.apache.jackrabbit.jcr2spi.nodetype.EffectiveNodeType) QPropertyDefinition(org.apache.jackrabbit.spi.QPropertyDefinition) ConstraintViolationException(javax.jcr.nodetype.ConstraintViolationException) ItemDefinitionProvider(org.apache.jackrabbit.jcr2spi.nodetype.ItemDefinitionProvider)

Aggregations

QNodeDefinition (org.apache.jackrabbit.spi.QNodeDefinition)45 Name (org.apache.jackrabbit.spi.Name)25 QPropertyDefinition (org.apache.jackrabbit.spi.QPropertyDefinition)19 ConstraintViolationException (javax.jcr.nodetype.ConstraintViolationException)16 QItemDefinition (org.apache.jackrabbit.spi.QItemDefinition)9 QValueConstraint (org.apache.jackrabbit.spi.QValueConstraint)9 ArrayList (java.util.ArrayList)7 RepositoryException (javax.jcr.RepositoryException)7 EffectiveNodeType (org.apache.jackrabbit.core.nodetype.EffectiveNodeType)7 NodeId (org.apache.jackrabbit.core.id.NodeId)6 NodeState (org.apache.jackrabbit.core.state.NodeState)6 ItemExistsException (javax.jcr.ItemExistsException)5 ChildNodeEntry (org.apache.jackrabbit.core.state.ChildNodeEntry)5 HashSet (java.util.HashSet)4 ItemNotFoundException (javax.jcr.ItemNotFoundException)4 NoSuchNodeTypeException (javax.jcr.nodetype.NoSuchNodeTypeException)4 ItemStateException (org.apache.jackrabbit.core.state.ItemStateException)4 QValue (org.apache.jackrabbit.spi.QValue)4 ValueConstraint (org.apache.jackrabbit.spi.commons.nodetype.constraint.ValueConstraint)4 NodeDefinition (javax.jcr.nodetype.NodeDefinition)3