use of org.alfresco.service.cmr.repository.AssociationRef in project alfresco-repository by Alfresco.
the class DbNodeServiceImpl method removeAssociation.
@Extend(traitAPI = NodeServiceTrait.class, extensionAPI = NodeServiceExtension.class)
public void removeAssociation(NodeRef sourceRef, NodeRef targetRef, QName assocTypeQName) throws InvalidNodeRefException {
// The node(s) involved may not be pending deletion
checkPendingDelete(sourceRef);
checkPendingDelete(targetRef);
Pair<Long, NodeRef> sourceNodePair = getNodePairNotNull(sourceRef);
Long sourceNodeId = sourceNodePair.getFirst();
Pair<Long, NodeRef> targetNodePair = getNodePairNotNull(targetRef);
Long targetNodeId = targetNodePair.getFirst();
AssociationRef assocRef = new AssociationRef(sourceRef, assocTypeQName, targetRef);
// Invoke policy behaviours
invokeBeforeDeleteAssociation(assocRef);
// delete it
int assocsDeleted = nodeDAO.removeNodeAssoc(sourceNodeId, targetNodeId, assocTypeQName);
if (assocsDeleted > 0) {
// Invoke policy behaviours
invokeOnDeleteAssociation(assocRef);
}
}
use of org.alfresco.service.cmr.repository.AssociationRef in project alfresco-repository by Alfresco.
the class DbNodeServiceImpl method setAssociations.
@Override
@Extend(traitAPI = NodeServiceTrait.class, extensionAPI = NodeServiceExtension.class)
public void setAssociations(NodeRef sourceRef, QName assocTypeQName, List<NodeRef> targetRefs) {
// The node(s) involved may not be pending deletion
checkPendingDelete(sourceRef);
Pair<Long, NodeRef> sourceNodePair = getNodePairNotNull(sourceRef);
Long sourceNodeId = sourceNodePair.getFirst();
// First get the existing associations
Collection<Pair<Long, AssociationRef>> assocsBefore = nodeDAO.getTargetNodeAssocs(sourceNodeId, assocTypeQName);
Map<NodeRef, Long> targetRefsBefore = new HashMap<NodeRef, Long>(assocsBefore.size());
Map<NodeRef, Long> toRemoveMap = new HashMap<NodeRef, Long>(assocsBefore.size());
for (Pair<Long, AssociationRef> assocBeforePair : assocsBefore) {
Long id = assocBeforePair.getFirst();
NodeRef nodeRef = assocBeforePair.getSecond().getTargetRef();
targetRefsBefore.put(nodeRef, id);
toRemoveMap.put(nodeRef, id);
}
// Work out which associations need to be removed
toRemoveMap.keySet().removeAll(targetRefs);
// Fire policies for redundant assocs
for (NodeRef targetRef : toRemoveMap.keySet()) {
AssociationRef assocRef = new AssociationRef(sourceRef, assocTypeQName, targetRef);
invokeBeforeDeleteAssociation(assocRef);
}
// Remove reduncant assocs
List<Long> toRemoveIds = new ArrayList<Long>(toRemoveMap.values());
nodeDAO.removeNodeAssocs(toRemoveIds);
// Work out which associations need to be added
Set<NodeRef> toAdd = new HashSet<NodeRef>(targetRefs);
toAdd.removeAll(targetRefsBefore.keySet());
// Iterate over the desired result and create new or reset indexes
int assocIndex = 1;
for (NodeRef targetNodeRef : targetRefs) {
// The node(s) involved may not be pending deletion
checkPendingDelete(targetNodeRef);
Long id = targetRefsBefore.get(targetNodeRef);
// Is this an existing assoc?
if (id != null) {
// Update it
nodeDAO.setNodeAssocIndex(id, assocIndex);
} else {
Long targetNodeId = getNodePairNotNull(targetNodeRef).getFirst();
nodeDAO.newNodeAssoc(sourceNodeId, targetNodeId, assocTypeQName, assocIndex);
}
assocIndex++;
}
// Invoke policy behaviours
for (NodeRef targetNodeRef : toAdd) {
AssociationRef assocRef = new AssociationRef(sourceRef, assocTypeQName, targetNodeRef);
invokeOnCreateAssociation(assocRef);
}
}
use of org.alfresco.service.cmr.repository.AssociationRef in project alfresco-repository by Alfresco.
the class DbNodeServiceImpl method getTargetAssocsByPropertyValue.
@Override
@Extend(traitAPI = NodeServiceTrait.class, extensionAPI = NodeServiceExtension.class)
public List<AssociationRef> getTargetAssocsByPropertyValue(NodeRef sourceRef, QNamePattern qnamePattern, QName propertyQName, Serializable propertyValue) {
Pair<Long, NodeRef> sourceNodePair = getNodePairNotNull(sourceRef);
Long sourceNodeId = sourceNodePair.getFirst();
QName qnameFilter = null;
if (qnamePattern instanceof QName) {
qnameFilter = (QName) qnamePattern;
}
// Check the QName is not one of the "special" system maintained ones.
if (getChildAssocsByPropertyValueBannedProps.contains(propertyQName)) {
throw new IllegalArgumentException("getTargetAssocsByPropertyValue does not allow search of system maintained properties: " + propertyQName);
}
Collection<Pair<Long, AssociationRef>> assocPairs = nodeDAO.getTargetAssocsByPropertyValue(sourceNodeId, qnameFilter, propertyQName, propertyValue);
List<AssociationRef> nodeAssocRefs = new ArrayList<AssociationRef>(assocPairs.size());
for (Pair<Long, AssociationRef> assocPair : assocPairs) {
AssociationRef assocRef = assocPair.getSecond();
// check qname pattern, if not already filtered
if (qnameFilter == null && !qnamePattern.isMatch(assocRef.getTypeQName())) {
// the assoc name doesn't match the pattern given
continue;
}
nodeAssocRefs.add(assocRef);
}
// done
return nodeAssocRefs;
}
use of org.alfresco.service.cmr.repository.AssociationRef in project alfresco-repository by Alfresco.
the class AssocSourceMultiplicityIntegrityEvent method checkSourceMultiplicity.
/**
* Checks that the source multiplicity has not been violated for the
* target of the association.
*/
protected void checkSourceMultiplicity(List<IntegrityRecord> eventResults, AssociationDefinition assocDef, QName assocTypeQName, NodeRef targetNodeRef) {
// get the source multiplicity
boolean mandatory = assocDef.isSourceMandatory();
boolean allowMany = assocDef.isSourceMany();
// do we need to check
if (!mandatory && allowMany) {
// it is not mandatory and it allows many on both sides of the assoc
return;
}
// check the target of the association if this is a delete
if (isDelete) {
// get the class the association is defined for and see if it is an aspect
ClassDefinition classDef = assocDef.getTargetClass();
if (classDef.isAspect()) {
// there's no need to check multiplicity
if (!this.nodeService.hasAspect(targetNodeRef, classDef.getName())) {
return;
}
}
}
int actualSize = 0;
if (assocDef.isChild()) {
// check the parent assocs present
List<ChildAssociationRef> parentAssocRefs = nodeService.getParentAssocs(targetNodeRef, assocTypeQName, RegexQNamePattern.MATCH_ALL);
actualSize = parentAssocRefs.size();
} else {
// check the source assocs present
List<AssociationRef> sourceAssocRefs = nodeService.getSourceAssocs(targetNodeRef, assocTypeQName);
actualSize = sourceAssocRefs.size();
}
if ((mandatory && actualSize == 0) || (!allowMany && actualSize > 1)) {
if (actualSize == 0) {
// multiplicity (a feature of the source type/aspect) is not relevant
return;
}
String parentOrSourceStr = (assocDef.isChild() ? "parent" : "source");
IntegrityRecord result = new IntegrityRecord("The association " + parentOrSourceStr + " multiplicity has been violated: \n" + " Target Node: " + targetNodeRef + "\n" + " Association: " + assocDef + "\n" + " Required " + parentOrSourceStr + " Multiplicity: " + getMultiplicityString(mandatory, allowMany) + "\n" + " Actual " + parentOrSourceStr + " Multiplicity: " + actualSize);
eventResults.add(result);
}
}
use of org.alfresco.service.cmr.repository.AssociationRef in project alfresco-repository by Alfresco.
the class AssocTargetMultiplicityIntegrityEvent method checkTargetMultiplicity.
/**
* Checks that the target multiplicity has not been violated for the
* source of the association.
*/
protected void checkTargetMultiplicity(List<IntegrityRecord> eventResults, AssociationDefinition assocDef, QName assocTypeQName, NodeRef sourceNodeRef) {
// get the source multiplicity
boolean mandatory = assocDef.isTargetMandatory();
boolean allowMany = assocDef.isTargetMany();
boolean enforced = assocDef.isTargetMandatoryEnforced();
// do we need to check
if (!(mandatory && enforced) && allowMany) {
// it is not mandatory and it allows many on both sides of the assoc
return;
}
// check the source of the association if this is a delete
if (isDelete) {
// get the class the association is defined for and see if it is an aspect
ClassDefinition classDef = assocDef.getSourceClass();
if (classDef.isAspect()) {
// there's no need to check multiplicity
if (!this.nodeService.hasAspect(sourceNodeRef, classDef.getName())) {
return;
}
}
}
int actualSize = 0;
if (assocDef.isChild()) {
// check the child assocs present
List<ChildAssociationRef> childAssocRefs = nodeService.getChildAssocs(sourceNodeRef, assocTypeQName, RegexQNamePattern.MATCH_ALL);
actualSize = childAssocRefs.size();
} else {
// check the target assocs present
List<AssociationRef> targetAssocRefs = nodeService.getTargetAssocs(sourceNodeRef, assocTypeQName);
actualSize = targetAssocRefs.size();
}
if (((mandatory && enforced) && actualSize == 0) || (!allowMany && actualSize > 1)) {
if (actualSize == 0) {
// Double check that the association source is still present
ClassDefinition classDef = assocDef.getSourceClass();
if (classDef.isAspect() && !nodeService.hasAspect(sourceNodeRef, classDef.getName())) {
// The source is an aspect but the aspect is not present
return;
}
}
String childOrTargetStr = (assocDef.isChild() ? "child" : "target");
IntegrityRecord result = new IntegrityRecord("The association " + childOrTargetStr + " multiplicity has been violated: \n" + " Source Node: " + sourceNodeRef + "\n" + " Association: " + assocDef + "\n" + " Required " + childOrTargetStr + " Multiplicity: " + getMultiplicityString(mandatory, allowMany) + "\n" + " Actual " + childOrTargetStr + " Multiplicity: " + actualSize);
eventResults.add(result);
}
}
Aggregations