Enhanced 'beforeCreateChildAssociaton' and 'onCreateChildAssociation' to carry an 'isNewNode' flag.

Fixed Lock and Rules to react correctly to this new information.


git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@6003 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
This commit is contained in:
Derek Hulley
2007-06-18 11:29:00 +00:00
parent 832c1b599e
commit 6e0c406488
9 changed files with 106 additions and 45 deletions

View File

@@ -489,7 +489,8 @@ public class LockServiceImpl implements LockService,
NodeRef parentNodeRef, NodeRef parentNodeRef,
NodeRef childNodeRef, NodeRef childNodeRef,
QName assocTypeQName, QName assocTypeQName,
QName assocQName) QName assocQName,
boolean isNewNode)
{ {
checkForLock(parentNodeRef); checkForLock(parentNodeRef);
} }

View File

@@ -439,19 +439,19 @@ public abstract class AbstractNodeServiceImpl implements NodeService
* @see NodeServicePolicies.BeforeCreateChildAssociationPolicy#beforeCreateChildAssociation(NodeRef, * @see NodeServicePolicies.BeforeCreateChildAssociationPolicy#beforeCreateChildAssociation(NodeRef,
* NodeRef, QName, QName) * NodeRef, QName, QName)
*/ */
protected void invokeBeforeCreateChildAssociation(NodeRef parentNodeRef, NodeRef childNodeRef, QName assocTypeQName, QName assocQName) protected void invokeBeforeCreateChildAssociation(NodeRef parentNodeRef, NodeRef childNodeRef, QName assocTypeQName, QName assocQName, boolean isNewNode)
{ {
// get qnames to invoke against // get qnames to invoke against
Set<QName> qnames = getTypeAndAspectQNames(parentNodeRef); Set<QName> qnames = getTypeAndAspectQNames(parentNodeRef);
// execute policy for node type // execute policy for node type
NodeServicePolicies.BeforeCreateChildAssociationPolicy policy = beforeCreateChildAssociationDelegate.get(parentNodeRef, qnames, assocTypeQName); NodeServicePolicies.BeforeCreateChildAssociationPolicy policy = beforeCreateChildAssociationDelegate.get(parentNodeRef, qnames, assocTypeQName);
policy.beforeCreateChildAssociation(parentNodeRef, childNodeRef, assocTypeQName, assocQName); policy.beforeCreateChildAssociation(parentNodeRef, childNodeRef, assocTypeQName, assocQName, isNewNode);
} }
/** /**
* @see NodeServicePolicies.OnCreateChildAssociationPolicy#onCreateChildAssociation(ChildAssociationRef) * @see NodeServicePolicies.OnCreateChildAssociationPolicy#onCreateChildAssociation(ChildAssociationRef)
*/ */
protected void invokeOnCreateChildAssociation(ChildAssociationRef childAssocRef) protected void invokeOnCreateChildAssociation(ChildAssociationRef childAssocRef, boolean isNewNode)
{ {
// Get the parent reference and the assoc type qName // Get the parent reference and the assoc type qName
NodeRef parentNodeRef = childAssocRef.getParentRef(); NodeRef parentNodeRef = childAssocRef.getParentRef();
@@ -460,7 +460,7 @@ public abstract class AbstractNodeServiceImpl implements NodeService
Set<QName> qnames = getTypeAndAspectQNames(parentNodeRef); Set<QName> qnames = getTypeAndAspectQNames(parentNodeRef);
// execute policy for node type and aspects // execute policy for node type and aspects
NodeServicePolicies.OnCreateChildAssociationPolicy policy = onCreateChildAssociationDelegate.get(parentNodeRef, qnames, assocTypeQName); NodeServicePolicies.OnCreateChildAssociationPolicy policy = onCreateChildAssociationDelegate.get(parentNodeRef, qnames, assocTypeQName);
policy.onCreateChildAssociation(childAssocRef); policy.onCreateChildAssociation(childAssocRef, isNewNode);
} }
/** /**

View File

@@ -239,16 +239,18 @@ public interface NodeServicePolicies
/** /**
* Called before a node child association is created. * Called before a node child association is created.
* *
* @param parentNodeRef * @param parentNodeRef the parent node reference
* @param childNodeRef * @param childNodeRef the child node reference
* @param assocTypeQName the type of the association * @param assocTypeQName the type of the association
* @param assocQName the name of the association * @param assocQName the name of the association
* @param isNewNode <tt>true</tt> if the node is new or <tt>false</tt> if the node is being linked in
*/ */
public void beforeCreateChildAssociation( public void beforeCreateChildAssociation(
NodeRef parentNodeRef, NodeRef parentNodeRef,
NodeRef childNodeRef, NodeRef childNodeRef,
QName assocTypeQName, QName assocTypeQName,
QName assocQName); QName assocQName,
boolean isNewNode);
} }
public interface OnCreateChildAssociationPolicy extends AssociationPolicy public interface OnCreateChildAssociationPolicy extends AssociationPolicy
@@ -256,9 +258,10 @@ public interface NodeServicePolicies
/** /**
* Called after a node child association has been created. * Called after a node child association has been created.
* *
* @param childAssocRef the child association that has been created * @param childAssocRef the child association that has been created
* @param isNewNode <tt>true</tt> if the node is new or <tt>false</tt> if the node is being linked in
*/ */
public void onCreateChildAssociation(ChildAssociationRef childAssocRef); public void onCreateChildAssociation(ChildAssociationRef childAssocRef, boolean isNewNode);
} }
public interface BeforeDeleteChildAssociationPolicy extends AssociationPolicy public interface BeforeDeleteChildAssociationPolicy extends AssociationPolicy

View File

@@ -322,7 +322,7 @@ public class DbNodeServiceImpl extends AbstractNodeServiceImpl
NodeRef childNodeRef = childNode.getNodeRef(); NodeRef childNodeRef = childNode.getNodeRef();
// We now have enough to declare the child association creation // We now have enough to declare the child association creation
invokeBeforeCreateChildAssociation(parentRef, childNodeRef, assocTypeQName, assocQName); invokeBeforeCreateChildAssociation(parentRef, childNodeRef, assocTypeQName, assocQName, true);
// Get the parent node // Get the parent node
Node parentNode = getNodeNotNull(parentRef); Node parentNode = getNodeNotNull(parentRef);
@@ -354,7 +354,7 @@ public class DbNodeServiceImpl extends AbstractNodeServiceImpl
// Invoke policy behaviour // Invoke policy behaviour
invokeOnCreateNode(childAssocRef); invokeOnCreateNode(childAssocRef);
invokeOnCreateChildAssociation(childAssocRef); invokeOnCreateChildAssociation(childAssocRef, true);
if (propertiesAfter != null) if (propertiesAfter != null)
{ {
invokeOnUpdateProperties(childAssocRef.getChildRef(), propertiesBefore, propertiesAfter); invokeOnUpdateProperties(childAssocRef.getChildRef(), propertiesBefore, propertiesAfter);
@@ -427,7 +427,7 @@ public class DbNodeServiceImpl extends AbstractNodeServiceImpl
else else
{ {
invokeBeforeDeleteChildAssociation(oldAssocRef); invokeBeforeDeleteChildAssociation(oldAssocRef);
invokeBeforeCreateChildAssociation(newParentRef, nodeToMoveRef, assocTypeQName, assocQName); invokeBeforeCreateChildAssociation(newParentRef, nodeToMoveRef, assocTypeQName, assocQName, false);
} }
// remove the child assoc from the old parent // remove the child assoc from the old parent
@@ -467,7 +467,7 @@ public class DbNodeServiceImpl extends AbstractNodeServiceImpl
} }
else else
{ {
invokeOnCreateChildAssociation(newAssoc.getChildAssocRef()); invokeOnCreateChildAssociation(newAssoc.getChildAssocRef(), false);
invokeOnDeleteChildAssociation(oldAssoc.getChildAssocRef()); invokeOnDeleteChildAssociation(oldAssoc.getChildAssocRef());
} }
invokeOnMoveNode(oldAssocRef, newAssocRef); invokeOnMoveNode(oldAssocRef, newAssocRef);
@@ -741,7 +741,7 @@ public class DbNodeServiceImpl extends AbstractNodeServiceImpl
public ChildAssociationRef addChild(NodeRef parentRef, NodeRef childRef, QName assocTypeQName, QName assocQName) public ChildAssociationRef addChild(NodeRef parentRef, NodeRef childRef, QName assocTypeQName, QName assocQName)
{ {
// Invoke policy behaviours // Invoke policy behaviours
invokeBeforeCreateChildAssociation(parentRef, childRef, assocTypeQName, assocQName); invokeBeforeCreateChildAssociation(parentRef, childRef, assocTypeQName, assocQName, false);
// get the parent node and ensure that it is a container node // get the parent node and ensure that it is a container node
Node parentNode = getNodeNotNull(parentRef); Node parentNode = getNodeNotNull(parentRef);
@@ -764,7 +764,7 @@ public class DbNodeServiceImpl extends AbstractNodeServiceImpl
getPaths(childNodeRef, false); getPaths(childNodeRef, false);
// Invoke policy behaviours // Invoke policy behaviours
invokeOnCreateChildAssociation(assocRef); invokeOnCreateChildAssociation(assocRef, false);
return assoc.getChildAssocRef(); return assoc.getChildAssocRef();
} }

View File

@@ -109,9 +109,12 @@ public class NodeIndexer
indexer.deleteNode(childAssocRef); indexer.deleteNode(childAssocRef);
} }
public void onCreateChildAssociation(ChildAssociationRef childAssocRef) public void onCreateChildAssociation(ChildAssociationRef childAssocRef, boolean isNew)
{ {
indexer.createChildRelationship(childAssocRef); if (!isNew)
{
indexer.createChildRelationship(childAssocRef);
}
} }
public void onDeleteChildAssociation(ChildAssociationRef childAssocRef) public void onDeleteChildAssociation(ChildAssociationRef childAssocRef)

View File

@@ -231,6 +231,9 @@ public class IncompleteNodeTagger
} }
} }
/**
* {@inheritDoc}
*/
public void onCreateNode(ChildAssociationRef childAssocRef) public void onCreateNode(ChildAssociationRef childAssocRef)
{ {
NodeRef nodeRef = childAssocRef.getChildRef(); NodeRef nodeRef = childAssocRef.getChildRef();
@@ -238,6 +241,9 @@ public class IncompleteNodeTagger
saveAssoc(nodeRef, null); saveAssoc(nodeRef, null);
} }
/**
* {@inheritDoc}
*/
public void onUpdateProperties( public void onUpdateProperties(
NodeRef nodeRef, NodeRef nodeRef,
Map<QName, Serializable> before, Map<QName, Serializable> before,
@@ -247,6 +253,8 @@ public class IncompleteNodeTagger
} }
/** /**
* {@inheritDoc}
* <p>
* Save the node for checking of properties. * Save the node for checking of properties.
* The {@link org.alfresco.model.ContentModel#ASPECT_INCOMPLETE incomplete} aspect is * The {@link org.alfresco.model.ContentModel#ASPECT_INCOMPLETE incomplete} aspect is
* not processed. * not processed.
@@ -279,20 +287,21 @@ public class IncompleteNodeTagger
} }
/** /**
* @see AssocSourceTypeIntegrityEvent * {@inheritDoc}
* @see AssocTargetTypeIntegrityEvent * <p>
* @see AssocSourceMultiplicityIntegrityEvent * This only saves the node for checking if it is <i>not</i> new. The create of the
* @see AssocTargetMultiplicityIntegrityEvent * node will handle it.
* @see AssocTargetRoleIntegrityEvent
*/ */
public void onCreateChildAssociation(ChildAssociationRef childAssocRef) public void onCreateChildAssociation(ChildAssociationRef childAssocRef, boolean isNew)
{ {
saveAssoc(childAssocRef.getParentRef(), childAssocRef.getTypeQName()); if (!isNew)
{
saveAssoc(childAssocRef.getParentRef(), childAssocRef.getTypeQName());
}
} }
/** /**
* @see AssocSourceMultiplicityIntegrityEvent * {@inheritDoc}
* @see AssocTargetMultiplicityIntegrityEvent
*/ */
public void onDeleteChildAssociation(ChildAssociationRef childAssocRef) public void onDeleteChildAssociation(ChildAssociationRef childAssocRef)
{ {
@@ -300,10 +309,7 @@ public class IncompleteNodeTagger
} }
/** /**
* @see AssocSourceTypeIntegrityEvent * {@inheritDoc}
* @see AssocTargetTypeIntegrityEvent
* @see AssocSourceMultiplicityIntegrityEvent
* @see AssocTargetMultiplicityIntegrityEvent
*/ */
public void onCreateAssociation(AssociationRef nodeAssocRef) public void onCreateAssociation(AssociationRef nodeAssocRef)
{ {
@@ -311,8 +317,7 @@ public class IncompleteNodeTagger
} }
/** /**
* @see AssocSourceMultiplicityIntegrityEvent * {@inheritDoc}
* @see AssocTargetMultiplicityIntegrityEvent
*/ */
public void onDeleteAssociation(AssociationRef nodeAssocRef) public void onDeleteAssociation(AssociationRef nodeAssocRef)
{ {

View File

@@ -328,7 +328,7 @@ public class IntegrityChecker
save(event); save(event);
// check that the multiplicity and other properties of the new association are allowed // check that the multiplicity and other properties of the new association are allowed
onCreateChildAssociation(childAssocRef); onCreateChildAssociation(childAssocRef, false);
// check mandatory aspects // check mandatory aspects
event = new AspectsIntegrityEvent(nodeService, dictionaryService, childRef); event = new AspectsIntegrityEvent(nodeService, dictionaryService, childRef);
@@ -426,14 +426,21 @@ public class IntegrityChecker
} }
/** /**
* This handles the creation of secondary child associations.
*
* @see AssocSourceTypeIntegrityEvent * @see AssocSourceTypeIntegrityEvent
* @see AssocTargetTypeIntegrityEvent * @see AssocTargetTypeIntegrityEvent
* @see AssocSourceMultiplicityIntegrityEvent * @see AssocSourceMultiplicityIntegrityEvent
* @see AssocTargetMultiplicityIntegrityEvent * @see AssocTargetMultiplicityIntegrityEvent
* @see AssocTargetRoleIntegrityEvent * @see AssocTargetRoleIntegrityEvent
*/ */
public void onCreateChildAssociation(ChildAssociationRef childAssocRef) public void onCreateChildAssociation(ChildAssociationRef childAssocRef, boolean isNew)
{ {
if (isNew)
{
return;
}
IntegrityEvent event = null; IntegrityEvent event = null;
// check source type // check source type
event = new AssocSourceTypeIntegrityEvent( event = new AssocSourceTypeIntegrityEvent(

View File

@@ -24,6 +24,7 @@
*/ */
package org.alfresco.repo.rule.ruletrigger; package org.alfresco.repo.rule.ruletrigger;
import org.alfresco.repo.node.NodeServicePolicies;
import org.alfresco.repo.transaction.AlfrescoTransactionSupport; import org.alfresco.repo.transaction.AlfrescoTransactionSupport;
import org.alfresco.service.cmr.dictionary.ClassDefinition; import org.alfresco.service.cmr.dictionary.ClassDefinition;
import org.alfresco.service.cmr.dictionary.DataTypeDefinition; import org.alfresco.service.cmr.dictionary.DataTypeDefinition;
@@ -38,10 +39,18 @@ import org.apache.commons.logging.LogFactory;
* We use this specialised trigger for create node beaucse of a problem with the CIFS integration. * We use this specialised trigger for create node beaucse of a problem with the CIFS integration.
* <p> * <p>
* The create node trigger will only be fired if the object is NOT a sub-type of content. * The create node trigger will only be fired if the object is NOT a sub-type of content.
* <p>
* Policy names supported are:
* <ul>
* <li>{@linkplain NodeServicePolicies.OnCreateChildAssociationPolicy}</li>
* <li>{@linkplain NodeServicePolicies.BeforeDeleteChildAssociationPolicy}</li>
* <li>{@linkplain NodeServicePolicies.OnCreateNodePolicy}</li>
* </ul>
* *
* @author Roy Wetherall * @author Roy Wetherall
*/ */
public class CreateNodeRuleTrigger extends SingleChildAssocRefPolicyRuleTrigger public class CreateNodeRuleTrigger extends SingleChildAssocRefPolicyRuleTrigger
implements NodeServicePolicies.OnCreateNodePolicy
{ {
/** /**
* The logger * The logger
@@ -55,7 +64,10 @@ public class CreateNodeRuleTrigger extends SingleChildAssocRefPolicyRuleTrigger
this.dictionaryService = dictionaryService; this.dictionaryService = dictionaryService;
} }
public void policyBehaviour(ChildAssociationRef childAssocRef) /**
* {@inheritDoc}
*/
public void onCreateNode(ChildAssociationRef childAssocRef)
{ {
// Only fire the rule if the node is question has no potential to contain content // Only fire the rule if the node is question has no potential to contain content
// TODO we need to find a better way to do this .. how can this be resolved in CIFS?? // TODO we need to find a better way to do this .. how can this be resolved in CIFS??

View File

@@ -24,6 +24,7 @@
*/ */
package org.alfresco.repo.rule.ruletrigger; package org.alfresco.repo.rule.ruletrigger;
import org.alfresco.repo.node.NodeServicePolicies;
import org.alfresco.repo.policy.JavaBehaviour; import org.alfresco.repo.policy.JavaBehaviour;
import org.alfresco.service.cmr.repository.ChildAssociationRef; import org.alfresco.service.cmr.repository.ChildAssociationRef;
import org.alfresco.service.cmr.rule.RuleServiceException; import org.alfresco.service.cmr.rule.RuleServiceException;
@@ -32,7 +33,22 @@ import org.alfresco.service.namespace.QName;
import org.apache.commons.logging.Log; import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory; import org.apache.commons.logging.LogFactory;
public class SingleChildAssocRefPolicyRuleTrigger extends RuleTriggerAbstractBase /**
* A rule trigger for the creation of <b>secondary child associations</b>.
* <p>
* Policy names supported are:
* <ul>
* <li>{@linkplain NodeServicePolicies.OnCreateChildAssociationPolicy}</li>
* <li>{@linkplain NodeServicePolicies.BeforeDeleteChildAssociationPolicy}</li>
* </ul>
*
* @author Roy Wetherall
*/
public class SingleChildAssocRefPolicyRuleTrigger
extends RuleTriggerAbstractBase
implements NodeServicePolicies.OnCreateChildAssociationPolicy,
NodeServicePolicies.BeforeDeleteChildAssociationPolicy
{ {
private static final String ERR_POLICY_NAME_NOT_SET = "Unable to register rule trigger since policy name has not been set."; private static final String ERR_POLICY_NAME_NOT_SET = "Unable to register rule trigger since policy name has not been set.";
@@ -77,24 +93,38 @@ public class SingleChildAssocRefPolicyRuleTrigger extends RuleTriggerAbstractBas
this.policyComponent.bindClassBehaviour( this.policyComponent.bindClassBehaviour(
QName.createQName(this.policyNamespace, this.policyName), QName.createQName(this.policyNamespace, this.policyName),
this, this,
new JavaBehaviour(this, "policyBehaviour")); new JavaBehaviour(this, policyName));
} }
else else
{ {
this.policyComponent.bindAssociationBehaviour( this.policyComponent.bindAssociationBehaviour(
QName.createQName(this.policyNamespace, this.policyName), QName.createQName(this.policyNamespace, this.policyName),
this, this,
new JavaBehaviour(this, "policyBehaviour")); new JavaBehaviour(this, policyName));
} }
} }
public void policyBehaviour(ChildAssociationRef childAssocRef) public void beforeDeleteChildAssociation(ChildAssociationRef childAssocRef)
{ {
if (logger.isDebugEnabled() == true) if (logger.isDebugEnabled() == true)
{ {
logger.debug("Single child assoc trigger (policy = " + this.policyName + ") fired for parent node " + childAssocRef.getParentRef() + " and child node " + childAssocRef.getChildRef()); logger.debug("Single child assoc trigger (policy = " + this.policyName + ") fired for parent node " + childAssocRef.getParentRef() + " and child node " + childAssocRef.getChildRef());
} }
triggerRules(childAssocRef.getParentRef(), childAssocRef.getChildRef()); triggerRules(childAssocRef.getParentRef(), childAssocRef.getChildRef());
} }
public void onCreateChildAssociation(ChildAssociationRef childAssocRef, boolean isNewNode)
{
if (isNewNode)
{
return;
}
if (logger.isDebugEnabled() == true)
{
logger.debug("Single child assoc trigger (policy = " + this.policyName + ") fired for parent node " + childAssocRef.getParentRef() + " and child node " + childAssocRef.getChildRef());
}
triggerRules(childAssocRef.getParentRef(), childAssocRef.getChildRef());
}
} }