diff --git a/source/java/org/alfresco/repo/node/integrity/AssocSourceMultiplicityIntegrityEvent.java b/source/java/org/alfresco/repo/node/integrity/AssocSourceMultiplicityIntegrityEvent.java
index 9db9e71bde..6f57aeebdd 100644
--- a/source/java/org/alfresco/repo/node/integrity/AssocSourceMultiplicityIntegrityEvent.java
+++ b/source/java/org/alfresco/repo/node/integrity/AssocSourceMultiplicityIntegrityEvent.java
@@ -167,6 +167,17 @@ public class AssocSourceMultiplicityIntegrityEvent extends AbstractIntegrityEven
if ((mandatory && actualSize == 0) || (!allowMany && actualSize > 1))
{
+ if (actualSize == 0)
+ {
+ // Double check that the association source is still present
+ ClassDefinition classDef = assocDef.getTargetClass();
+ if (classDef.isAspect() && !nodeService.hasAspect(targetNodeRef, classDef.getName()))
+ {
+ // The target is an aspect but the aspect is not present
+ return;
+ }
+ }
+
String parentOrSourceStr = (assocDef.isChild() ? "parent" : "source");
IntegrityRecord result = new IntegrityRecord(
"The association " + parentOrSourceStr + " multiplicity has been violated: \n" +
diff --git a/source/java/org/alfresco/repo/node/integrity/AssocSourceTypeIntegrityEvent.java b/source/java/org/alfresco/repo/node/integrity/AssocSourceTypeIntegrityEvent.java
index 1313498adc..d6b770cf65 100644
--- a/source/java/org/alfresco/repo/node/integrity/AssocSourceTypeIntegrityEvent.java
+++ b/source/java/org/alfresco/repo/node/integrity/AssocSourceTypeIntegrityEvent.java
@@ -29,6 +29,7 @@ import org.alfresco.service.cmr.dictionary.TypeDefinition;
import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.cmr.repository.NodeService;
import org.alfresco.service.namespace.QName;
+import org.alfresco.service.namespace.RegexQNamePattern;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
@@ -127,6 +128,24 @@ public class AssocSourceTypeIntegrityEvent extends AbstractIntegrityEvent
}
if (!found)
{
+ // Actually make sure that the association still exists
+ if (assocDef.isChild())
+ {
+ if (nodeService.getChildAssocs(sourceNodeRef, assocDef.getName(), RegexQNamePattern.MATCH_ALL).size() == 0)
+ {
+ // The association does not exist any more
+ return;
+ }
+ }
+ else
+ {
+ if (nodeService.getTargetAssocs(sourceNodeRef, assocDef.getName()).size() == 0)
+ {
+ // The association does not exist any more
+ return;
+ }
+ }
+ // The association is still present
IntegrityRecord result = new IntegrityRecord(
"The association source is missing the aspect required for this association: \n" +
" Source Node: " + sourceNodeRef + "\n" +
diff --git a/source/java/org/alfresco/repo/node/integrity/AssocTargetMultiplicityIntegrityEvent.java b/source/java/org/alfresco/repo/node/integrity/AssocTargetMultiplicityIntegrityEvent.java
index 5e345a5d3c..4a577f7cd1 100644
--- a/source/java/org/alfresco/repo/node/integrity/AssocTargetMultiplicityIntegrityEvent.java
+++ b/source/java/org/alfresco/repo/node/integrity/AssocTargetMultiplicityIntegrityEvent.java
@@ -167,6 +167,17 @@ public class AssocTargetMultiplicityIntegrityEvent extends AbstractIntegrityEven
if ((mandatory && 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" +
diff --git a/source/java/org/alfresco/repo/node/integrity/AssocTargetTypeIntegrityEvent.java b/source/java/org/alfresco/repo/node/integrity/AssocTargetTypeIntegrityEvent.java
index 7171401f02..17a66e38b5 100644
--- a/source/java/org/alfresco/repo/node/integrity/AssocTargetTypeIntegrityEvent.java
+++ b/source/java/org/alfresco/repo/node/integrity/AssocTargetTypeIntegrityEvent.java
@@ -29,6 +29,7 @@ import org.alfresco.service.cmr.dictionary.TypeDefinition;
import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.cmr.repository.NodeService;
import org.alfresco.service.namespace.QName;
+import org.alfresco.service.namespace.RegexQNamePattern;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
@@ -127,13 +128,34 @@ public class AssocTargetTypeIntegrityEvent extends AbstractIntegrityEvent
}
if (!found)
{
- IntegrityRecord result = new IntegrityRecord(
- "The association target is missing the aspect required for this association: \n" +
- " Target Node: " + targetNodeRef + "\n" +
- " Association: " + assocDef + "\n" +
- " Required Target Aspect: " + targetDef.getName() + "\n" +
- " Actual Target Aspects: " + targetAspects);
- eventResults.add(result);
+ // Actually make sure that the association still exists
+ if (assocDef.isChild())
+ {
+ if (nodeService.getParentAssocs(targetNodeRef, assocDef.getName(), RegexQNamePattern.MATCH_ALL).size() == 0)
+ {
+ // The association does not exist any more
+ return;
+ }
+ }
+ else
+ {
+ if (nodeService.getSourceAssocs(targetNodeRef, assocDef.getName()).size() == 0)
+ {
+ // The association does not exist any more
+ return;
+ }
+ }
+ // The association is still present
+ if (nodeService.getSourceAssocs(targetNodeRef, assocDef.getName()).size() > 0)
+ {
+ IntegrityRecord result = new IntegrityRecord(
+ "The association target is missing the aspect required for this association: \n" +
+ " Target Node: " + targetNodeRef + "\n" +
+ " Association: " + assocDef + "\n" +
+ " Required Target Aspect: " + targetDef.getName() + "\n" +
+ " Actual Target Aspects: " + targetAspects);
+ eventResults.add(result);
+ }
}
}
else
diff --git a/source/java/org/alfresco/repo/node/integrity/IntegrityTest.java b/source/java/org/alfresco/repo/node/integrity/IntegrityTest.java
index 5eba3dc4af..01af365813 100644
--- a/source/java/org/alfresco/repo/node/integrity/IntegrityTest.java
+++ b/source/java/org/alfresco/repo/node/integrity/IntegrityTest.java
@@ -73,6 +73,7 @@ public class IntegrityTest extends TestCase
public static final QName TEST_ASSOC_NODE_ZEROMANY_ZEROMANY = QName.createQName(NAMESPACE, "assoc-0to* - 0to*");
public static final QName TEST_ASSOC_CHILD_ZEROMANY_ZEROMANY = QName.createQName(NAMESPACE, "child-0to* - 0to*");
public static final QName TEST_ASSOC_NODE_ONE_ONE = QName.createQName(NAMESPACE, "assoc-1to1 - 1to1");
+ public static final QName TEST_ASSOC_NODE_ONE_MANY = QName.createQName(NAMESPACE, "assoc-1to1 - 0to*");
public static final QName TEST_ASSOC_CHILD_ONE_ONE = QName.createQName(NAMESPACE, "child-1to1 - 1to1");
public static final QName TEST_ASSOC_ASPECT_ONE_ONE = QName.createQName(NAMESPACE, "aspect-assoc-1to1 - 1to1");
public static final QName TEST_ASSOC_CHILD_NON_ENFORCED = QName.createQName(NAMESPACE, "child-non-enforced");
@@ -436,4 +437,15 @@ public class IntegrityTest extends TestCase
checkIntegrityExpectFailure("Failed to detect excess target cardinality for one-to-one assocs", 3);
}
+
+ public void testExcessTargetsOfOneToManyAssocs() throws Exception
+ {
+ NodeRef source = createNode("abc", TEST_TYPE_WITH_ASSOCS, null);
+ NodeRef target1 = createNode("target1", TEST_TYPE_WITHOUT_ANYTHING, null);
+ NodeRef target2 = createNode("target2", TEST_TYPE_WITHOUT_ANYTHING, null);
+ nodeService.createAssociation(source, target1, TEST_ASSOC_NODE_ONE_MANY);
+ nodeService.createAssociation(source, target2, TEST_ASSOC_NODE_ONE_MANY);
+
+ checkIntegrityExpectFailure("Failed to detect excess source cardinality for one-to-many assocs", 1);
+ }
}
diff --git a/source/java/org/alfresco/repo/node/integrity/IntegrityTest_model.xml b/source/java/org/alfresco/repo/node/integrity/IntegrityTest_model.xml
index b6883d345a..8fc1ece87c 100644
--- a/source/java/org/alfresco/repo/node/integrity/IntegrityTest_model.xml
+++ b/source/java/org/alfresco/repo/node/integrity/IntegrityTest_model.xml
@@ -91,6 +91,17 @@
false
+
+
+ true
+ false
+
+
+ test:typeWithoutAnything
+ false
+ true
+
+