Search in sources :

Example 36 with QPropertyDefinition

use of org.apache.jackrabbit.spi.QPropertyDefinition 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 {
                // (see http://issues.apache.org/jira/browse/JCR-1128)
                if (!(existing.getId().equals(id) && (uuidBehavior == ImportUUIDBehavior.IMPORT_UUID_COLLISION_REMOVE_EXISTING || uuidBehavior == ImportUUIDBehavior.IMPORT_UUID_COLLISION_REPLACE_EXISTING))) {
                    throw new ItemExistsException("Node with the same UUID exists:" + existing);
                }
            // fall through
            }
        }
    }
    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);
}
Also used : NodeImpl(org.apache.jackrabbit.core.NodeImpl) NodeDefinition(javax.jcr.nodetype.NodeDefinition) Name(org.apache.jackrabbit.spi.Name) ItemExistsException(javax.jcr.ItemExistsException) QPropertyDefinition(org.apache.jackrabbit.spi.QPropertyDefinition) NodeId(org.apache.jackrabbit.core.id.NodeId) ItemNotFoundException(javax.jcr.ItemNotFoundException)

Example 37 with QPropertyDefinition

use of org.apache.jackrabbit.spi.QPropertyDefinition 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);
}
Also used : ItemExistsException(javax.jcr.ItemExistsException) QPropertyDefinition(org.apache.jackrabbit.spi.QPropertyDefinition) ConstraintViolationException(javax.jcr.nodetype.ConstraintViolationException) InternalValue(org.apache.jackrabbit.core.value.InternalValue) PropertyState(org.apache.jackrabbit.core.state.PropertyState) Name(org.apache.jackrabbit.spi.Name) PropertyId(org.apache.jackrabbit.core.id.PropertyId)

Example 38 with QPropertyDefinition

use of org.apache.jackrabbit.spi.QPropertyDefinition in project jackrabbit by apache.

the class ItemManager method getDefinition.

PropertyDefinitionImpl getDefinition(PropertyState state) throws RepositoryException {
    // see also: JCR-2408
    if (state.getStatus() == ItemState.STATUS_EXISTING_REMOVED && state.getName().equals(NameConstants.JCR_UUID)) {
        NodeTypeRegistry ntReg = sessionContext.getNodeTypeRegistry();
        QPropertyDefinition def = ntReg.getEffectiveNodeType(NameConstants.MIX_REFERENCEABLE).getApplicablePropertyDef(state.getName(), state.getType());
        return sessionContext.getNodeTypeManager().getPropertyDefinition(def);
    }
    try {
        // retrieve parent in 2 steps in order to avoid the check for
        // read permissions on the parent which isn't required in order
        // to read the property's definition. see also JCR-2418.
        ItemData parentData = getItemData(state.getParentId(), null, false);
        NodeImpl parent = (NodeImpl) createItemInstance(parentData);
        return parent.getApplicablePropertyDefinition(state.getName(), state.getType(), state.isMultiValued(), true);
    } catch (ItemNotFoundException e) {
    // parent probably removed, get it from attic
    }
    try {
        NodeState parent = (NodeState) sism.getAttic().getItemState(state.getParentId()).getOverlayedState();
        NodeTypeRegistry ntReg = sessionContext.getNodeTypeRegistry();
        EffectiveNodeType ent = ntReg.getEffectiveNodeType(parent.getNodeTypeName(), parent.getMixinTypeNames());
        QPropertyDefinition def;
        try {
            def = ent.getApplicablePropertyDef(state.getName(), state.getType(), state.isMultiValued());
        } catch (ConstraintViolationException e) {
            ent = ntReg.getEffectiveNodeType(NameConstants.NT_UNSTRUCTURED);
            def = ent.getApplicablePropertyDef(state.getName(), state.getType(), state.isMultiValued());
            log.warn("Fallback to nt:unstructured due to unknown property " + "definition for '" + state.getName() + "'");
        }
        return sessionContext.getNodeTypeManager().getPropertyDefinition(def);
    } catch (ItemStateException e) {
        throw new RepositoryException(e);
    } catch (NodeTypeConflictException e) {
        throw new RepositoryException(e);
    }
}
Also used : EffectiveNodeType(org.apache.jackrabbit.core.nodetype.EffectiveNodeType) NodeState(org.apache.jackrabbit.core.state.NodeState) QPropertyDefinition(org.apache.jackrabbit.spi.QPropertyDefinition) NodeTypeConflictException(org.apache.jackrabbit.core.nodetype.NodeTypeConflictException) ConstraintViolationException(javax.jcr.nodetype.ConstraintViolationException) NodeTypeRegistry(org.apache.jackrabbit.core.nodetype.NodeTypeRegistry) RepositoryException(javax.jcr.RepositoryException) ItemNotFoundException(javax.jcr.ItemNotFoundException) NoSuchItemStateException(org.apache.jackrabbit.core.state.NoSuchItemStateException) InvalidItemStateException(javax.jcr.InvalidItemStateException) ItemStateException(org.apache.jackrabbit.core.state.ItemStateException)

Example 39 with QPropertyDefinition

use of org.apache.jackrabbit.spi.QPropertyDefinition in project jackrabbit by apache.

the class QueryImpl method getColumns.

/**
     * Returns the columns for this query.
     *
     * @return array of columns.
     * @throws RepositoryException if an error occurs.
     */
protected ColumnImpl[] getColumns() throws RepositoryException {
    SessionImpl session = sessionContext.getSessionImpl();
    QueryObjectModelFactory qomFactory = session.getWorkspace().getQueryManager().getQOMFactory();
    // get columns
    Map<Name, ColumnImpl> columns = new LinkedHashMap<Name, ColumnImpl>();
    for (Name name : root.getSelectProperties()) {
        String pn = sessionContext.getJCRName(name);
        ColumnImpl col = (ColumnImpl) qomFactory.column(sessionContext.getJCRName(DEFAULT_SELECTOR_NAME), pn, pn);
        columns.put(name, col);
    }
    if (columns.size() == 0) {
        // use node type constraint
        LocationStepQueryNode[] steps = root.getLocationNode().getPathSteps();
        final Name[] ntName = new Name[1];
        steps[steps.length - 1].acceptOperands(new DefaultQueryNodeVisitor() {

            public Object visit(AndQueryNode node, Object data) throws RepositoryException {
                return node.acceptOperands(this, data);
            }

            public Object visit(NodeTypeQueryNode node, Object data) {
                ntName[0] = node.getValue();
                return data;
            }
        }, null);
        if (ntName[0] == null) {
            ntName[0] = NameConstants.NT_BASE;
        }
        NodeTypeImpl nt = session.getNodeTypeManager().getNodeType(ntName[0]);
        PropertyDefinition[] propDefs = nt.getPropertyDefinitions();
        for (PropertyDefinition pd : propDefs) {
            QPropertyDefinition propDef = ((PropertyDefinitionImpl) pd).unwrap();
            if (!propDef.definesResidual() && !propDef.isMultiple()) {
                columns.put(propDef.getName(), columnForName(propDef.getName()));
            }
        }
    }
    // add jcr:path and jcr:score if not selected already
    if (!columns.containsKey(NameConstants.JCR_PATH)) {
        columns.put(NameConstants.JCR_PATH, columnForName(NameConstants.JCR_PATH));
    }
    if (!columns.containsKey(NameConstants.JCR_SCORE)) {
        columns.put(NameConstants.JCR_SCORE, columnForName(NameConstants.JCR_SCORE));
    }
    return columns.values().toArray(new ColumnImpl[columns.size()]);
}
Also used : NodeTypeImpl(org.apache.jackrabbit.core.nodetype.NodeTypeImpl) LocationStepQueryNode(org.apache.jackrabbit.spi.commons.query.LocationStepQueryNode) PropertyDefinitionImpl(org.apache.jackrabbit.spi.commons.nodetype.PropertyDefinitionImpl) RepositoryException(javax.jcr.RepositoryException) QPropertyDefinition(org.apache.jackrabbit.spi.QPropertyDefinition) PropertyDefinition(javax.jcr.nodetype.PropertyDefinition) LinkedHashMap(java.util.LinkedHashMap) Name(org.apache.jackrabbit.spi.Name) QPropertyDefinition(org.apache.jackrabbit.spi.QPropertyDefinition) SessionImpl(org.apache.jackrabbit.core.SessionImpl) QueryObjectModelFactory(javax.jcr.query.qom.QueryObjectModelFactory) ColumnImpl(org.apache.jackrabbit.spi.commons.query.qom.ColumnImpl) DefaultQueryNodeVisitor(org.apache.jackrabbit.spi.commons.query.DefaultQueryNodeVisitor) NodeTypeQueryNode(org.apache.jackrabbit.spi.commons.query.NodeTypeQueryNode) AndQueryNode(org.apache.jackrabbit.spi.commons.query.AndQueryNode)

Example 40 with QPropertyDefinition

use of org.apache.jackrabbit.spi.QPropertyDefinition in project jackrabbit by apache.

the class NodeTypeRegistry method validateNodeTypeDef.

/**
     * Validates the specified <code>NodeTypeDef</code> within the context of
     * the two other given collections and returns an <code>EffectiveNodeType</code>.
     *
     * @param ntd node type definition
     * @param entCache effective node type cache
     * @param ntdCache cache of 'known' node type definitions, used to resolve dependencies
     * @param nsReg    namespace registry used for validatingatch names
     * @param lenient flag governing whether validation can be lenient or has to be strict
     * @return an effective node type representation of the specified <code>QNodeTypeDefinition</code>
     * @throws InvalidNodeTypeDefException if the node type is not valid
     * @throws RepositoryException         if another error occurs
     */
private static EffectiveNodeType validateNodeTypeDef(QNodeTypeDefinition ntd, EffectiveNodeTypeCache entCache, Map<Name, QNodeTypeDefinition> ntdCache, NamespaceRegistry nsReg, boolean lenient) throws InvalidNodeTypeDefException, RepositoryException {
    /**
         * the effective (i.e. merged and resolved) node type resulting from
         * the specified node type definition;
         * the effective node type will finally be created after the definition
         * has been verified and checked for conflicts etc.; in some cases it
         * will be created already at an earlier stage during the validation
         * of child node definitions
         */
    EffectiveNodeType ent = null;
    Name name = ntd.getName();
    if (name == null) {
        String msg = "no name specified";
        log.debug(msg);
        throw new InvalidNodeTypeDefException(msg);
    }
    checkNamespace(name, nsReg);
    // validate supertypes
    Name[] supertypes = ntd.getSupertypes();
    if (supertypes.length > 0) {
        for (Name supertype : supertypes) {
            checkNamespace(supertype, nsReg);
            /**
                 * simple check for infinite recursion
                 * (won't trap recursion on a deeper inheritance level)
                 */
            if (name.equals(supertype)) {
                String msg = "[" + name + "] invalid supertype: " + supertype + " (infinite recursion))";
                log.debug(msg);
                throw new InvalidNodeTypeDefException(msg);
            }
            if (!ntdCache.containsKey(supertype)) {
                String msg = "[" + name + "] invalid supertype: " + supertype;
                log.debug(msg);
                throw new InvalidNodeTypeDefException(msg);
            }
        }
        /**
             * check for circularity in inheritance chain
             * ('a' extends 'b' extends 'a')
             */
        Stack<Name> inheritanceChain = new Stack<Name>();
        inheritanceChain.push(name);
        checkForCircularInheritance(supertypes, inheritanceChain, ntdCache);
    }
    /**
         * build effective (i.e. merged and resolved) node type from supertypes
         * and check for conflicts
         */
    if (supertypes.length > 0) {
        try {
            EffectiveNodeType est = getEffectiveNodeType(supertypes, entCache, ntdCache);
            // a supertypes's primaryItem -> illegal (JCR-1947)
            if (ntd.getPrimaryItemName() != null && est.getPrimaryItemName() != null) {
                String msg = "[" + name + "] primaryItemName is already specified by a supertype and must therefore not be overridden.";
                log.debug(msg);
                throw new InvalidNodeTypeDefException(msg);
            }
        } catch (NodeTypeConflictException ntce) {
            String msg = "[" + name + "] failed to validate supertypes";
            log.debug(msg);
            throw new InvalidNodeTypeDefException(msg, ntce);
        } catch (NoSuchNodeTypeException nsnte) {
            String msg = "[" + name + "] failed to validate supertypes";
            log.debug(msg);
            throw new InvalidNodeTypeDefException(msg, nsnte);
        }
    }
    checkNamespace(ntd.getPrimaryItemName(), nsReg);
    // validate property definitions
    QPropertyDefinition[] pda = ntd.getPropertyDefs();
    for (QPropertyDefinition pd : pda) {
        /**
             * sanity check:
             * make sure declaring node type matches name of node type definition
             */
        if (!name.equals(pd.getDeclaringNodeType())) {
            String msg = "[" + name + "#" + pd.getName() + "] invalid declaring node type specified";
            log.debug(msg);
            throw new InvalidNodeTypeDefException(msg);
        }
        checkNamespace(pd.getName(), nsReg);
        // check that auto-created properties specify a name
        if (pd.definesResidual() && pd.isAutoCreated()) {
            String msg = "[" + name + "#" + pd.getName() + "] auto-created properties must specify a name";
            log.debug(msg);
            throw new InvalidNodeTypeDefException(msg);
        }
        // check that auto-created properties specify a type
        if (pd.getRequiredType() == PropertyType.UNDEFINED && pd.isAutoCreated()) {
            String msg = "[" + name + "#" + pd.getName() + "] auto-created properties must specify a type";
            log.debug(msg);
            throw new InvalidNodeTypeDefException(msg);
        }
        /**
             * check default values:
             * make sure type of value is consistent with required property type
             */
        QValue[] defVals = pd.getDefaultValues();
        if (defVals != null && defVals.length != 0) {
            int reqType = pd.getRequiredType();
            for (QValue defVal : defVals) {
                if (reqType == PropertyType.UNDEFINED) {
                    reqType = defVal.getType();
                } else {
                    if (defVal.getType() != reqType) {
                        String msg = "[" + name + "#" + pd.getName() + "] type of default value(s) is not consistent with required property type";
                        log.debug(msg);
                        throw new InvalidNodeTypeDefException(msg);
                    }
                }
            }
        } else {
            // no default values specified
            if (!lenient) {
                // auto-created properties must have a default value
                if (pd.isAutoCreated()) {
                    String msg = "[" + name + "#" + pd.getName() + "] auto-created property must have a default value";
                    log.debug(msg);
                    throw new InvalidNodeTypeDefException(msg);
                }
            }
        }
        // check that default values satisfy value constraints
        QValueConstraint[] constraints = pd.getValueConstraints();
        if (constraints != null && constraints.length > 0) {
            if (defVals != null && defVals.length > 0) {
                // check value constraints on every value
                for (QValue defVal : defVals) {
                    // constraints are OR-ed together
                    boolean satisfied = false;
                    ConstraintViolationException cve = null;
                    for (QValueConstraint constraint : constraints) {
                        try {
                            constraint.check(defVal);
                            // at least one constraint is satisfied
                            satisfied = true;
                            break;
                        } catch (ConstraintViolationException e) {
                            cve = e;
                        }
                    }
                    if (!satisfied) {
                        // report last exception we encountered
                        String msg = "[" + name + "#" + pd.getName() + "] default value does not satisfy value constraint";
                        log.debug(msg);
                        throw new InvalidNodeTypeDefException(msg, cve);
                    }
                }
            }
            /**
                 * ReferenceConstraint:
                 * the specified node type must be registered, with one notable
                 * exception: the node type just being registered
                 */
            if (pd.getRequiredType() == PropertyType.REFERENCE || pd.getRequiredType() == PropertyType.WEAKREFERENCE) {
                for (QValueConstraint constraint : constraints) {
                    Name ntName = NameFactoryImpl.getInstance().create(constraint.getString());
                    if (!name.equals(ntName) && !ntdCache.containsKey(ntName)) {
                        String msg = "[" + name + "#" + pd.getName() + "] invalid " + (pd.getRequiredType() == PropertyType.REFERENCE ? "REFERENCE" : "WEAKREFERENCE") + " value constraint '" + ntName + "' (unknown node type)";
                        log.debug(msg);
                        throw new InvalidNodeTypeDefException(msg);
                    }
                }
            }
        }
    }
    // validate child-node definitions
    QNodeDefinition[] cnda = ntd.getChildNodeDefs();
    for (QNodeDefinition cnd : cnda) {
        /**
             * sanity check:
             * make sure declaring node type matches name of node type definition
             */
        if (!name.equals(cnd.getDeclaringNodeType())) {
            String msg = "[" + name + "#" + cnd.getName() + "] invalid declaring node type specified";
            log.debug(msg);
            throw new InvalidNodeTypeDefException(msg);
        }
        checkNamespace(cnd.getName(), nsReg);
        // check that auto-created child-nodes specify a name
        if (cnd.definesResidual() && cnd.isAutoCreated()) {
            String msg = "[" + name + "#" + cnd.getName() + "] auto-created child-nodes must specify a name";
            log.debug(msg);
            throw new InvalidNodeTypeDefException(msg);
        }
        // check that auto-created child-nodes specify a default primary type
        if (cnd.getDefaultPrimaryType() == null && cnd.isAutoCreated()) {
            String msg = "[" + name + "#" + cnd.getName() + "] auto-created child-nodes must specify a default primary type";
            log.debug(msg);
            throw new InvalidNodeTypeDefException(msg);
        }
        // check default primary type
        Name dpt = cnd.getDefaultPrimaryType();
        checkNamespace(dpt, nsReg);
        boolean referenceToSelf = false;
        EffectiveNodeType defaultENT = null;
        if (dpt != null) {
            // check if this node type specifies itself as default primary type
            if (name.equals(dpt)) {
                referenceToSelf = true;
            }
            /**
                 * the default primary type must be registered, with one notable
                 * exception: the node type just being registered
                 */
            if (!name.equals(dpt) && !ntdCache.containsKey(dpt)) {
                String msg = "[" + name + "#" + cnd.getName() + "] invalid default primary type '" + dpt + "'";
                log.debug(msg);
                throw new InvalidNodeTypeDefException(msg);
            }
            /**
                 * build effective (i.e. merged and resolved) node type from
                 * default primary type and check for conflicts
                 */
            try {
                if (!referenceToSelf) {
                    defaultENT = getEffectiveNodeType(dpt, entCache, ntdCache);
                } else {
                    /**
                         * the default primary type is identical with the node
                         * type just being registered; we have to instantiate it
                         * 'manually'
                         */
                    ent = EffectiveNodeType.create(ntd, entCache, ntdCache);
                    defaultENT = ent;
                }
                if (cnd.isAutoCreated()) {
                    /**
                         * check for circularity through default primary types
                         * of auto-created child nodes (node type 'a' defines
                         * auto-created child node with default primary type 'a')
                         */
                    Stack<Name> definingNTs = new Stack<Name>();
                    definingNTs.push(name);
                    checkForCircularNodeAutoCreation(defaultENT, definingNTs, entCache, ntdCache);
                }
            } catch (NodeTypeConflictException ntce) {
                String msg = "[" + name + "#" + cnd.getName() + "] failed to validate default primary type";
                log.debug(msg);
                throw new InvalidNodeTypeDefException(msg, ntce);
            } catch (NoSuchNodeTypeException nsnte) {
                String msg = "[" + name + "#" + cnd.getName() + "] failed to validate default primary type";
                log.debug(msg);
                throw new InvalidNodeTypeDefException(msg, nsnte);
            }
        }
        // check required primary types
        Name[] reqTypes = cnd.getRequiredPrimaryTypes();
        if (reqTypes != null && reqTypes.length > 0) {
            for (Name rpt : reqTypes) {
                // skip nt:base required types
                if (NameConstants.NT_BASE.equals(rpt)) {
                    continue;
                }
                checkNamespace(rpt, nsReg);
                referenceToSelf = false;
                /**
                     * check if this node type specifies itself as required
                     * primary type
                     */
                if (name.equals(rpt)) {
                    referenceToSelf = true;
                }
                /**
                     * the required primary type must be registered, with one
                     * notable exception: the node type just being registered
                     */
                if (!name.equals(rpt) && !ntdCache.containsKey(rpt)) {
                    String msg = "[" + name + "#" + cnd.getName() + "] invalid required primary type: " + rpt;
                    log.debug(msg);
                    throw new InvalidNodeTypeDefException(msg);
                }
                /**
                     * check if default primary type satisfies the required
                     * primary type constraint
                     */
                if (defaultENT != null && !defaultENT.includesNodeType(rpt)) {
                    String msg = "[" + name + "#" + cnd.getName() + "] default primary type does not satisfy required primary type constraint " + rpt;
                    log.debug(msg);
                    throw new InvalidNodeTypeDefException(msg);
                }
                /**
                     * build effective (i.e. merged and resolved) node type from
                     * required primary type constraint and check for conflicts
                     */
                try {
                    if (!referenceToSelf) {
                        getEffectiveNodeType(rpt, entCache, ntdCache);
                    } else {
                        /**
                             * the required primary type is identical with the
                             * node type just being registered; we have to
                             * instantiate it 'manually'
                             */
                        if (ent == null) {
                            ent = EffectiveNodeType.create(ntd, entCache, ntdCache);
                        }
                    }
                } catch (NodeTypeConflictException ntce) {
                    String msg = "[" + name + "#" + cnd.getName() + "] failed to validate required primary type constraint";
                    log.debug(msg);
                    throw new InvalidNodeTypeDefException(msg, ntce);
                } catch (NoSuchNodeTypeException nsnte) {
                    String msg = "[" + name + "#" + cnd.getName() + "] failed to validate required primary type constraint";
                    log.debug(msg);
                    throw new InvalidNodeTypeDefException(msg, nsnte);
                }
            }
        }
    }
    /**
         * now build effective (i.e. merged and resolved) node type from
         * this node type definition; this will potentially detect more
         * conflicts or problems
         */
    if (ent == null) {
        try {
            ent = EffectiveNodeType.create(ntd, entCache, ntdCache);
        } catch (NodeTypeConflictException ntce) {
            String msg = "[" + name + "] failed to resolve node type definition";
            log.debug(msg);
            throw new InvalidNodeTypeDefException(msg, ntce);
        } catch (NoSuchNodeTypeException nsnte) {
            String msg = "[" + name + "] failed to resolve node type definition";
            log.debug(msg);
            throw new InvalidNodeTypeDefException(msg, nsnte);
        }
    }
    return ent;
}
Also used : QValue(org.apache.jackrabbit.spi.QValue) QValueConstraint(org.apache.jackrabbit.spi.QValueConstraint) QNodeDefinition(org.apache.jackrabbit.spi.QNodeDefinition) QValueConstraint(org.apache.jackrabbit.spi.QValueConstraint) Name(org.apache.jackrabbit.spi.Name) Stack(java.util.Stack) NoSuchNodeTypeException(javax.jcr.nodetype.NoSuchNodeTypeException) QPropertyDefinition(org.apache.jackrabbit.spi.QPropertyDefinition) ConstraintViolationException(javax.jcr.nodetype.ConstraintViolationException)

Aggregations

QPropertyDefinition (org.apache.jackrabbit.spi.QPropertyDefinition)81 Name (org.apache.jackrabbit.spi.Name)32 ConstraintViolationException (javax.jcr.nodetype.ConstraintViolationException)22 QNodeDefinition (org.apache.jackrabbit.spi.QNodeDefinition)19 RepositoryException (javax.jcr.RepositoryException)14 QValue (org.apache.jackrabbit.spi.QValue)12 QItemDefinition (org.apache.jackrabbit.spi.QItemDefinition)9 QValueConstraint (org.apache.jackrabbit.spi.QValueConstraint)9 ArrayList (java.util.ArrayList)8 Value (javax.jcr.Value)7 InternalValue (org.apache.jackrabbit.core.value.InternalValue)7 ItemExistsException (javax.jcr.ItemExistsException)6 NodeId (org.apache.jackrabbit.core.id.NodeId)6 PropertyDefinition (javax.jcr.nodetype.PropertyDefinition)5 EffectiveNodeType (org.apache.jackrabbit.core.nodetype.EffectiveNodeType)5 PropertyState (org.apache.jackrabbit.core.state.PropertyState)5 QNodeTypeDefinition (org.apache.jackrabbit.spi.QNodeTypeDefinition)5 ValueConstraint (org.apache.jackrabbit.spi.commons.nodetype.constraint.ValueConstraint)5 NodeState (org.apache.jackrabbit.core.state.NodeState)4 NameException (org.apache.jackrabbit.spi.commons.conversion.NameException)4