Package org.apache.jackrabbit.core.nodetype

Examples of org.apache.jackrabbit.core.nodetype.NodeTypeManagerImpl


            throws ItemExistsException, PathNotFoundException,
            ConstraintViolationException, NoSuchNodeTypeException,
            RepositoryException {

        // get frozen node type
        NodeTypeManagerImpl ntMgr = session.getNodeTypeManager();
        NodeTypeImpl nt = ntMgr.getNodeType(frozen.getFrozenPrimaryType());

        // get frozen id
        NodeId id = frozen.getFrozenId();

        NodeImpl node = internalAddChildNode(name, nt, id);
View Full Code Here


            throws ItemExistsException, PathNotFoundException,
            ConstraintViolationException, NoSuchNodeTypeException,
            RepositoryException {

        // get frozen node type
        NodeTypeManagerImpl ntMgr = session.getNodeTypeManager();
        NodeTypeImpl nt = ntMgr.getNodeType(frozen.getFrozenPrimaryType());

        // get frozen id
        NodeId id = frozen.getFrozenId();

        NodeImpl node = internalAddNode(relPath, nt, id);
View Full Code Here

                }
            }
        }

        // add 'auto-create' properties that do not exist yet
        NodeTypeManagerImpl ntMgr = session.getNodeTypeManager();
        for (Name mixinName : mixinNames) {
            NodeTypeImpl mixin = ntMgr.getNodeType(mixinName);
            PropertyDefinition[] pda = mixin.getAutoCreatedPropertyDefinitions();
            for (PropertyDefinition aPda : pda) {
                PropertyDefinitionImpl pd = (PropertyDefinitionImpl) aPda;
                if (!hasProperty(pd.getQName())) {
                    createChildProperty(pd.getQName(), pd.getRequiredType(), pd);
View Full Code Here

        if (ntName.equals(state.getNodeTypeName())) {
            log.debug("Node already has " + nodeTypeName + " as primary node type.");
            return;
        }

        NodeTypeManagerImpl ntMgr = session.getNodeTypeManager();
        NodeType nt = ntMgr.getNodeType(ntName);
        if (nt.isMixin()) {
            throw new ConstraintViolationException(nodeTypeName + ": not a primary node type.");
        } else if (nt.isAbstract()) {
            throw new ConstraintViolationException(nodeTypeName + ": is an abstract node type.");
        }

        // build effective node type of new primary type & existing mixin's
        // in order to detect conflicts
        NodeTypeRegistry ntReg = ntMgr.getNodeTypeRegistry();
        EffectiveNodeType entNew, entOld, entAll;
        try {
            entNew = ntReg.getEffectiveNodeType(ntName);
            entOld = ntReg.getEffectiveNodeType(state.getNodeTypeName());

            // try to build new effective node type (will throw in case of conflicts)
            entAll = ntReg.getEffectiveNodeType(ntName, state.getMixinTypeNames());
        } catch (NodeTypeConflictException ntce) {
            throw new ConstraintViolationException(ntce.getMessage());
        }

        // get applicable definition for this node using new primary type
        NodeDefId defId;
        try {
            NodeImpl parent = (NodeImpl) getParent();
            defId = parent.getApplicableChildNodeDefinition(getQName(), ntName).unwrap().getId();
        } catch (RepositoryException re) {
            String msg = this + ": no applicable definition found in parent node's node type";
            log.debug(msg);
            throw new ConstraintViolationException(msg, re);
        }

        if (!defId.equals(state.getDefinitionId())) {
            onRedefine(defId);
        }

        Set<ItemDef> oldDefs = new HashSet<ItemDef>(Arrays.asList(entOld.getAllItemDefs()));
        Set<ItemDef> newDefs = new HashSet<ItemDef>(Arrays.asList(entNew.getAllItemDefs()));
        Set<ItemDef> allDefs = new HashSet<ItemDef>(Arrays.asList(entAll.getAllItemDefs()));

        // added child item definitions
        Set<ItemDef> addedDefs = new HashSet<ItemDef>(newDefs);
        addedDefs.removeAll(oldDefs);

        // referential integrity check
        boolean referenceableOld = entOld.includesNodeType(NameConstants.MIX_REFERENCEABLE);
        boolean referenceableNew = entNew.includesNodeType(NameConstants.MIX_REFERENCEABLE);
        if (referenceableOld && !referenceableNew) {
            // node would become non-referenceable;
            // make sure no references exist
            PropertyIterator iter = getReferences();
            if (iter.hasNext()) {
                throw new ConstraintViolationException(
                        "the new primary type cannot be set as it would render "
                                + "this node 'non-referenceable' while it is still being "
                                + "referenced through at least one property of type REFERENCE");
            }
        }

        // do the actual modifications in content as mandated by the new primary type

        // modify the state of this node
        NodeState thisState = (NodeState) getOrCreateTransientItemState();
        thisState.setNodeTypeName(ntName);

        // set jcr:primaryType property
        internalSetProperty(NameConstants.JCR_PRIMARYTYPE, InternalValue.create(ntName));

        // walk through properties and child nodes and change definition as necessary

        // use temp set to avoid ConcurrentModificationException
        HashSet<Name> set = new HashSet<Name>(thisState.getPropertyNames());
        for (Name propName : set) {
            try {
                PropertyState propState =
                        (PropertyState) stateMgr.getItemState(
                                new PropertyId(thisState.getNodeId(), propName));
                if (!allDefs.contains(ntReg.getPropDef(propState.getDefinitionId()))) {
                    // try to find new applicable definition first and
                    // redefine property if possible
                    try {
                        PropertyImpl prop = (PropertyImpl) itemMgr.getItem(propState.getId());
                        if (prop.getDefinition().isProtected()) {
                            // remove 'orphaned' protected properties immediately
                            removeChildProperty(propName);
                            continue;
                        }
                        PropertyDefinitionImpl pdi = getApplicablePropertyDefinition(
                                propName, propState.getType(),
                                propState.isMultiValued(), false);
                        if (pdi.getRequiredType() != PropertyType.UNDEFINED
                                && pdi.getRequiredType() != propState.getType()) {
                            // value conversion required
                            if (propState.isMultiValued()) {
                                // convert value
                                Value[] values =
                                        ValueHelper.convert(
                                                prop.getValues(),
                                                pdi.getRequiredType(),
                                                session.getValueFactory());
                                // redefine property
                                prop.onRedefine(pdi.unwrap().getId());
                                // set converted values
                                prop.setValue(values);
                            } else {
                                // convert value
                                Value value =
                                        ValueHelper.convert(
                                                prop.getValue(),
                                                pdi.getRequiredType(),
                                                session.getValueFactory());
                                // redefine property
                                prop.onRedefine(pdi.unwrap().getId());
                                // set converted values
                                prop.setValue(value);
                            }
                        } else {
                            // redefine property
                            prop.onRedefine(pdi.unwrap().getId());
                        }
                        // update collection of added definitions
                        addedDefs.remove(pdi.unwrap());
                    } catch (ValueFormatException vfe) {
                        // value conversion failed, remove it
                        removeChildProperty(propName);
                    } catch (ConstraintViolationException cve) {
                        // no suitable definition found for this property,
                        // remove it
                        removeChildProperty(propName);
                    }
                }
            } catch (ItemStateException ise) {
                String msg = propName + ": failed to retrieve property state";
                log.error(msg, ise);
                throw new RepositoryException(msg, ise);
            }
        }

        // use temp array to avoid ConcurrentModificationException
        ArrayList<ChildNodeEntry> list = new ArrayList<ChildNodeEntry>(thisState.getChildNodeEntries());
        // start from tail to avoid problems with same-name siblings
        for (int i = list.size() - 1; i >= 0; i--) {
            ChildNodeEntry entry = list.get(i);
            try {
                NodeState nodeState = (NodeState) stateMgr.getItemState(entry.getId());
                if (!allDefs.contains(ntReg.getNodeDef(nodeState.getDefinitionId()))) {
                    // try to find new applicable definition first and
                    // redefine node if possible
                    try {
                        NodeImpl node = (NodeImpl) itemMgr.getItem(nodeState.getId());
                        if (node.getDefinition().isProtected()) {
                            // remove 'orphaned' protected child node immediately
                            removeChildNode(entry.getName(), entry.getIndex());
                            continue;
                        }
                        NodeDefinitionImpl ndi = getApplicableChildNodeDefinition(
                                entry.getName(),
                                nodeState.getNodeTypeName());
                        // redefine node
                        node.onRedefine(ndi.unwrap().getId());
                        // update collection of added definitions
                        addedDefs.remove(ndi.unwrap());
                    } catch (ConstraintViolationException cve) {
                        // no suitable definition found for this child node,
                        // remove it
                        removeChildNode(entry.getName(), entry.getIndex());
                    }
                }
            } catch (ItemStateException ise) {
                String msg = entry.getName() + ": failed to retrieve node state";
                log.error(msg, ise);
                throw new RepositoryException(msg, ise);
            }
        }

        // create items that are defined as auto-created by the new primary node
        // type and at the same time were not present with the old nt
        for (Iterator<ItemDef> iter = addedDefs.iterator(); iter.hasNext();) {
            ItemDef def = iter.next();
            if (def.isAutoCreated()) {
                if (def.definesNode()) {
                    NodeDefinitionImpl ndi = ntMgr.getNodeDefinition(((NodeDef) def).getId());
                    createChildNode(ndi.getQName(), ndi, (NodeTypeImpl) ndi.getDefaultPrimaryType(), null);
                } else {
                    PropertyDefinitionImpl pdi = ntMgr.getPropertyDefinition(((PropDef) def).getId());
                    createChildProperty(pdi.getQName(), pdi.getRequiredType(), pdi);
                }
            }
        }
    }
View Full Code Here

        this.subject = subject;

        userId = retrieveUserId(subject);

        namePathResolver = new DefaultNamePathResolver(this, this, true);
        ntMgr = new NodeTypeManagerImpl(rep.getNodeTypeRegistry(), this, rep.getDataStore());
        String wspName = wspConfig.getName();
        wsp = createWorkspaceInstance(wspConfig,
                rep.getWorkspaceStateManager(wspName), rep, this);
        itemStateMgr = createSessionItemStateManager(wsp.getItemStateManager());
        hierMgr = itemStateMgr.getHierarchyMgr();
View Full Code Here

         * (for adding/removing child entries of a node), in
         * Node.addMixin/removeMixin/setPrimaryType (for type changes on nodes)
         * and in Property.setValue (for properties to be modified).
         */
        AccessManager accessMgr = session.getAccessManager();
        NodeTypeManagerImpl ntMgr = session.getNodeTypeManager();
        // walk through list of dirty transient items and validate each
        while (dirtyIter.hasNext()) {
            ItemState itemState = dirtyIter.next();
            ItemDefinition def;
            if (itemState.isNode()) {
                def = ntMgr.getNodeDefinition(((NodeState) itemState).getDefinitionId());
            } else {
                def = ntMgr.getPropertyDefinition(((PropertyState) itemState).getDefinitionId());
            }
            /* check permissions for non-protected items. protected items are
               only added through API methods which need to assert that
               permissions are not violated.
             */
            if (!def.isProtected()) {
                /* detect the effective set of modification:
                   - new added node -> add_node perm on the child
                   - new property added -> set_property permission
                   - property modified -> set_property permission
                   - modified nodes can be ignored for changes only included
                     child-item addition or removal or changes of protected
                     properties such as mixin-types which are covered separately
                   note: removed items are checked later on.
                */
                Path path = stateMgr.getHierarchyMgr().getPath(itemState.getId());
                boolean isGranted = true;
                if (itemState.isNode()) {
                    if (itemState.getStatus() == ItemState.STATUS_NEW) {
                        isGranted = accessMgr.isGranted(path, Permission.ADD_NODE);
                    } // else: modified node (see comment above)
                } else {
                    // modified or new property: set_property permission
                    isGranted = accessMgr.isGranted(path, Permission.SET_PROPERTY);
                }

                if (!isGranted) {
                    String msg = itemMgr.safeGetJCRPath(path) + ": not allowed to add or modify item";
                    log.debug(msg);
                    throw new AccessDeniedException(msg);
                }
            }

            if (itemState.isNode()) {
                // the transient item is a node
                NodeState nodeState = (NodeState) itemState;
                ItemId id = nodeState.getNodeId();
                NodeDefinition nodeDef = (NodeDefinition) def;
                // primary type
                NodeTypeImpl pnt = ntMgr.getNodeType(nodeState.getNodeTypeName());
                // effective node type (primary type incl. mixins)
                EffectiveNodeType ent = getEffectiveNodeType(nodeState);
                /**
                 * if the transient node was added (i.e. if it is 'new') or if
                 * its primary type has changed, check its node type against the
                 * required node type in its definition
                 */
                if (nodeState.getStatus() == ItemState.STATUS_NEW
                        || !nodeState.getNodeTypeName().equals(
                            ((NodeState) nodeState.getOverlayedState()).getNodeTypeName())) {
                    NodeType[] nta = nodeDef.getRequiredPrimaryTypes();
                    for (int i = 0; i < nta.length; i++) {
                        NodeTypeImpl ntReq = (NodeTypeImpl) nta[i];
                        if (!(pnt.getQName().equals(ntReq.getQName())
                                || pnt.isDerivedFrom(ntReq.getQName()))) {
                            /**
                             * the transient node's primary node type does not
                             * satisfy the 'required primary types' constraint
                             */
                            String msg = itemMgr.safeGetJCRPath(id)
                                    + " must be of node type " + ntReq.getName();
                            log.debug(msg);
                            throw new ConstraintViolationException(msg);
                        }
                    }
                }

                // mandatory child properties
                PropDef[] pda = ent.getMandatoryPropDefs();
                for (int i = 0; i < pda.length; i++) {
                    PropDef pd = pda[i];
                    if (pd.getDeclaringNodeType().equals(NameConstants.MIX_VERSIONABLE)
                            || pd.getDeclaringNodeType().equals(NameConstants.MIX_SIMPLE_VERSIONABLE)) {
                        /**
                         * todo FIXME workaround for mix:versionable:
                         * the mandatory properties are initialized at a
                         * later stage and might not exist yet
                         */
                        continue;
                    }
                    if (!nodeState.hasPropertyName(pd.getName())) {
                        String msg = itemMgr.safeGetJCRPath(id)
                                + ": mandatory property " + pd.getName()
                                + " does not exist";
                        log.debug(msg);
                        throw new ConstraintViolationException(msg);
                    }
                }
                // mandatory child nodes
                NodeDef[] cnda = ent.getMandatoryNodeDefs();
                for (int i = 0; i < cnda.length; i++) {
                    NodeDef cnd = cnda[i];
                    if (!nodeState.hasChildNodeEntry(cnd.getName())) {
                        String msg = itemMgr.safeGetJCRPath(id)
                                + ": mandatory child node " + cnd.getName()
                                + " does not exist";
                        log.debug(msg);
                        throw new ConstraintViolationException(msg);
                    }
                }
            } else {
                // the transient item is a property
                PropertyState propState = (PropertyState) itemState;
                ItemId propId = propState.getPropertyId();
                PropertyDefinitionImpl propDef = (PropertyDefinitionImpl) def;

                /**
                 * check value constraints
                 * (no need to check value constraints of protected properties
                 * as those are set by the implementation only, i.e. they
                 * cannot be set by the user through the api)
                 */
                if (!def.isProtected()) {
                    String[] constraints = propDef.getValueConstraints();
                    if (constraints != null) {
                        InternalValue[] values = propState.getValues();
                        try {
                            EffectiveNodeType.checkSetPropertyValueConstraints(
                                    propDef.unwrap(), values);
                        } catch (RepositoryException e) {
                            // repack exception for providing more verbose error message
                            String msg = itemMgr.safeGetJCRPath(propId) + ": " + e.getMessage();
                            log.debug(msg);
                            throw new ConstraintViolationException(msg);
                        }

                        /**
                         * need to manually check REFERENCE value constraints
                         * as this requires a session (target node needs to
                         * be checked)
                         */
                        if (constraints.length > 0
                                && (propDef.getRequiredType() == PropertyType.REFERENCE
                                    || propDef.getRequiredType() == PropertyType.WEAKREFERENCE)) {
                            for (int i = 0; i < values.length; i++) {
                                boolean satisfied = false;
                                String constraintViolationMsg = null;
                                try {
                                    NodeId targetId = values[i].getNodeId();
                                    if (propDef.getRequiredType() == PropertyType.WEAKREFERENCE
                                        && !itemMgr.itemExists(targetId)) {
                                        // target of weakref doesn;t exist, skip
                                        continue;
                                    }
                                    Node targetNode = session.getNodeById(targetId);
                                    /**
                                     * constraints are OR-ed, i.e. at least one
                                     * has to be satisfied
                                     */
                                    for (int j = 0; j < constraints.length; j++) {
                                        /**
                                         * a [WEAK]REFERENCE value constraint specifies
                                         * the name of the required node type of
                                         * the target node
                                         */
                                        String ntName = constraints[j];
                                        if (targetNode.isNodeType(ntName)) {
                                            satisfied = true;
                                            break;
                                        }
                                    }
                                    if (!satisfied) {
                                        NodeType[] mixinNodeTypes = targetNode.getMixinNodeTypes();
                                        String[] targetMixins = new String[mixinNodeTypes.length];
                                        for (int j = 0; j < mixinNodeTypes.length; j++) {
                                            targetMixins[j] = mixinNodeTypes[j].getName();
                                        }
                                        String targetMixinsString = Text.implode(targetMixins, ", ");
                                        String constraintsString = Text.implode(constraints, ", ");
                                        constraintViolationMsg = itemMgr.safeGetJCRPath(propId)
                                                + ": is constraint to ["
                                                + constraintsString
                                                + "] but references [primaryType="
                                                + targetNode.getPrimaryNodeType().getName()
                                                + ", mixins="
                                                + targetMixinsString + "]";
                                    }
                                } catch (RepositoryException re) {
                                    String msg = itemMgr.safeGetJCRPath(propId)
                                            + ": failed to check "
                                            + ((propDef.getRequiredType() == PropertyType.REFERENCE) ? "REFERENCE" : "WEAKREFERENCE")
                                            + " value constraint";
                                    log.debug(msg);
                                    throw new ConstraintViolationException(msg, re);
                                }
                                if (!satisfied) {
                                    log.debug(constraintViolationMsg);
                                    throw new ConstraintViolationException(constraintViolationMsg);
                                }
                            }
                        }
                    }
                }

                /**
                 * no need to check the protected flag as this is checked
                 * in PropertyImpl.setValue(Value)
                 */
            }
        }

        // walk through list of removed transient items and check REMOVE permission
        while (removedIter.hasNext()) {
            ItemState itemState = removedIter.next();
            ItemDefinition def;
            if (itemState.isNode()) {
                def = ntMgr.getNodeDefinition(((NodeState) itemState).getDefinitionId());
            } else {
                def = ntMgr.getPropertyDefinition(((PropertyState) itemState).getDefinitionId());
            }
            if (!def.isProtected()) {
                Path path = stateMgr.getAtticAwareHierarchyMgr().getPath(itemState.getId());
                // check REMOVE permission
                int permission = (itemState.isNode()) ? Permission.REMOVE_NODE : Permission.REMOVE_PROPERTY;
View Full Code Here

        SessionImpl session = context.getSessionImpl();
        ItemManager itemMgr = context.getItemManager();
        SessionItemStateManager stateMgr = context.getItemStateManager();

        AccessManager accessMgr = context.getAccessManager();
        NodeTypeManagerImpl ntMgr = context.getNodeTypeManager();
        // walk through list of dirty transient items and validate each
        for (ItemState itemState : dirty) {
            ItemDefinition def;
            if (itemState.isNode()) {
                def = itemMgr.getDefinition((NodeState) itemState);
            } else {
                def = itemMgr.getDefinition((PropertyState) itemState);
            }
            /* check permissions for non-protected items. protected items are
               only added through API methods which need to assert that
               permissions are not violated.
             */
            if (!def.isProtected()) {
                /* detect the effective set of modification:
                   - new added node -> add_node perm on the child
                   - new property added -> set_property permission
                   - property modified -> set_property permission
                   - modified nodes can be ignored for changes only included
                     child-item addition or removal or changes of protected
                     properties such as mixin-types which are covered separately
                   note: removed items are checked later on.
                   note: reordering of child nodes has been covered upfront as
                         this information isn't available here.
                */
                Path path = stateMgr.getHierarchyMgr().getPath(itemState.getId());
                boolean isGranted = true;
                if (itemState.isNode()) {
                    if (itemState.getStatus() == ItemState.STATUS_NEW) {
                        isGranted = accessMgr.isGranted(path, Permission.ADD_NODE);
                    } // else: modified node (see comment above)
                } else {
                    // modified or new property: set_property permission
                    isGranted = accessMgr.isGranted(path, Permission.SET_PROPERTY);
                }

                if (!isGranted) {
                    String msg = itemMgr.safeGetJCRPath(path) + ": not allowed to add or modify item";
                    log.debug(msg);
                    throw new AccessDeniedException(msg);
                }
            }

            if (itemState.isNode()) {
                // the transient item is a node
                NodeState nodeState = (NodeState) itemState;
                ItemId id = nodeState.getNodeId();
                NodeDefinition nodeDef = (NodeDefinition) def;
                // primary type
                NodeTypeImpl pnt = ntMgr.getNodeType(nodeState.getNodeTypeName());
                // effective node type (primary type incl. mixins)
                EffectiveNodeType ent = getEffectiveNodeType(
                        context.getRepositoryContext().getNodeTypeRegistry(),
                        nodeState);
                /**
 
View Full Code Here

     * @throws RepositoryException          if another error occurs
     */
    protected NodeDefinitionImpl getApplicableChildNodeDefinition(Name nodeName,
                                                                  Name nodeTypeName)
            throws ConstraintViolationException, RepositoryException {
        NodeTypeManagerImpl ntMgr = sessionContext.getNodeTypeManager();
        QNodeDefinition cnd = getEffectiveNodeType().getApplicableChildNodeDef(
                nodeName, nodeTypeName, sessionContext.getNodeTypeRegistry());
        return ntMgr.getNodeDefinition(cnd);
    }
View Full Code Here

            throws NoSuchNodeTypeException, RepositoryException {
        // check state of this instance
        sanityCheck();

        Name ntName = sessionContext.getQName(mixinName);
        NodeTypeManagerImpl ntMgr = sessionContext.getNodeTypeManager();
        NodeTypeImpl mixin = ntMgr.getNodeType(ntName);
        if (!mixin.isMixin()) {
            return false;
        }

        int options = ItemValidator.CHECK_LOCK | ItemValidator.CHECK_CHECKED_OUT
                | ItemValidator.CHECK_CONSTRAINTS | ItemValidator.CHECK_HOLD;
        int permissions = Permission.NODE_TYPE_MNGMT;
        // special handling of mix:(simple)versionable. since adding the mixin alters
        // the version storage jcr:versionManagement privilege is required
        // in addition.
        if (NameConstants.MIX_VERSIONABLE.equals(ntName)
                || NameConstants.MIX_SIMPLE_VERSIONABLE.equals(ntName)) {
            permissions |= Permission.VERSION_MNGMT;
        }
        if (!sessionContext.getItemValidator().canModify(this, options, permissions)) {
            return false;
        }

        final Name primaryTypeName = data.getNodeState().getNodeTypeName();

        NodeTypeImpl primaryType = ntMgr.getNodeType(primaryTypeName);
        if (primaryType.isDerivedFrom(ntName)) {
            // mixin already inherited -> addMixin is allowed but has no effect.
            return true;
        }

        // build effective node type of mixins & primary type
        // in order to detect conflicts
        NodeTypeRegistry ntReg = ntMgr.getNodeTypeRegistry();
        EffectiveNodeType entExisting;
        try {
            // existing mixin's
            Set<Name> mixins = new HashSet<Name>(data.getNodeState().getMixinTypeNames());
View Full Code Here

        if (ntName.equals(state.getNodeTypeName())) {
            log.debug("Node already has " + nodeTypeName + " as primary node type.");
            return;
        }

        NodeTypeManagerImpl ntMgr = sessionContext.getNodeTypeManager();
        NodeType nt = ntMgr.getNodeType(ntName);
        if (nt.isMixin()) {
            throw new ConstraintViolationException(nodeTypeName + ": not a primary node type.");
        } else if (nt.isAbstract()) {
            throw new ConstraintViolationException(nodeTypeName + ": is an abstract node type.");
        }

        // build effective node type of new primary type & existing mixin's
        // in order to detect conflicts
        NodeTypeRegistry ntReg = ntMgr.getNodeTypeRegistry();
        EffectiveNodeType entNew, entOld, entAll;
        try {
            entNew = ntReg.getEffectiveNodeType(ntName);
            entOld = ntReg.getEffectiveNodeType(state.getNodeTypeName());

            // try to build new effective node type (will throw in case of conflicts)
            entAll = ntReg.getEffectiveNodeType(ntName, state.getMixinTypeNames());
        } catch (NodeTypeConflictException ntce) {
            throw new ConstraintViolationException(ntce.getMessage());
        }

        // get applicable definition for this node using new primary type
        QNodeDefinition nodeDef;
        try {
            NodeImpl parent = (NodeImpl) getParent();
            nodeDef = parent.getApplicableChildNodeDefinition(getQName(), ntName).unwrap();
        } catch (RepositoryException re) {
            String msg = this + ": no applicable definition found in parent node's node type";
            log.debug(msg);
            throw new ConstraintViolationException(msg, re);
        }

        if (!nodeDef.equals(itemMgr.getDefinition(state).unwrap())) {
            onRedefine(nodeDef);
        }

        Set<QItemDefinition> oldDefs = new HashSet<QItemDefinition>(Arrays.asList(entOld.getAllItemDefs()));
        Set<QItemDefinition> newDefs = new HashSet<QItemDefinition>(Arrays.asList(entNew.getAllItemDefs()));
        Set<QItemDefinition> allDefs = new HashSet<QItemDefinition>(Arrays.asList(entAll.getAllItemDefs()));

        // added child item definitions
        Set<QItemDefinition> addedDefs = new HashSet<QItemDefinition>(newDefs);
        addedDefs.removeAll(oldDefs);

        // referential integrity check
        boolean referenceableOld = entOld.includesNodeType(NameConstants.MIX_REFERENCEABLE);
        boolean referenceableNew = entNew.includesNodeType(NameConstants.MIX_REFERENCEABLE);
        if (referenceableOld && !referenceableNew) {
            // node would become non-referenceable;
            // make sure no references exist
            PropertyIterator iter = getReferences();
            if (iter.hasNext()) {
                throw new ConstraintViolationException(
                        "the new primary type cannot be set as it would render "
                                + "this node 'non-referenceable' while it is still being "
                                + "referenced through at least one property of type REFERENCE");
            }
        }

        // do the actual modifications in content as mandated by the new primary type

        // modify the state of this node
        NodeState thisState = (NodeState) getOrCreateTransientItemState();
        thisState.setNodeTypeName(ntName);

        // set jcr:primaryType property
        internalSetProperty(NameConstants.JCR_PRIMARYTYPE, InternalValue.create(ntName));

        // walk through properties and child nodes and change definition as necessary

        // use temp set to avoid ConcurrentModificationException
        HashSet<Name> set = new HashSet<Name>(thisState.getPropertyNames());
        for (Name propName : set) {
            try {
                PropertyState propState =
                        (PropertyState) stateMgr.getItemState(
                                new PropertyId(thisState.getNodeId(), propName));
                if (!allDefs.contains(itemMgr.getDefinition(propState).unwrap())) {
                    // try to find new applicable definition first and
                    // redefine property if possible
                    try {
                        PropertyImpl prop = (PropertyImpl) itemMgr.getItem(propState.getId());
                        if (prop.getDefinition().isProtected()) {
                            // remove 'orphaned' protected properties immediately
                            removeChildProperty(propName);
                            continue;
                        }
                        PropertyDefinitionImpl pdi = getApplicablePropertyDefinition(
                                propName, propState.getType(),
                                propState.isMultiValued(), false);
                        if (pdi.getRequiredType() != PropertyType.UNDEFINED
                                && pdi.getRequiredType() != propState.getType()) {
                            // value conversion required
                            if (propState.isMultiValued()) {
                                // convert value
                                Value[] values =
                                        ValueHelper.convert(
                                                prop.getValues(),
                                                pdi.getRequiredType(),
                                                getSession().getValueFactory());
                                // redefine property
                                prop.onRedefine(pdi.unwrap());
                                // set converted values
                                prop.setValue(values);
                            } else {
                                // convert value
                                Value value =
                                        ValueHelper.convert(
                                                prop.getValue(),
                                                pdi.getRequiredType(),
                                                getSession().getValueFactory());
                                // redefine property
                                prop.onRedefine(pdi.unwrap());
                                // set converted values
                                prop.setValue(value);
                            }
                        } else {
                            // redefine property
                            prop.onRedefine(pdi.unwrap());
                        }
                        // update collection of added definitions
                        addedDefs.remove(pdi.unwrap());
                    } catch (ValueFormatException vfe) {
                        // value conversion failed, remove it
                        removeChildProperty(propName);
                    } catch (ConstraintViolationException cve) {
                        // no suitable definition found for this property,
                        // remove it
                        removeChildProperty(propName);
                    }
                }
            } catch (ItemStateException ise) {
                String msg = propName + ": failed to retrieve property state";
                log.error(msg, ise);
                throw new RepositoryException(msg, ise);
            }
        }

        // use temp array to avoid ConcurrentModificationException
        ArrayList<ChildNodeEntry> list = new ArrayList<ChildNodeEntry>(thisState.getChildNodeEntries());
        // start from tail to avoid problems with same-name siblings
        for (int i = list.size() - 1; i >= 0; i--) {
            ChildNodeEntry entry = list.get(i);
            try {
                NodeState nodeState = (NodeState) stateMgr.getItemState(entry.getId());
                if (!allDefs.contains(itemMgr.getDefinition(nodeState).unwrap())) {
                    // try to find new applicable definition first and
                    // redefine node if possible
                    try {
                        NodeImpl node = (NodeImpl) itemMgr.getItem(nodeState.getId());
                        if (node.getDefinition().isProtected()) {
                            // remove 'orphaned' protected child node immediately
                            removeChildNode(entry.getId());
                            continue;
                        }
                        NodeDefinitionImpl ndi = getApplicableChildNodeDefinition(
                                entry.getName(),
                                nodeState.getNodeTypeName());
                        // redefine node
                        node.onRedefine(ndi.unwrap());
                        // update collection of added definitions
                        addedDefs.remove(ndi.unwrap());
                    } catch (ConstraintViolationException cve) {
                        // no suitable definition found for this child node,
                        // remove it
                        removeChildNode(entry.getId());
                    }
                }
            } catch (ItemStateException ise) {
                String msg = entry.getName() + ": failed to retrieve node state";
                log.error(msg, ise);
                throw new RepositoryException(msg, ise);
            }
        }

        // create items that are defined as auto-created by the new primary node
        // type and at the same time were not present with the old nt
        for (QItemDefinition def : addedDefs) {
            if (def.isAutoCreated()) {
                if (def.definesNode()) {
                    NodeDefinitionImpl ndi = ntMgr.getNodeDefinition((QNodeDefinition) def);
                    createChildNode(def.getName(), (NodeTypeImpl) ndi.getDefaultPrimaryType(), null);
                } else {
                    PropertyDefinitionImpl pdi = ntMgr.getPropertyDefinition((QPropertyDefinition) def);
                    createChildProperty(pdi.unwrap().getName(), pdi.getRequiredType(), pdi);
                }
            }
        }
    }
View Full Code Here

TOP

Related Classes of org.apache.jackrabbit.core.nodetype.NodeTypeManagerImpl

Copyright © 2018 www.massapicom. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.