Search in sources :

Example 26 with QNodeDefinition

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

the class EffectiveNodeType method create.

/**
 * Package private factory method.
 * <p>
 * Creates an effective node type representation of a node type definition.
 * Note that the definitions of all referenced node types must be contained
 * in <code>ntdCache</code>.
 *
 * @param ntd      node type definition
 * @param entCache cache of already-built effective node types
 * @param ntdCache cache of node type definitions, used to resolve dependencies
 * @return an effective node type representation of the given node type definition.
 * @throws NodeTypeConflictException if the node type definition is invalid,
 *                                   e.g. due to ambiguous child definitions.
 * @throws NoSuchNodeTypeException if a node type reference (e.g. a supertype)
 *                                 could not be resolved.
 */
static EffectiveNodeType create(QNodeTypeDefinition ntd, EffectiveNodeTypeCache entCache, Map<Name, QNodeTypeDefinition> ntdCache) throws NodeTypeConflictException, NoSuchNodeTypeException {
    // create empty effective node type instance
    EffectiveNodeType ent = new EffectiveNodeType();
    Name ntName = ntd.getName();
    // prepare new instance
    ent.mergedNodeTypes.add(ntName);
    ent.allNodeTypes.add(ntName);
    // map of all item definitions (maps id to definition)
    // used to effectively detect ambiguous child definitions where
    // ambiguity is defined in terms of definition identity
    Set<QItemDefinition> itemDefs = new HashSet<QItemDefinition>();
    QNodeDefinition[] cnda = ntd.getChildNodeDefs();
    for (QNodeDefinition aCnda : cnda) {
        // this node type definition
        if (itemDefs.contains(aCnda)) {
            // conflict
            String msg;
            if (aCnda.definesResidual()) {
                msg = ntName + " contains ambiguous residual child node definitions";
            } else {
                msg = ntName + " contains ambiguous definitions for child node named " + aCnda.getName();
            }
            log.debug(msg);
            throw new NodeTypeConflictException(msg);
        } else {
            itemDefs.add(aCnda);
        }
        if (aCnda.definesResidual()) {
            // residual node definition
            ent.unnamedItemDefs.add(aCnda);
        } else {
            // named node definition
            Name name = aCnda.getName();
            List<QItemDefinition> defs = ent.namedItemDefs.get(name);
            if (defs == null) {
                defs = new ArrayList<QItemDefinition>();
                ent.namedItemDefs.put(name, defs);
            }
            if (defs.size() > 0) {
                /**
                 * there already exists at least one definition with that
                 * name; make sure none of them is auto-create
                 */
                for (QItemDefinition def : defs) {
                    if (aCnda.isAutoCreated() || def.isAutoCreated()) {
                        // conflict
                        String msg = "There are more than one 'auto-create' item definitions for '" + name + "' in node type '" + ntName + "'";
                        log.debug(msg);
                        throw new NodeTypeConflictException(msg);
                    }
                }
            }
            defs.add(aCnda);
        }
    }
    QPropertyDefinition[] pda = ntd.getPropertyDefs();
    for (QPropertyDefinition aPda : pda) {
        // this node type definition
        if (itemDefs.contains(aPda)) {
            // conflict
            String msg;
            if (aPda.definesResidual()) {
                msg = ntName + " contains ambiguous residual property definitions";
            } else {
                msg = ntName + " contains ambiguous definitions for property named " + aPda.getName();
            }
            log.debug(msg);
            throw new NodeTypeConflictException(msg);
        } else {
            itemDefs.add(aPda);
        }
        if (aPda.definesResidual()) {
            // residual property definition
            ent.unnamedItemDefs.add(aPda);
        } else {
            // named property definition
            Name name = aPda.getName();
            List<QItemDefinition> defs = ent.namedItemDefs.get(name);
            if (defs == null) {
                defs = new ArrayList<QItemDefinition>();
                ent.namedItemDefs.put(name, defs);
            }
            if (defs.size() > 0) {
                /**
                 * there already exists at least one definition with that
                 * name; make sure none of them is auto-create
                 */
                for (QItemDefinition def : defs) {
                    if (aPda.isAutoCreated() || def.isAutoCreated()) {
                        // conflict
                        String msg = "There are more than one 'auto-create' item definitions for '" + name + "' in node type '" + ntName + "'";
                        log.debug(msg);
                        throw new NodeTypeConflictException(msg);
                    }
                }
            }
            defs.add(aPda);
        }
    }
    // resolve supertypes recursively
    Name[] supertypes = ntd.getSupertypes();
    if (supertypes.length > 0) {
        EffectiveNodeType base = NodeTypeRegistry.getEffectiveNodeType(supertypes, entCache, ntdCache);
        ent.internalMerge(base, true);
    }
    // resolve 'orderable child nodes' attribute value (JCR-1947)
    if (ntd.hasOrderableChildNodes()) {
        ent.orderableChildNodes = true;
    } else {
        Name[] nta = ent.getInheritedNodeTypes();
        for (Name aNta : nta) {
            QNodeTypeDefinition def = ntdCache.get(aNta);
            if (def.hasOrderableChildNodes()) {
                ent.orderableChildNodes = true;
                break;
            }
        }
    }
    // resolve 'primary item' attribute value (JCR-1947)
    if (ntd.getPrimaryItemName() != null) {
        ent.primaryItemName = ntd.getPrimaryItemName();
    } else {
        Name[] nta = ent.getInheritedNodeTypes();
        for (Name aNta : nta) {
            QNodeTypeDefinition def = ntdCache.get(aNta);
            if (def.getPrimaryItemName() != null) {
                ent.primaryItemName = def.getPrimaryItemName();
                break;
            }
        }
    }
    // we're done
    return ent;
}
Also used : QItemDefinition(org.apache.jackrabbit.spi.QItemDefinition) QNodeDefinition(org.apache.jackrabbit.spi.QNodeDefinition) Name(org.apache.jackrabbit.spi.Name) QNodeTypeDefinition(org.apache.jackrabbit.spi.QNodeTypeDefinition) QPropertyDefinition(org.apache.jackrabbit.spi.QPropertyDefinition) HashSet(java.util.HashSet)

Example 27 with QNodeDefinition

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

the class EffectiveNodeType method getNamedNodeDefs.

public QNodeDefinition[] getNamedNodeDefs(Name name) {
    List<QItemDefinition> list = namedItemDefs.get(name);
    if (list == null || list.size() == 0) {
        return QNodeDefinition.EMPTY_ARRAY;
    }
    ArrayList<QNodeDefinition> defs = new ArrayList<QNodeDefinition>(list.size());
    for (QItemDefinition def : list) {
        if (def.definesNode()) {
            defs.add((QNodeDefinition) def);
        }
    }
    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) QNodeDefinition(org.apache.jackrabbit.spi.QNodeDefinition)

Example 28 with QNodeDefinition

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

the class WorkspaceImporter method startNode.

/**
 * {@inheritDoc}
 */
public void startNode(NodeInfo nodeInfo, List<PropInfo> propInfos) throws RepositoryException {
    if (aborted) {
        // the import has been aborted, get outta here...
        return;
    }
    boolean succeeded = false;
    NodeState parent;
    try {
        // check sanity of workspace/session first
        wsp.sanityCheck();
        parent = parents.peek();
        // process node
        NodeState node = null;
        NodeId id = nodeInfo.getId();
        Name nodeName = nodeInfo.getName();
        Name ntName = nodeInfo.getNodeTypeName();
        Name[] mixins = nodeInfo.getMixinNames();
        if (parent == null) {
            // parent node was skipped, skip this child node too
            // push null onto stack for skipped node
            parents.push(null);
            succeeded = true;
            log.debug("skipping node " + nodeName);
            return;
        }
        if (parent.hasChildNodeEntry(nodeName)) {
            // a node with that name already exists...
            ChildNodeEntry entry = parent.getChildNodeEntry(nodeName, 1);
            NodeId idExisting = entry.getId();
            NodeState existing = (NodeState) itemOps.getItemState(idExisting);
            QNodeDefinition def = itemOps.findApplicableNodeDefinition(nodeName, existing.getNodeTypeName(), parent);
            if (!def.allowsSameNameSiblings()) {
                // existing doesn't allow same-name siblings,
                // check for potential conflicts
                EffectiveNodeType entExisting = itemOps.getEffectiveNodeType(existing);
                if (def.isProtected() && entExisting.includesNodeType(ntName)) {
                    // skip protected node
                    // push null onto stack for skipped node
                    parents.push(null);
                    succeeded = true;
                    log.debug("skipping protected node " + itemOps.safeGetJCRPath(existing.getNodeId()));
                    return;
                }
                if (def.isAutoCreated() && entExisting.includesNodeType(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 (!(idExisting.equals(id) && (uuidBehavior == ImportUUIDBehavior.IMPORT_UUID_COLLISION_REMOVE_EXISTING || uuidBehavior == ImportUUIDBehavior.IMPORT_UUID_COLLISION_REPLACE_EXISTING))) {
                        throw new ItemExistsException(itemOps.safeGetJCRPath(existing.getNodeId()));
                    }
                // fall through
                }
            }
        }
        if (node == null) {
            // there's no node with that name...
            if (id == null) {
                // no potential uuid conflict, always create new node
                QNodeDefinition def = itemOps.findApplicableNodeDefinition(nodeName, ntName, parent);
                if (def.isProtected()) {
                    // skip protected node
                    // push null onto stack for skipped node
                    parents.push(null);
                    succeeded = true;
                    log.debug("skipping protected node " + nodeName);
                    return;
                }
                // check if new node can be added (check access rights &
                // node type constraints only, assume locking & versioning status
                // and retention/hold has already been checked on ancestor)
                itemOps.checkAddNode(parent, nodeName, ntName, BatchedItemOperations.CHECK_ACCESS | BatchedItemOperations.CHECK_CONSTRAINTS);
                // do create new node
                node = itemOps.createNodeState(parent, nodeName, ntName, mixins, null, def);
            } else {
                // potential uuid conflict
                try {
                    NodeState conflicting = itemOps.getNodeState(id);
                    // resolve uuid conflict
                    node = resolveUUIDConflict(parent, conflicting, nodeInfo);
                    if (node == null) {
                        // no new node has been created, so skip this node
                        // push null onto stack for skipped node
                        parents.push(null);
                        succeeded = true;
                        log.debug("skipping existing node: " + nodeName);
                        return;
                    }
                } catch (ItemNotFoundException e) {
                    // create new with given uuid
                    QNodeDefinition def = itemOps.findApplicableNodeDefinition(nodeName, ntName, parent);
                    if (def.isProtected()) {
                        // skip protected node
                        // push null onto stack for skipped node
                        parents.push(null);
                        succeeded = true;
                        log.debug("skipping protected node " + nodeName);
                        return;
                    }
                    // check if new node can be added (check access rights &
                    // node type constraints only, assume locking & versioning status
                    // and retention/hold has already been checked on ancestor)
                    itemOps.checkAddNode(parent, nodeName, ntName, BatchedItemOperations.CHECK_ACCESS | BatchedItemOperations.CHECK_CONSTRAINTS);
                    // do create new node
                    node = itemOps.createNodeState(parent, nodeName, ntName, mixins, id, def);
                }
            }
        }
        // process properties
        for (PropInfo propInfo : propInfos) {
            processProperty(node, propInfo);
        }
        // store affected nodes
        itemOps.store(node);
        itemOps.store(parent);
        // push current node onto stack of parents
        parents.push(node);
        succeeded = true;
    } finally {
        if (!succeeded) {
            // update operation failed, cancel all modifications
            aborted = true;
            itemOps.cancel();
        }
    }
}
Also used : EffectiveNodeType(org.apache.jackrabbit.core.nodetype.EffectiveNodeType) NodeState(org.apache.jackrabbit.core.state.NodeState) ItemExistsException(javax.jcr.ItemExistsException) ChildNodeEntry(org.apache.jackrabbit.core.state.ChildNodeEntry) NodeId(org.apache.jackrabbit.core.id.NodeId) QNodeDefinition(org.apache.jackrabbit.spi.QNodeDefinition) Name(org.apache.jackrabbit.spi.Name) ItemNotFoundException(javax.jcr.ItemNotFoundException)

Example 29 with QNodeDefinition

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

the class NodeImpl method createNode.

// ---------------------------------------------< private implementation >---
/**
 * Create a new <code>NodeState</code> and subsequently retrieves the
 * corresponding <code>Node</code> object.
 *
 * @param nodeName     name of the new node
 * @param nodeTypeName name of the new node's node type or <code>null</code>
 *                     if it should be determined automatically
 * @return the newly added node
 * @throws ItemExistsException
 * @throws NoSuchNodeTypeException
 * @throws VersionException
 * @throws ConstraintViolationException
 * @throws LockException
 * @throws RepositoryException
 */
private synchronized Node createNode(Name nodeName, Name nodeTypeName) throws ItemExistsException, NoSuchNodeTypeException, VersionException, ConstraintViolationException, LockException, RepositoryException {
    QNodeDefinition definition = session.getItemDefinitionProvider().getQNodeDefinition(getNodeState().getAllNodeTypeNames(), nodeName, nodeTypeName);
    if (nodeTypeName == null) {
        // use default node type
        nodeTypeName = definition.getDefaultPrimaryType();
    }
    // validation check are performed by item state manager
    // NOTE: uuid is generated while creating new state.
    Operation an = AddNode.create(getNodeState(), nodeName, nodeTypeName, null);
    session.getSessionItemStateManager().execute(an);
    // finally retrieve the new node
    List<ItemState> addedStates = ((AddNode) an).getAddedStates();
    ItemState nState = addedStates.get(0);
    return (Node) getItemManager().getItem(nState.getHierarchyEntry());
}
Also used : ItemState(org.apache.jackrabbit.jcr2spi.state.ItemState) AddNode(org.apache.jackrabbit.jcr2spi.operation.AddNode) Node(javax.jcr.Node) Operation(org.apache.jackrabbit.jcr2spi.operation.Operation) QNodeDefinition(org.apache.jackrabbit.spi.QNodeDefinition) AddNode(org.apache.jackrabbit.jcr2spi.operation.AddNode)

Example 30 with QNodeDefinition

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

the class NodeImpl method getDefinition.

/**
 * @see Node#getDefinition()
 */
public NodeDefinition getDefinition() throws RepositoryException {
    checkStatus();
    QNodeDefinition qnd = getNodeState().getDefinition();
    return session.getNodeTypeManager().getNodeDefinition(qnd);
}
Also used : QNodeDefinition(org.apache.jackrabbit.spi.QNodeDefinition)

Aggregations

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