Search in sources :

Example 6 with QItemDefinition

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

the class ItemDefinitionProviderImpl method getMatchingPropDef.

private static QPropertyDefinition getMatchingPropDef(QPropertyDefinition[] defs, int type) {
    QPropertyDefinition match = null;
    for (int i = 0; i < defs.length; i++) {
        QItemDefinition qDef = defs[i];
        if (!qDef.definesNode()) {
            QPropertyDefinition pd = (QPropertyDefinition) qDef;
            int reqType = pd.getRequiredType();
            // match type
            if (reqType == PropertyType.UNDEFINED || type == PropertyType.UNDEFINED || reqType == type) {
                if (match == null) {
                    match = pd;
                } else {
                    // the one we've already got
                    if (match.getRequiredType() != pd.getRequiredType()) {
                        if (match.getRequiredType() == PropertyType.UNDEFINED) {
                            // found better match
                            match = pd;
                        }
                    } else {
                        if (match.isMultiple() && !pd.isMultiple()) {
                            // found better match
                            match = pd;
                        }
                    }
                }
                if (match.getRequiredType() != PropertyType.UNDEFINED && !match.isMultiple()) {
                    // found best possible match, get outta here
                    return match;
                }
            }
        }
    }
    return match;
}
Also used : QPropertyDefinition(org.apache.jackrabbit.spi.QPropertyDefinition) QItemDefinition(org.apache.jackrabbit.spi.QItemDefinition)

Example 7 with QItemDefinition

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

the class EffectiveNodeTypeImpl method getNamedQPropertyDefinitions.

/**
     * @see EffectiveNodeType#getNamedQPropertyDefinitions(Name)
     */
public QPropertyDefinition[] getNamedQPropertyDefinitions(Name name) {
    List<QItemDefinition> list = namedItemDefs.get(name);
    if (list == null || list.size() == 0) {
        return QPropertyDefinition.EMPTY_ARRAY;
    }
    ArrayList<QItemDefinition> defs = new ArrayList<QItemDefinition>(list.size());
    for (QItemDefinition qDef : list) {
        if (!qDef.definesNode()) {
            defs.add(qDef);
        }
    }
    if (defs.size() == 0) {
        return QPropertyDefinition.EMPTY_ARRAY;
    }
    return defs.toArray(new QPropertyDefinition[defs.size()]);
}
Also used : ArrayList(java.util.ArrayList) QItemDefinition(org.apache.jackrabbit.spi.QItemDefinition)

Example 8 with QItemDefinition

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

the class EffectiveNodeTypeImpl method getNamedQNodeDefinitions.

/**
     * @see EffectiveNodeType#getNamedQNodeDefinitions(Name)
     */
public QNodeDefinition[] getNamedQNodeDefinitions(Name name) {
    List<QItemDefinition> list = namedItemDefs.get(name);
    if (list == null || list.size() == 0) {
        return QNodeDefinition.EMPTY_ARRAY;
    }
    ArrayList<QItemDefinition> defs = new ArrayList<QItemDefinition>(list.size());
    for (QItemDefinition qDef : list) {
        if (qDef.definesNode()) {
            defs.add(qDef);
        }
    }
    if (defs.size() == 0) {
        return QNodeDefinition.EMPTY_ARRAY;
    }
    return defs.toArray(new QNodeDefinition[defs.size()]);
}
Also used : ArrayList(java.util.ArrayList) QItemDefinition(org.apache.jackrabbit.spi.QItemDefinition)

Example 9 with QItemDefinition

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

the class ItemDefinitionProviderImpl method getMatchingPropDef.

private static QPropertyDefinition getMatchingPropDef(QPropertyDefinition[] defs, int type, boolean multiValued, boolean throwWhenAmbiguous) throws ConstraintViolationException {
    QPropertyDefinition match = null;
    for (int i = 0; i < defs.length; i++) {
        QItemDefinition qDef = defs[i];
        if (!qDef.definesNode()) {
            QPropertyDefinition pd = (QPropertyDefinition) qDef;
            int reqType = pd.getRequiredType();
            // match type
            if (reqType == PropertyType.UNDEFINED || type == PropertyType.UNDEFINED || reqType == type) {
                // match multiValued flag
                if (multiValued == pd.isMultiple()) {
                    // found match
                    if (pd.getRequiredType() != PropertyType.UNDEFINED) {
                        if (match != null && throwWhenAmbiguous) {
                            throw new ConstraintViolationException("ambiguous property definitions found: " + match + " vs " + pd);
                        }
                        // thus obviously specified a String.
                        if (match == null || match.getRequiredType() != PropertyType.STRING) {
                            // found best possible match
                            match = pd;
                        }
                    } else {
                        if (match == null) {
                            match = pd;
                        }
                    }
                }
            }
        }
    }
    return match;
}
Also used : QPropertyDefinition(org.apache.jackrabbit.spi.QPropertyDefinition) ConstraintViolationException(javax.jcr.nodetype.ConstraintViolationException) QItemDefinition(org.apache.jackrabbit.spi.QItemDefinition)

Example 10 with QItemDefinition

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

the class NodeImpl method setMixins.

/**
     * {@inheritDoc}
     */
public void setMixins(String[] mixinNames) throws NoSuchNodeTypeException, VersionException, ConstraintViolationException, LockException, RepositoryException {
    // check state of this instance
    sanityCheck();
    NodeTypeManagerImpl ntMgr = sessionContext.getNodeTypeManager();
    Set<Name> newMixins = new HashSet<Name>();
    for (String name : mixinNames) {
        Name qName = sessionContext.getQName(name);
        if (!ntMgr.getNodeType(qName).isMixin()) {
            throw new RepositoryException(sessionContext.getJCRName(qName) + " is not a mixin node type");
        }
        newMixins.add(qName);
    }
    // make sure this node is checked-out, neither protected nor locked and
    // the editing session has sufficient permission to change the mixin types.
    // special handling of mix:(simple)versionable. since adding the
    // mixin alters the version storage jcr:versionManagement privilege
    // is required in addition.
    int permissions = Permission.NODE_TYPE_MNGMT;
    if (newMixins.contains(MIX_VERSIONABLE) || newMixins.contains(MIX_SIMPLE_VERSIONABLE)) {
        permissions |= Permission.VERSION_MNGMT;
    }
    int options = ItemValidator.CHECK_CHECKED_OUT | ItemValidator.CHECK_LOCK | ItemValidator.CHECK_CONSTRAINTS | ItemValidator.CHECK_HOLD;
    sessionContext.getItemValidator().checkModify(this, options, permissions);
    final NodeState state = data.getNodeState();
    // build effective node type of primary type & new mixin's
    // in order to detect conflicts
    NodeTypeRegistry ntReg = ntMgr.getNodeTypeRegistry();
    EffectiveNodeType entNew, entOld, entAll;
    try {
        entNew = ntReg.getEffectiveNodeType(newMixins);
        entOld = ntReg.getEffectiveNodeType(state.getMixinTypeNames());
        // try to build new effective node type (will throw in case of conflicts)
        entAll = ntReg.getEffectiveNodeType(state.getNodeTypeName(), newMixins);
    } catch (NodeTypeConflictException ntce) {
        throw new ConstraintViolationException(ntce.getMessage());
    }
    // added child item definitions
    Set<QItemDefinition> addedDefs = new HashSet<QItemDefinition>(Arrays.asList(entNew.getAllItemDefs()));
    addedDefs.removeAll(Arrays.asList(entOld.getAllItemDefs()));
    // referential integrity check
    boolean referenceableOld = getEffectiveNodeType().includesNodeType(NameConstants.MIX_REFERENCEABLE);
    boolean referenceableNew = entAll.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 mixin types 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");
        }
    }
    // gather currently assigned definitions *before* doing actual modifications
    Map<ItemId, ItemDefinition> oldDefs = new HashMap<ItemId, ItemDefinition>();
    for (Name name : getNodeState().getPropertyNames()) {
        PropertyId id = new PropertyId(getNodeId(), name);
        try {
            PropertyState propState = (PropertyState) stateMgr.getItemState(id);
            oldDefs.put(id, itemMgr.getDefinition(propState));
        } catch (ItemStateException ise) {
            String msg = name + ": failed to retrieve property state";
            log.error(msg, ise);
            throw new RepositoryException(msg, ise);
        }
    }
    for (ChildNodeEntry cne : getNodeState().getChildNodeEntries()) {
        try {
            NodeState nodeState = (NodeState) stateMgr.getItemState(cne.getId());
            oldDefs.put(cne.getId(), itemMgr.getDefinition(nodeState));
        } catch (ItemStateException ise) {
            String msg = cne + ": failed to retrieve node state";
            log.error(msg, ise);
            throw new RepositoryException(msg, ise);
        }
    }
    // now do the actual modifications in content as mandated by the new mixins
    // modify the state of this node
    NodeState thisState = (NodeState) getOrCreateTransientItemState();
    thisState.setMixinTypeNames(newMixins);
    // set jcr:mixinTypes property
    setMixinTypesProperty(newMixins);
    // 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) {
        PropertyState propState = null;
        try {
            propState = (PropertyState) stateMgr.getItemState(new PropertyId(thisState.getNodeId(), propName));
            // the following call triggers ConstraintViolationException
            // if there isn't any suitable definition anymore
            itemMgr.getDefinition(propState);
        } catch (ConstraintViolationException cve) {
            // redefine property if possible
            try {
                if (oldDefs.get(propState.getId()).isProtected()) {
                    // remove 'orphaned' protected properties immediately
                    removeChildProperty(propName);
                    continue;
                }
                PropertyDefinitionImpl pdi = getApplicablePropertyDefinition(propName, propState.getType(), propState.isMultiValued(), false);
                PropertyImpl prop = (PropertyImpl) itemMgr.getItem(propState.getId());
                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 cve1) {
                // 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);
        NodeState nodeState = null;
        try {
            nodeState = (NodeState) stateMgr.getItemState(entry.getId());
            // the following call triggers ConstraintViolationException
            // if there isn't any suitable definition anymore
            itemMgr.getDefinition(nodeState);
        } catch (ConstraintViolationException cve) {
            // redefine node if possible
            try {
                if (oldDefs.get(nodeState.getId()).isProtected()) {
                    // remove 'orphaned' protected child node immediately
                    removeChildNode(entry.getId());
                    continue;
                }
                NodeDefinitionImpl ndi = getApplicableChildNodeDefinition(entry.getName(), nodeState.getNodeTypeName());
                NodeImpl node = (NodeImpl) itemMgr.getItem(nodeState.getId());
                // redefine node
                node.onRedefine(ndi.unwrap());
                // update collection of added definitions
                addedDefs.remove(ndi.unwrap());
            } catch (ConstraintViolationException cve1) {
                // no suitable definition found for this child node,
                // remove it
                removeChildNode(entry.getId());
            }
        } catch (ItemStateException ise) {
            String msg = entry + ": failed to retrieve node state";
            log.error(msg, ise);
            throw new RepositoryException(msg, ise);
        }
    }
    // and at the same time were not present with the old mixins
    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);
            }
        }
    }
}
Also used : NodeState(org.apache.jackrabbit.core.state.NodeState) HashMap(java.util.HashMap) NodeTypeConflictException(org.apache.jackrabbit.core.nodetype.NodeTypeConflictException) QItemDefinition(org.apache.jackrabbit.spi.QItemDefinition) ItemDefinition(javax.jcr.nodetype.ItemDefinition) ArrayList(java.util.ArrayList) ItemId(org.apache.jackrabbit.core.id.ItemId) Name(org.apache.jackrabbit.spi.Name) NodeDefinitionImpl(org.apache.jackrabbit.spi.commons.nodetype.NodeDefinitionImpl) ConstraintViolationException(javax.jcr.nodetype.ConstraintViolationException) NodeTypeManagerImpl(org.apache.jackrabbit.core.nodetype.NodeTypeManagerImpl) HashSet(java.util.HashSet) ChildNodeEntry(org.apache.jackrabbit.core.state.ChildNodeEntry) PropertyIterator(javax.jcr.PropertyIterator) PropertyDefinitionImpl(org.apache.jackrabbit.spi.commons.nodetype.PropertyDefinitionImpl) RepositoryException(javax.jcr.RepositoryException) QItemDefinition(org.apache.jackrabbit.spi.QItemDefinition) PropertyId(org.apache.jackrabbit.core.id.PropertyId) PropertyState(org.apache.jackrabbit.core.state.PropertyState) InvalidItemStateException(javax.jcr.InvalidItemStateException) ItemStateException(org.apache.jackrabbit.core.state.ItemStateException) EffectiveNodeType(org.apache.jackrabbit.core.nodetype.EffectiveNodeType) Value(javax.jcr.Value) InternalValue(org.apache.jackrabbit.core.value.InternalValue) ValueFormatException(javax.jcr.ValueFormatException) NodeTypeRegistry(org.apache.jackrabbit.core.nodetype.NodeTypeRegistry)

Aggregations

QItemDefinition (org.apache.jackrabbit.spi.QItemDefinition)22 ConstraintViolationException (javax.jcr.nodetype.ConstraintViolationException)10 Name (org.apache.jackrabbit.spi.Name)10 QNodeDefinition (org.apache.jackrabbit.spi.QNodeDefinition)9 QPropertyDefinition (org.apache.jackrabbit.spi.QPropertyDefinition)9 ArrayList (java.util.ArrayList)7 RepositoryException (javax.jcr.RepositoryException)6 EffectiveNodeType (org.apache.jackrabbit.core.nodetype.EffectiveNodeType)6 NodeState (org.apache.jackrabbit.core.state.NodeState)5 HashSet (java.util.HashSet)4 ChildNodeEntry (org.apache.jackrabbit.core.state.ChildNodeEntry)4 ItemStateException (org.apache.jackrabbit.core.state.ItemStateException)4 AccessDeniedException (javax.jcr.AccessDeniedException)3 ItemNotFoundException (javax.jcr.ItemNotFoundException)3 NodeId (org.apache.jackrabbit.core.id.NodeId)3 PropertyId (org.apache.jackrabbit.core.id.PropertyId)3 NodeTypeManagerImpl (org.apache.jackrabbit.core.nodetype.NodeTypeManagerImpl)3 NodeTypeRegistry (org.apache.jackrabbit.core.nodetype.NodeTypeRegistry)3 AccessManager (org.apache.jackrabbit.core.security.AccessManager)3 PropertyState (org.apache.jackrabbit.core.state.PropertyState)3