transfer service : read only implementation plus unit test

git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@21353 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
This commit is contained in:
Mark Rogers
2010-07-22 13:04:15 +00:00
parent 5d4cfd5ab0
commit 5b86cfb4e9
6 changed files with 843 additions and 366 deletions

View File

@@ -39,8 +39,14 @@ import org.alfresco.service.namespace.QName;
* supports the policy interface) until the Policy is registered. Otherwise, * supports the policy interface) until the Policy is registered. Otherwise,
* the behaviour is validated at bind-time. * the behaviour is validated at bind-time.
* *
* Policies may be selectively "turned off" by the Behaviour Filter.
*
*
*
* @see org.alfresco.repo.policy.BehaviourFilter * @see org.alfresco.repo.policy.BehaviourFilter
* *
* @see org.alfresco.repo.node.NodeServicePolicies
*
* *
* @author David Caruana * @author David Caruana
* *
@@ -94,7 +100,7 @@ public interface PolicyComponent
* Determine if the specified policy has been registered * Determine if the specified policy has been registered
* *
* @param policyType the policy type * @param policyType the policy type
* @param policy the policy name * @param policy the fully qualified name of the policy
* @return true => registered, false => not yet * @return true => registered, false => not yet
*/ */
public boolean isRegisteredPolicy(PolicyType policyType, QName policy); public boolean isRegisteredPolicy(PolicyType policyType, QName policy);
@@ -108,13 +114,13 @@ public interface PolicyComponent
* Example of calling this method * Example of calling this method
* <pre> * <pre>
* this.policyComponent.bindClassBehaviour( * this.policyComponent.bindClassBehaviour(
* QName.createQName(NamespaceService.ALFRESCO_URI, "beforeUpdateNode"), * NodeServicePolicies.BeforeUpdateNodePolicy.QNAME,
* ContentModel.ASPECT_LOCKABLE, * ContentModel.ASPECT_LOCKABLE,
* new JavaBehaviour(this, "beforeUpdateNode")); * new JavaBehaviour(this, "beforeUpdateNode"));
* </pre> * </pre>
* @param policy the fully qualified policy name * @param policy the fully qualified policy name
* @param className the qualified name of a type or aspect that the policy is bound to * @param className the qualified name of a type or aspect that the policy is bound to
* @param behaviour the behaviour, what gets executed by the policy * @param behaviour the behaviour. What gets executed by the policy
* @return the registered behaviour definition * @return the registered behaviour definition
*/ */
public BehaviourDefinition<ClassBehaviourBinding> bindClassBehaviour(QName policy, QName className, Behaviour behaviour); public BehaviourDefinition<ClassBehaviourBinding> bindClassBehaviour(QName policy, QName className, Behaviour behaviour);
@@ -124,7 +130,7 @@ public interface PolicyComponent
* *
* @param policy the fully qualified policy name * @param policy the fully qualified policy name
* @param service the service (any object, in fact) * @param service the service (any object, in fact)
* @param behaviour the behaviour, what gets executed by the policy * @param behaviour the behaviour. What gets executed by the policy
* @return the registered behaviour definition * @return the registered behaviour definition
*/ */
public BehaviourDefinition<ServiceBehaviourBinding> bindClassBehaviour(QName policy, Object service, Behaviour behaviour); public BehaviourDefinition<ServiceBehaviourBinding> bindClassBehaviour(QName policy, Object service, Behaviour behaviour);
@@ -135,7 +141,7 @@ public interface PolicyComponent
* @param policy the fully qualified policy name * @param policy the fully qualified policy name
* @param className the qualified name of the class (type or aspect) to bind against * @param className the qualified name of the class (type or aspect) to bind against
* @param propertyName the name of the property to bind against * @param propertyName the name of the property to bind against
* @param behaviour the behaviour, what gets executed by the policy * @param behaviour the behaviour. What gets executed by the policy
* @return the registered behaviour definition * @return the registered behaviour definition
*/ */
public BehaviourDefinition<ClassFeatureBehaviourBinding> bindPropertyBehaviour(QName policy, QName className, QName propertyName, Behaviour behaviour); public BehaviourDefinition<ClassFeatureBehaviourBinding> bindPropertyBehaviour(QName policy, QName className, QName propertyName, Behaviour behaviour);
@@ -143,7 +149,7 @@ public interface PolicyComponent
/** /**
* Bind a Property specific behaviour to a Property-level Policy (for all properties of a Class) * Bind a Property specific behaviour to a Property-level Policy (for all properties of a Class)
* *
* @param policy the policy name * @param policy the fully qualified policy name
* @param className the name of the class (type or aspect) to bind against * @param className the name of the class (type or aspect) to bind against
* @param behaviour the behaviour, what gets executed by the policy * @param behaviour the behaviour, what gets executed by the policy
* @return the registered behaviour definition * @return the registered behaviour definition
@@ -153,7 +159,7 @@ public interface PolicyComponent
/** /**
* Bind a Service specific behaviour to a Property-level Policy * Bind a Service specific behaviour to a Property-level Policy
* *
* @param policy the policy name * @param policy the fully qualified policy name
* @param service the binding service * @param service the binding service
* @param behaviour the behaviour * @param behaviour the behaviour
* @return the registered behaviour definition * @return the registered behaviour definition
@@ -166,7 +172,7 @@ public interface PolicyComponent
* For example, before a rule folder association is created. * For example, before a rule folder association is created.
* <pre> * <pre>
* policyComponent.bindAssociationBehaviour( * policyComponent.bindAssociationBehaviour(
* QName.createQName(NamespaceService.ALFRESCO_URI, "beforeCreateChildAssociation"), * NodeServicePolicies.BeforeCreateChildAssociationPolicy.QNAME,
* RuleModel.ASPECT_RULES, * RuleModel.ASPECT_RULES,
* RuleModel.ASSOC_RULE_FOLDER, * RuleModel.ASSOC_RULE_FOLDER,
* new JavaBehaviour(this, "beforeCreateChildAssociation")); * new JavaBehaviour(this, "beforeCreateChildAssociation"));
@@ -175,7 +181,7 @@ public interface PolicyComponent
* @param policy the policy name * @param policy the policy name
* @param className the name of the class (type or aspect) to bind against * @param className the name of the class (type or aspect) to bind against
* @param assocName the name of the association to bind against * @param assocName the name of the association to bind against
* @param behaviour the behaviour, what gets executed by the policy * @param behaviour the behaviour. What gets executed by the policy
* @return the registered behaviour definition * @return the registered behaviour definition
*/ */
public BehaviourDefinition<ClassFeatureBehaviourBinding> bindAssociationBehaviour(QName policy, QName className, QName assocName, Behaviour behaviour); public BehaviourDefinition<ClassFeatureBehaviourBinding> bindAssociationBehaviour(QName policy, QName className, QName assocName, Behaviour behaviour);
@@ -185,7 +191,7 @@ public interface PolicyComponent
* *
* @param policy the policy name * @param policy the policy name
* @param className the name of the class (type or aspect) to bind against * @param className the name of the class (type or aspect) to bind against
* @param behaviour the behaviour * @param behaviour the behaviour. What gets executed by the policy
* @return the registered behaviour definition * @return the registered behaviour definition
*/ */
public BehaviourDefinition<ClassFeatureBehaviourBinding> bindAssociationBehaviour(QName policy, QName className, Behaviour behaviour); public BehaviourDefinition<ClassFeatureBehaviourBinding> bindAssociationBehaviour(QName policy, QName className, Behaviour behaviour);
@@ -195,7 +201,7 @@ public interface PolicyComponent
* *
* @param policy the policy name * @param policy the policy name
* @param service the binding service * @param service the binding service
* @param behaviour the behaviour * @param behaviour the behaviour. What gets executed by the policy
* @return the registered behaviour definition * @return the registered behaviour definition
*/ */
public BehaviourDefinition<ServiceBehaviourBinding> bindAssociationBehaviour(QName policy, Object service, Behaviour behaviour); public BehaviourDefinition<ServiceBehaviourBinding> bindAssociationBehaviour(QName policy, Object service, Behaviour behaviour);

View File

@@ -29,6 +29,7 @@ import java.util.Map;
import java.util.Set; import java.util.Set;
import org.alfresco.model.ContentModel; import org.alfresco.model.ContentModel;
import org.alfresco.repo.security.authentication.AuthenticationUtil;
import org.alfresco.repo.transfer.CorrespondingNodeResolver.ResolvedParentChildPair; import org.alfresco.repo.transfer.CorrespondingNodeResolver.ResolvedParentChildPair;
import org.alfresco.repo.transfer.manifest.ManifestAccessControl; import org.alfresco.repo.transfer.manifest.ManifestAccessControl;
import org.alfresco.repo.transfer.manifest.ManifestPermission; import org.alfresco.repo.transfer.manifest.ManifestPermission;
@@ -38,6 +39,8 @@ import org.alfresco.repo.transfer.manifest.TransferManifestNode;
import org.alfresco.repo.transfer.manifest.TransferManifestNormalNode; import org.alfresco.repo.transfer.manifest.TransferManifestNormalNode;
import org.alfresco.service.cmr.dictionary.AspectDefinition; import org.alfresco.service.cmr.dictionary.AspectDefinition;
import org.alfresco.service.cmr.dictionary.DictionaryService; import org.alfresco.service.cmr.dictionary.DictionaryService;
import org.alfresco.service.cmr.lock.LockService;
import org.alfresco.service.cmr.lock.LockType;
import org.alfresco.service.cmr.repository.ChildAssociationRef; import org.alfresco.service.cmr.repository.ChildAssociationRef;
import org.alfresco.service.cmr.repository.ContentData; import org.alfresco.service.cmr.repository.ContentData;
import org.alfresco.service.cmr.repository.ContentService; import org.alfresco.service.cmr.repository.ContentService;
@@ -87,6 +90,7 @@ public class RepoPrimaryManifestProcessorImpl extends AbstractManifestProcessorB
private ContentService contentService; private ContentService contentService;
private DictionaryService dictionaryService; private DictionaryService dictionaryService;
private CorrespondingNodeResolver nodeResolver; private CorrespondingNodeResolver nodeResolver;
private LockService lockService;
// State within this class // State within this class
/** /**
@@ -290,7 +294,16 @@ public class RepoPrimaryManifestProcessorImpl extends AbstractManifestProcessorB
props.put(TransferModel.PROP_REPOSITORY_ID, header.getRepositoryId()); props.put(TransferModel.PROP_REPOSITORY_ID, header.getRepositoryId());
} }
props.put(TransferModel.PROP_FROM_REPOSITORY_ID, header.getRepositoryId()); props.put(TransferModel.PROP_FROM_REPOSITORY_ID, header.getRepositoryId());
// Do we need to worry about locking this new node ?
if(header.isReadOnly())
{
log.debug("new node needs to be locked");
props.put(ContentModel.PROP_LOCK_OWNER, AuthenticationUtil.getAdminUserName());
props.put(ContentModel.PROP_LOCK_TYPE, LockType.READ_ONLY_LOCK.toString());
props.put(ContentModel.PROP_EXPIRY_DATE, null);
}
// Create the corresponding node... // Create the corresponding node...
ChildAssociationRef newNode = nodeService.createNode(parentNodeRef, parentAssocType, parentAssocName, node ChildAssociationRef newNode = nodeService.createNode(parentNodeRef, parentAssocType, parentAssocName, node
.getType(), props); .getType(), props);
@@ -312,6 +325,7 @@ public class RepoPrimaryManifestProcessorImpl extends AbstractManifestProcessorB
nodeService.addAspect(newNode.getChildRef(), aspect, null); nodeService.addAspect(newNode.getChildRef(), aspect, null);
} }
ManifestAccessControl acl = node.getAccessControl(); ManifestAccessControl acl = node.getAccessControl();
// Apply new ACL to this node // Apply new ACL to this node
if(acl != null) if(acl != null)
@@ -412,6 +426,15 @@ public class RepoPrimaryManifestProcessorImpl extends AbstractManifestProcessorB
props.put(TransferModel.PROP_REPOSITORY_ID, header.getRepositoryId()); props.put(TransferModel.PROP_REPOSITORY_ID, header.getRepositoryId());
} }
props.put(TransferModel.PROP_FROM_REPOSITORY_ID, header.getRepositoryId()); props.put(TransferModel.PROP_FROM_REPOSITORY_ID, header.getRepositoryId());
// Do we need to worry about locking this updated ?
if(header.isReadOnly())
{
props.put(ContentModel.PROP_LOCK_OWNER, AuthenticationUtil.getAdminUserName());
props.put(ContentModel.PROP_LOCK_TYPE, LockType.READ_ONLY_LOCK.toString());
props.put(ContentModel.PROP_EXPIRY_DATE, null);
log.debug("updated node needs to be locked");
}
// Split out the content properties and sanitise the others // Split out the content properties and sanitise the others
Map<QName, Serializable> contentProps = processProperties(nodeToUpdate, props, existingProps); Map<QName, Serializable> contentProps = processProperties(nodeToUpdate, props, existingProps);
@@ -434,6 +457,11 @@ public class RepoPrimaryManifestProcessorImpl extends AbstractManifestProcessorB
suppliedAspects.add(aspectDef.getName()); suppliedAspects.add(aspectDef.getName());
} }
if(header.isReadOnly())
{
suppliedAspects.add(ContentModel.ASPECT_LOCKABLE);
}
aspectsToRemove.removeAll(suppliedAspects); aspectsToRemove.removeAll(suppliedAspects);
aspectsToRemove.remove(TransferModel.ASPECT_TRANSFERRED); aspectsToRemove.remove(TransferModel.ASPECT_TRANSFERRED);
suppliedAspects.removeAll(existingAspects); suppliedAspects.removeAll(existingAspects);

View File

@@ -45,7 +45,7 @@ import org.apache.commons.logging.LogFactory;
* For a complete transfer it is responsible for deleting any replicated nodes * For a complete transfer it is responsible for deleting any replicated nodes
* which exist in the target repository that do not exist in the source repository. * which exist in the target repository that do not exist in the source repository.
* *
* If the transfer is not "complete" then this processor does nothing. * If the transfer is not "sync" then this processor does nothing.
* *
*/ */
public class RepoTertiaryManifestProcessorImpl extends AbstractManifestProcessorBase public class RepoTertiaryManifestProcessorImpl extends AbstractManifestProcessorBase

View File

@@ -573,6 +573,7 @@ public class TransferServiceImpl implements TransferService
header.setCreatedDate(new Date()); header.setCreatedDate(new Date());
header.setNodeCount(nodes.size()); header.setNodeCount(nodes.size());
header.setSync(definition.isSync()); header.setSync(definition.isSync());
header.setReadOnly(definition.isReadOnly());
formatter.startTransferManifest(snapshotWriter); formatter.startTransferManifest(snapshotWriter);
formatter.writeTransferManifestHeader(header); formatter.writeTransferManifestHeader(header);
for(NodeRef nodeRef : nodes) for(NodeRef nodeRef : nodes)

View File

@@ -17,11 +17,9 @@
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>. * along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
*/ */
/** /**
* Provides the public interface for the invitation service that is used * Provides the public interface for the lock service that is used
* to invite users to sites. * to lock nodes.
* <p> * <p>
* Two types of invitation are provided, Nominated invitations, where a user * @see org.alfresco.service.cmr.lock.LockService
* nominates another user to become a member of a site and moderated invitations where a user askes to become a member of a site and
* its then up to an administrator to either accept or reject the invitation.
*/ */
package org.alfresco.service.cmr.lock; package org.alfresco.service.cmr.lock;