Search in sources :

Example 21 with AssociationDefinition

use of org.alfresco.service.cmr.dictionary.AssociationDefinition in project alfresco-repository by Alfresco.

the class PolicyComponentImpl method bindAssociationBehaviour.

/* (non-Javadoc)
     * @see org.alfresco.repo.policy.PolicyComponent#bindAssociationBehaviour(org.alfresco.repo.ref.QName, org.alfresco.repo.ref.QName, org.alfresco.repo.ref.QName, org.alfresco.repo.policy.Behaviour)
     */
public BehaviourDefinition<ClassFeatureBehaviourBinding> bindAssociationBehaviour(QName policy, QName className, QName assocName, Behaviour behaviour) {
    // Validate arguments
    ParameterCheck.mandatory("Policy", policy);
    ParameterCheck.mandatory("Class Reference", className);
    ParameterCheck.mandatory("Association Reference", assocName);
    ParameterCheck.mandatory("Behaviour", behaviour);
    // Validate Binding
    AssociationDefinition assocDefinition = dictionary.getAssociation(assocName);
    if (assocDefinition == null) {
        throw new IllegalArgumentException("Association " + assocName + " of class " + className + " has not been defined in the data dictionary");
    }
    // Create behaviour definition and bind to policy
    ClassFeatureBehaviourBinding binding = new ClassFeatureBehaviourBinding(dictionary, className, assocName);
    BehaviourDefinition<ClassFeatureBehaviourBinding> definition = createBehaviourDefinition(PolicyType.Association, policy, binding, behaviour);
    getAssociationBehaviourIndex(policy).putClassBehaviour(definition);
    if (logger.isInfoEnabled())
        logger.info("Bound " + behaviour + " to policy " + policy + " for association " + assocName + " of class " + className);
    return definition;
}
Also used : AssociationDefinition(org.alfresco.service.cmr.dictionary.AssociationDefinition)

Example 22 with AssociationDefinition

use of org.alfresco.service.cmr.dictionary.AssociationDefinition in project alfresco-repository by Alfresco.

the class DbNodeServiceImpl method removeAspect.

@Override
@Extend(traitAPI = NodeServiceTrait.class, extensionAPI = NodeServiceExtension.class)
public void removeAspect(NodeRef nodeRef, QName aspectTypeQName) throws InvalidNodeRefException, InvalidAspectException {
    // Don't allow spoofed aspect(s) to be removed
    if (aspectTypeQName.equals(ContentModel.ASPECT_PENDING_DELETE)) {
        throw new IllegalArgumentException("The aspect is reserved for system use: " + aspectTypeQName);
    }
    /*
         * Note: Aspect and property removal is resilient to missing dictionary definitions
         */
    // get the node
    final Pair<Long, NodeRef> nodePair = getNodePairNotNull(nodeRef);
    final Long nodeId = nodePair.getFirst();
    boolean hadAspect = nodeDAO.hasNodeAspect(nodeId, aspectTypeQName);
    // Invoke policy behaviours
    invokeBeforeUpdateNode(nodeRef);
    if (hadAspect) {
        invokeBeforeRemoveAspect(nodeRef, aspectTypeQName);
        nodeDAO.removeNodeAspects(nodeId, Collections.singleton(aspectTypeQName));
    }
    AspectDefinition aspectDef = dictionaryService.getAspect(aspectTypeQName);
    boolean updated = false;
    if (aspectDef != null) {
        // Remove default properties
        Map<QName, PropertyDefinition> propertyDefs = aspectDef.getProperties();
        Set<QName> propertyToRemoveQNames = propertyDefs.keySet();
        nodeDAO.removeNodeProperties(nodeId, propertyToRemoveQNames);
        // Remove child associations
        // We have to iterate over the associations and remove all those between the parent and child
        final List<Pair<Long, ChildAssociationRef>> assocsToDelete = new ArrayList<Pair<Long, ChildAssociationRef>>(5);
        final List<Pair<Long, NodeRef>> nodesToDelete = new ArrayList<Pair<Long, NodeRef>>(5);
        NodeDAO.ChildAssocRefQueryCallback callback = new NodeDAO.ChildAssocRefQueryCallback() {

            public boolean preLoadNodes() {
                return true;
            }

            @Override
            public boolean orderResults() {
                return false;
            }

            public boolean handle(Pair<Long, ChildAssociationRef> childAssocPair, Pair<Long, NodeRef> parentNodePair, Pair<Long, NodeRef> childNodePair) {
                if (isPendingDelete(parentNodePair.getSecond()) || isPendingDelete(childNodePair.getSecond())) {
                    if (logger.isTraceEnabled()) {
                        logger.trace("Aspect-triggered association removal: " + "Ignoring child associations where one of the nodes is pending delete: " + childAssocPair);
                    }
                    return true;
                }
                // have to delete the child node directly and with full archival.
                if (childAssocPair.getSecond().isPrimary()) {
                    nodesToDelete.add(childNodePair);
                } else {
                    assocsToDelete.add(childAssocPair);
                }
                // More results
                return true;
            }

            public void done() {
            }
        };
        // Get all the QNames to remove
        Set<QName> assocTypeQNamesToRemove = new HashSet<QName>(aspectDef.getChildAssociations().keySet());
        nodeDAO.getChildAssocs(nodeId, assocTypeQNamesToRemove, callback);
        // Delete all the collected associations
        for (Pair<Long, ChildAssociationRef> assocPair : assocsToDelete) {
            updated = true;
            Long assocId = assocPair.getFirst();
            ChildAssociationRef assocRef = assocPair.getSecond();
            // delete the association instance - it is not primary
            invokeBeforeDeleteChildAssociation(assocRef);
            nodeDAO.deleteChildAssoc(assocId);
            invokeOnDeleteChildAssociation(assocRef);
        }
        // Cascade-delete any nodes that were attached to primary associations
        for (Pair<Long, NodeRef> childNodePair : nodesToDelete) {
            NodeRef childNodeRef = childNodePair.getSecond();
            this.deleteNode(childNodeRef);
        }
        // Gather peer associations to delete
        Map<QName, AssociationDefinition> nodeAssocDefs = aspectDef.getAssociations();
        List<Long> nodeAssocIdsToRemove = new ArrayList<Long>(13);
        List<AssociationRef> assocRefsRemoved = new ArrayList<AssociationRef>(13);
        for (Map.Entry<QName, AssociationDefinition> entry : nodeAssocDefs.entrySet()) {
            if (isPendingDelete(nodeRef)) {
                if (logger.isTraceEnabled()) {
                    logger.trace("Aspect-triggered association removal: " + "Ignoring peer associations where one of the nodes is pending delete: " + nodeRef);
                }
                continue;
            }
            if (entry.getValue().isChild()) {
                // Not interested in child assocs
                continue;
            }
            QName assocTypeQName = entry.getKey();
            Collection<Pair<Long, AssociationRef>> targetAssocRefs = nodeDAO.getTargetNodeAssocs(nodeId, assocTypeQName);
            for (Pair<Long, AssociationRef> assocPair : targetAssocRefs) {
                if (isPendingDelete(assocPair.getSecond().getTargetRef())) {
                    if (logger.isTraceEnabled()) {
                        logger.trace("Aspect-triggered association removal: " + "Ignoring peer associations where one of the nodes is pending delete: " + assocPair);
                    }
                    continue;
                }
                nodeAssocIdsToRemove.add(assocPair.getFirst());
                assocRefsRemoved.add(assocPair.getSecond());
            }
        // MNT-9580: Daisy chained cm:original associations are cascade-deleted when the first original is deleted
        // As a side-effect of the investigation of MNT-9446, it was dicovered that inbound associations (ones pointing *to* this aspect)
        // were also being removed.  This is incorrect because the aspect being removed here has no say over who points at it.
        // Therefore, do not remove inbound associations because we only define outbound associations on types and aspects.
        // Integrity checking will ensure that the correct behaviours are in place to maintain model integrity.
        }
        // Now delete peer associations
        int assocsDeleted = nodeDAO.removeNodeAssocs(nodeAssocIdsToRemove);
        for (AssociationRef assocRefRemoved : assocRefsRemoved) {
            invokeOnDeleteAssociation(assocRefRemoved);
        }
        updated = updated || assocsDeleted > 0;
    }
    // Invoke policy behaviours
    if (updated) {
        invokeOnUpdateNode(nodeRef);
    }
    if (hadAspect) {
        invokeOnRemoveAspect(nodeRef, aspectTypeQName);
    }
}
Also used : ArrayList(java.util.ArrayList) ChildAssocRefQueryCallback(org.alfresco.repo.domain.node.NodeDAO.ChildAssocRefQueryCallback) ChildAssocRefQueryCallback(org.alfresco.repo.domain.node.NodeDAO.ChildAssocRefQueryCallback) ChildAssociationRef(org.alfresco.service.cmr.repository.ChildAssociationRef) AssociationRef(org.alfresco.service.cmr.repository.AssociationRef) NodeDAO(org.alfresco.repo.domain.node.NodeDAO) NodeRef(org.alfresco.service.cmr.repository.NodeRef) Pair(org.alfresco.util.Pair) HashSet(java.util.HashSet) QName(org.alfresco.service.namespace.QName) AspectDefinition(org.alfresco.service.cmr.dictionary.AspectDefinition) ChildAssociationRef(org.alfresco.service.cmr.repository.ChildAssociationRef) PropertyDefinition(org.alfresco.service.cmr.dictionary.PropertyDefinition) ChildAssociationDefinition(org.alfresco.service.cmr.dictionary.ChildAssociationDefinition) AssociationDefinition(org.alfresco.service.cmr.dictionary.AssociationDefinition) Map(java.util.Map) HashMap(java.util.HashMap) PropertyMap(org.alfresco.util.PropertyMap) StoreArchiveMap(org.alfresco.repo.node.StoreArchiveMap) Extend(org.alfresco.traitextender.Extend)

Example 23 with AssociationDefinition

use of org.alfresco.service.cmr.dictionary.AssociationDefinition in project alfresco-repository by Alfresco.

the class AssocSourceTypeIntegrityEvent method checkIntegrity.

public void checkIntegrity(List<IntegrityRecord> eventResults) {
    QName assocTypeQName = getTypeQName();
    NodeRef sourceNodeRef = getNodeRef();
    // if the node is gone then the check is irrelevant
    QName sourceNodeTypeQName = getNodeType(sourceNodeRef);
    if (sourceNodeTypeQName == null) {
        // target or source is missing
        if (logger.isDebugEnabled()) {
            logger.debug("Ignoring integrity check - node gone: \n" + "   event: " + this);
        }
        return;
    }
    // get the association def
    AssociationDefinition assocDef = getAssocDef(eventResults, assocTypeQName);
    // the association definition must exist
    if (assocDef == null) {
        IntegrityRecord result = new IntegrityRecord("Association type does not exist: \n" + "   Source Node: " + sourceNodeRef + "\n" + "   Source Node Type: " + sourceNodeTypeQName + "\n" + "   Association Type: " + assocTypeQName);
        eventResults.add(result);
        return;
    }
    // perform required checks
    checkSourceType(eventResults, assocDef, sourceNodeRef, sourceNodeTypeQName);
}
Also used : NodeRef(org.alfresco.service.cmr.repository.NodeRef) AssociationDefinition(org.alfresco.service.cmr.dictionary.AssociationDefinition) QName(org.alfresco.service.namespace.QName)

Example 24 with AssociationDefinition

use of org.alfresco.service.cmr.dictionary.AssociationDefinition in project alfresco-repository by Alfresco.

the class AssocTargetRoleIntegrityEvent method checkIntegrity.

public void checkIntegrity(List<IntegrityRecord> eventResults) {
    QName assocTypeQName = getTypeQName();
    QName assocQName = getQName();
    NodeRef sourceNodeRef = getNodeRef();
    // get the association def
    AssociationDefinition assocDef = getAssocDef(eventResults, assocTypeQName);
    // the association definition must exist
    if (assocDef == null) {
        IntegrityRecord result = new IntegrityRecord("Association type does not exist: \n" + "   Association Type: " + assocTypeQName);
        eventResults.add(result);
        return;
    }
    // check that we are dealing with child associations
    if (assocQName == null) {
        throw new IllegalArgumentException("The association qualified name must be supplied");
    }
    if (!assocDef.isChild()) {
        throw new UnsupportedOperationException("This operation is only relevant to child associations");
    }
    ChildAssociationDefinition childAssocDef = (ChildAssociationDefinition) assocDef;
    // perform required checks
    checkAssocQNameRegex(eventResults, childAssocDef, assocQName, sourceNodeRef);
}
Also used : NodeRef(org.alfresco.service.cmr.repository.NodeRef) AssociationDefinition(org.alfresco.service.cmr.dictionary.AssociationDefinition) ChildAssociationDefinition(org.alfresco.service.cmr.dictionary.ChildAssociationDefinition) ChildAssociationDefinition(org.alfresco.service.cmr.dictionary.ChildAssociationDefinition) QName(org.alfresco.service.namespace.QName)

Example 25 with AssociationDefinition

use of org.alfresco.service.cmr.dictionary.AssociationDefinition in project alfresco-repository by Alfresco.

the class AssocTargetTypeIntegrityEvent method checkIntegrity.

public void checkIntegrity(List<IntegrityRecord> eventResults) {
    QName assocTypeQName = getTypeQName();
    NodeRef targetNodeRef = getNodeRef();
    // if the node is gone then the check is irrelevant
    QName targetNodeTypeQName = getNodeType(targetNodeRef);
    if (targetNodeTypeQName == null) {
        // target or source is missing
        if (logger.isDebugEnabled()) {
            logger.debug("Ignoring integrity check - node gone: \n" + "   event: " + this);
        }
        return;
    }
    // get the association def
    AssociationDefinition assocDef = getAssocDef(eventResults, assocTypeQName);
    // the association definition must exist
    if (assocDef == null) {
        IntegrityRecord result = new IntegrityRecord("Association type does not exist: \n" + "   Target Node: " + targetNodeRef + "\n" + "   Target Node Type: " + targetNodeTypeQName + "\n" + "   Association Type: " + assocTypeQName);
        eventResults.add(result);
        return;
    }
    // perform required checks
    checkTargetType(eventResults, assocDef, targetNodeRef, targetNodeTypeQName);
}
Also used : NodeRef(org.alfresco.service.cmr.repository.NodeRef) AssociationDefinition(org.alfresco.service.cmr.dictionary.AssociationDefinition) QName(org.alfresco.service.namespace.QName)

Aggregations

AssociationDefinition (org.alfresco.service.cmr.dictionary.AssociationDefinition)60 QName (org.alfresco.service.namespace.QName)46 PropertyDefinition (org.alfresco.service.cmr.dictionary.PropertyDefinition)24 ChildAssociationDefinition (org.alfresco.service.cmr.dictionary.ChildAssociationDefinition)19 NodeRef (org.alfresco.service.cmr.repository.NodeRef)17 TypeDefinition (org.alfresco.service.cmr.dictionary.TypeDefinition)15 HashMap (java.util.HashMap)13 Serializable (java.io.Serializable)11 ArrayList (java.util.ArrayList)11 ClassDefinition (org.alfresco.service.cmr.dictionary.ClassDefinition)9 DataTypeDefinition (org.alfresco.service.cmr.dictionary.DataTypeDefinition)7 AlfrescoRuntimeException (org.alfresco.error.AlfrescoRuntimeException)6 AspectDefinition (org.alfresco.service.cmr.dictionary.AspectDefinition)6 ChildAssociationRef (org.alfresco.service.cmr.repository.ChildAssociationRef)6 Collection (java.util.Collection)5 AssociationRef (org.alfresco.service.cmr.repository.AssociationRef)5 HashSet (java.util.HashSet)4 List (java.util.List)4 Map (java.util.Map)4 Pair (org.alfresco.util.Pair)3