diff --git a/source/java/org/alfresco/repo/node/db/DbNodeServiceImpl.java b/source/java/org/alfresco/repo/node/db/DbNodeServiceImpl.java index 97278c4072..8db2bf6f92 100644 --- a/source/java/org/alfresco/repo/node/db/DbNodeServiceImpl.java +++ b/source/java/org/alfresco/repo/node/db/DbNodeServiceImpl.java @@ -595,20 +595,6 @@ public class DbNodeServiceImpl extends AbstractNodeServiceImpl // get the node Node node = getNodeNotNull(nodeRef); - // check that the aspect may be removed - TypeDefinition nodeTypeDef = dictionaryService.getType(node.getTypeQName()); - if (nodeTypeDef == null) - { - throw new InvalidNodeRefException("The node type is no longer valid: " + nodeRef, nodeRef); - } - List defaultAspects = nodeTypeDef.getDefaultAspects(); - if (defaultAspects.contains(aspectDef)) - { - throw new InvalidAspectException( - "The aspect is a default for the node's type and cannot be removed: " + aspectTypeQName, - aspectTypeQName); - } - // remove the aspect, if present boolean removed = node.getAspects().remove(aspectTypeQName); // if the aspect was present, remove the associated properties diff --git a/source/java/org/alfresco/repo/node/integrity/AspectsIntegrityEvent.java b/source/java/org/alfresco/repo/node/integrity/AspectsIntegrityEvent.java new file mode 100644 index 0000000000..0632dadeca --- /dev/null +++ b/source/java/org/alfresco/repo/node/integrity/AspectsIntegrityEvent.java @@ -0,0 +1,99 @@ +/* + * Copyright (C) 2005 Alfresco, Inc. + * + * Licensed under the Mozilla Public License version 1.1 + * with a permitted attribution clause. You may obtain a + * copy of the License at + * + * http://www.alfresco.org/legal/license.txt + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, + * either express or implied. See the License for the specific + * language governing permissions and limitations under the + * License. + */ +package org.alfresco.repo.node.integrity; + +import java.util.List; +import java.util.Set; + +import org.alfresco.service.cmr.dictionary.AspectDefinition; +import org.alfresco.service.cmr.dictionary.DictionaryService; +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.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +/** + * Event raised to check nodes' aspects + * + * @author Derek Hulley + */ +public class AspectsIntegrityEvent extends AbstractIntegrityEvent +{ + private static Log logger = LogFactory.getLog(AspectsIntegrityEvent.class); + + protected AspectsIntegrityEvent( + NodeService nodeService, + DictionaryService dictionaryService, + NodeRef nodeRef) + { + super(nodeService, dictionaryService, nodeRef, null, null); + } + + public void checkIntegrity(List eventResults) + { + NodeRef nodeRef = getNodeRef(); + if (!nodeService.exists(nodeRef)) + { + // node has gone + if (logger.isDebugEnabled()) + { + logger.debug("Event ignored - node gone: " + this); + } + eventResults.clear(); + return; + } + else + { + checkMandatoryAspects(getNodeRef(), eventResults); + } + } + + /** + * Checks that the node has the required mandatory aspects applied + */ + private void checkMandatoryAspects(NodeRef nodeRef, List eventResults) + { + Set aspects = nodeService.getAspects(nodeRef); + + // get the node type + QName nodeTypeQName = nodeService.getType(nodeRef); + // get the aspects that should exist + TypeDefinition typeDef = dictionaryService.getType(nodeTypeQName); + List mandatoryAspectDefs = typeDef.getDefaultAspects(); + + // check + for (AspectDefinition aspect : mandatoryAspectDefs) + { + if (aspects.contains(aspect.getName())) + { + // it's fine + continue; + } + IntegrityRecord result = new IntegrityRecord( + "Mandatory aspect not set: \n" + + " Node: " + nodeRef + "\n" + + " Type: " + nodeTypeQName + "\n" + + " Aspect: " + aspect.getName()); + eventResults.add(result); + // next one + continue; + } + // done + } +} diff --git a/source/java/org/alfresco/repo/node/integrity/IntegrityChecker.java b/source/java/org/alfresco/repo/node/integrity/IntegrityChecker.java index 4cae7893f6..1af48b8f78 100644 --- a/source/java/org/alfresco/repo/node/integrity/IntegrityChecker.java +++ b/source/java/org/alfresco/repo/node/integrity/IntegrityChecker.java @@ -278,19 +278,23 @@ public class IntegrityChecker */ public void onCreateNode(ChildAssociationRef childAssocRef) { + NodeRef childRef = childAssocRef.getChildRef(); IntegrityEvent event = null; // check properties on child node event = new PropertiesIntegrityEvent( nodeService, dictionaryService, - childAssocRef.getChildRef()); + childRef); save(event); + // check that the multiplicity and other properties of the new association are allowed onCreateChildAssociation(childAssocRef); + // check mandatory aspects + event = new AspectsIntegrityEvent(nodeService, dictionaryService, childRef); + save(event); // check for associations defined on the new node (child) - NodeRef childRef = childAssocRef.getChildRef(); QName childNodeTypeQName = nodeService.getType(childRef); ClassDefinition nodeTypeDef = dictionaryService.getClass(childNodeTypeQName); if (nodeTypeDef == null) @@ -370,10 +374,15 @@ public class IntegrityChecker } /** - * No checking performed: The property changes will be handled + * @see AspectsIntegrityEvent */ public void onRemoveAspect(NodeRef nodeRef, QName aspectTypeQName) { + IntegrityEvent event = null; + // check mandatory aspects + event = new AspectsIntegrityEvent(nodeService, dictionaryService, nodeRef); + save(event); + } /** diff --git a/source/java/org/alfresco/repo/node/integrity/IntegrityTest.java b/source/java/org/alfresco/repo/node/integrity/IntegrityTest.java index c036134d4d..036ddbf033 100644 --- a/source/java/org/alfresco/repo/node/integrity/IntegrityTest.java +++ b/source/java/org/alfresco/repo/node/integrity/IntegrityTest.java @@ -135,8 +135,22 @@ public class IntegrityTest extends TestCase public void tearDown() throws Exception { - authenticationComponent.clearCurrentSecurityContext(); - txn.rollback(); + try + { + authenticationComponent.clearCurrentSecurityContext(); + } + catch (Throwable e) + { + e.printStackTrace(); + } + try + { + txn.rollback(); + } + catch (Throwable e) + { + e.printStackTrace(); + } } /** @@ -220,6 +234,15 @@ public class IntegrityTest extends TestCase checkIntegrityNoFailure(); } + public void testRemoveMandatoryAspect() throws Exception + { + NodeRef nodeRef = createNode("abc", TEST_TYPE_WITH_ASPECT, allProperties); + // just remove the aspect + nodeService.removeAspect(nodeRef, TEST_ASPECT_WITH_PROPERTIES); + + checkIntegrityExpectFailure("Failed to removal of mandatory aspect", 1); + } + public void testCreateTargetOfAssocsWithMandatorySourcesPresent() throws Exception { // this is the target of 3 assoc types where the source cardinality is 1..1