diff --git a/config/alfresco/transfer-service-context.xml b/config/alfresco/transfer-service-context.xml
index 996410da69..69462a9c27 100644
--- a/config/alfresco/transfer-service-context.xml
+++ b/config/alfresco/transfer-service-context.xml
@@ -51,6 +51,7 @@
+
@@ -101,8 +102,9 @@
-
-
+
+
+
diff --git a/source/java/org/alfresco/repo/transfer/DefaultManifestProcessorFactoryImpl.java b/source/java/org/alfresco/repo/transfer/DefaultManifestProcessorFactoryImpl.java
index bfb7c94870..c58d2cc81a 100644
--- a/source/java/org/alfresco/repo/transfer/DefaultManifestProcessorFactoryImpl.java
+++ b/source/java/org/alfresco/repo/transfer/DefaultManifestProcessorFactoryImpl.java
@@ -27,17 +27,18 @@ import org.alfresco.repo.transfer.requisite.TransferRequsiteWriter;
import org.alfresco.service.cmr.dictionary.DictionaryService;
import org.alfresco.service.cmr.repository.ContentService;
import org.alfresco.service.cmr.repository.NodeService;
+import org.alfresco.service.cmr.security.PermissionService;
import org.alfresco.service.cmr.transfer.TransferReceiver;
/**
* @author brian
- *
*/
public class DefaultManifestProcessorFactoryImpl implements ManifestProcessorFactory
{
private NodeService nodeService;
private ContentService contentService;
private DictionaryService dictionaryService;
+ private PermissionService permissionService;
private CorrespondingNodeResolverFactory nodeResolverFactory;
/*
@@ -55,6 +56,7 @@ public class DefaultManifestProcessorFactoryImpl implements ManifestProcessorFac
primaryProcessor.setNodeResolver(nodeResolver);
primaryProcessor.setNodeService(nodeService);
primaryProcessor.setDictionaryService(dictionaryService);
+ primaryProcessor.setPermissionService(getPermissionService());
processors.add(primaryProcessor);
RepoSecondaryManifestProcessorImpl secondaryProcessor = new RepoSecondaryManifestProcessorImpl(receiver, transferId);
@@ -119,4 +121,14 @@ public class DefaultManifestProcessorFactoryImpl implements ManifestProcessorFac
return processor;
}
+ public void setPermissionService(PermissionService permissionService)
+ {
+ this.permissionService = permissionService;
+ }
+
+ public PermissionService getPermissionService()
+ {
+ return permissionService;
+ }
+
}
diff --git a/source/java/org/alfresco/repo/transfer/RepoPrimaryManifestProcessorImpl.java b/source/java/org/alfresco/repo/transfer/RepoPrimaryManifestProcessorImpl.java
index 17fb3e31ba..e8e84c8ff7 100644
--- a/source/java/org/alfresco/repo/transfer/RepoPrimaryManifestProcessorImpl.java
+++ b/source/java/org/alfresco/repo/transfer/RepoPrimaryManifestProcessorImpl.java
@@ -30,6 +30,8 @@ import java.util.Set;
import org.alfresco.model.ContentModel;
import org.alfresco.repo.transfer.CorrespondingNodeResolver.ResolvedParentChildPair;
+import org.alfresco.repo.transfer.manifest.ManifestAccessControl;
+import org.alfresco.repo.transfer.manifest.ManifestPermission;
import org.alfresco.repo.transfer.manifest.TransferManifestDeletedNode;
import org.alfresco.repo.transfer.manifest.TransferManifestHeader;
import org.alfresco.repo.transfer.manifest.TransferManifestNode;
@@ -43,6 +45,9 @@ import org.alfresco.service.cmr.repository.ContentWriter;
import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.cmr.repository.NodeService;
import org.alfresco.service.cmr.repository.StoreRef;
+import org.alfresco.service.cmr.security.AccessPermission;
+import org.alfresco.service.cmr.security.AccessStatus;
+import org.alfresco.service.cmr.security.PermissionService;
import org.alfresco.service.cmr.transfer.TransferReceiver;
import org.alfresco.service.namespace.QName;
import org.apache.commons.logging.Log;
@@ -78,6 +83,7 @@ public class RepoPrimaryManifestProcessorImpl extends AbstractManifestProcessorB
}
private NodeService nodeService;
+ private PermissionService permissionService;
private ContentService contentService;
private DictionaryService dictionaryService;
private CorrespondingNodeResolver nodeResolver;
@@ -319,6 +325,27 @@ public class RepoPrimaryManifestProcessorImpl extends AbstractManifestProcessorB
{
nodeService.addAspect(newNode.getChildRef(), aspect, null);
}
+
+ ManifestAccessControl acl = node.getAccessControl();
+ // Apply new ACL to this node
+ if(acl != null)
+ {
+ permissionService.setInheritParentPermissions(newNode.getChildRef(), acl.isInherited());
+
+ if(acl.getPermissions() != null)
+ {
+ for(ManifestPermission permission : acl.getPermissions())
+ {
+ log.debug("setting permission on node");
+ AccessStatus status = AccessStatus.valueOf(permission.getStatus());
+ // The node has its own access control list
+ permissionService.setPermission(newNode.getChildRef(),
+ permission.getAuthority(),
+ permission.getPermission(),
+ status == AccessStatus.ALLOWED);
+ }
+ }
+ }
// Is the node that we've just added the parent of any orphans that
// we've found earlier?
@@ -435,6 +462,70 @@ public class RepoPrimaryManifestProcessorImpl extends AbstractManifestProcessorB
{
nodeService.removeAspect(nodeToUpdate, aspect);
}
+
+ // Check the ACL of this updated node
+
+ ManifestAccessControl acl = node.getAccessControl();
+ if(acl != null)
+ {
+ boolean existInherit = permissionService.getInheritParentPermissions(nodeToUpdate);
+ if(existInherit != acl.isInherited())
+ {
+ log.debug("changed inherit permissions flag");
+ permissionService.setInheritParentPermissions(nodeToUpdate, acl.isInherited());
+ }
+
+ Set existingPermissions = permissionService.getAllSetPermissions(nodeToUpdate);
+ List newPermissions = acl.getPermissions();
+
+ if(existingPermissions.size() > 0 || newPermissions != null)
+ {
+ // Yes we have explicit permissions on this node.
+ log.debug("have to check permissions");
+
+ Setwork = new HashSet();
+ for(AccessPermission permission : existingPermissions)
+ {
+ if(permission.isSetDirectly())
+ {
+ ManifestPermission p = new ManifestPermission();
+ p.setAuthority(permission.getAuthority());
+ p.setPermission(permission.getPermission());
+ p.setStatus(permission.getAccessStatus().toString());
+ work.add(p);
+ }
+ }
+
+ // Do we need to check whether to add any permissions ?
+ if(newPermissions != null)
+ {
+ // Do we need to add any permissions ?
+ for(ManifestPermission permission : acl.getPermissions())
+ {
+ if(!work.contains(permission))
+ {
+ log.debug("setting permission on node:" + permission);
+ AccessStatus status = AccessStatus.valueOf(permission.getStatus());
+ permissionService.setPermission(nodeToUpdate,
+ permission.getAuthority(),
+ permission.getPermission(),
+ status == AccessStatus.ALLOWED);
+ }
+ }
+
+ // Remove permissions from "work" that should be there
+ work.removeAll(newPermissions);
+
+ }
+
+ // Do we need to remove any permissions
+ for(ManifestPermission permission : work)
+ {
+ log.debug("removing permission on node:" + permission);
+ permissionService.deletePermission(nodeToUpdate, permission.getAuthority(), permission.getPermission());
+ }
+ }
+ }
}
}
@@ -684,4 +775,14 @@ public class RepoPrimaryManifestProcessorImpl extends AbstractManifestProcessorB
this.nodeResolver = nodeResolver;
}
+ public void setPermissionService(PermissionService permissionService)
+ {
+ this.permissionService = permissionService;
+ }
+
+ public PermissionService getPermissionService()
+ {
+ return permissionService;
+ }
+
}
diff --git a/source/java/org/alfresco/repo/transfer/TransferServiceImplTest.java b/source/java/org/alfresco/repo/transfer/TransferServiceImplTest.java
index e856649b2a..b1a93801fe 100644
--- a/source/java/org/alfresco/repo/transfer/TransferServiceImplTest.java
+++ b/source/java/org/alfresco/repo/transfer/TransferServiceImplTest.java
@@ -48,7 +48,9 @@ import org.alfresco.service.cmr.repository.Path;
import org.alfresco.service.cmr.repository.StoreRef;
import org.alfresco.service.cmr.search.ResultSet;
import org.alfresco.service.cmr.search.SearchService;
+import org.alfresco.service.cmr.security.AccessPermission;
import org.alfresco.service.cmr.security.MutableAuthenticationService;
+import org.alfresco.service.cmr.security.PermissionService;
import org.alfresco.service.cmr.transfer.TransferCallback;
import org.alfresco.service.cmr.transfer.TransferDefinition;
import org.alfresco.service.cmr.transfer.TransferEvent;
@@ -86,6 +88,7 @@ public class TransferServiceImplTest extends BaseAlfrescoSpringTest
private TransactionService transactionService;
private TransferReceiver receiver;
private TransferManifestNodeFactory transferManifestNodeFactory;
+ private PermissionService permissionService;
String COMPANY_HOME_XPATH_QUERY = "/{http://www.alfresco.org/model/application/1.0}company_home";
String GUEST_HOME_XPATH_QUERY = "/{http://www.alfresco.org/model/application/1.0}company_home/{http://www.alfresco.org/model/application/1.0}guest_home";
@@ -116,6 +119,7 @@ public class TransferServiceImplTest extends BaseAlfrescoSpringTest
this.contentService = (ContentService) this.applicationContext.getBean("contentService");
this.authenticationService = (MutableAuthenticationService) this.applicationContext.getBean("authenticationService");
this.actionService = (ActionService)this.applicationContext.getBean("actionService");
+ this.permissionService = (PermissionService)this.applicationContext.getBean("permissionService");
this.receiver = (TransferReceiver)this.applicationContext.getBean("transferReceiver");
this.transferManifestNodeFactory = (TransferManifestNodeFactory)this.applicationContext.getBean("transferManifestNodeFactory");
this.authenticationComponent = (AuthenticationComponent) this.applicationContext.getBean("authenticationComponent");
@@ -740,9 +744,7 @@ public class TransferServiceImplTest extends BaseAlfrescoSpringTest
Date srcModifiedDate = (Date)nodeService.getProperty(contentNodeRef, ContentModel.PROP_MODIFIED);
logger.debug("srcModifiedDate : " + srcModifiedDate + " destModifiedDate : " + destModifiedDate);
-
- // BUGBUG - MER 14/07/2010 - can't set modified date
- // assertTrue("after update, modified date is not correct", destModifiedDate.compareTo(srcModifiedDate) == 0);
+ assertTrue("after update, modified date is not correct", destModifiedDate.compareTo(srcModifiedDate) == 0);
Date destCreatedDate = (Date)nodeService.getProperty(destNodeRef, ContentModel.PROP_CREATED);
Date srcCreatedDate = (Date)nodeService.getProperty(contentNodeRef, ContentModel.PROP_CREATED);
@@ -2646,6 +2648,354 @@ public class TransferServiceImplTest extends BaseAlfrescoSpringTest
// }
}
+
+ /**
+ * Test the transfer method with regard to permissions on a node.
+ *
+ * Step 1:
+ * Create a node with a single permission
+ * Inherit:false
+ * Read, Admin, Allow
+ * Transfer
+ *
+ * Step 2:
+ * Update it to have several permissions
+ * Inherit:false
+ * Read, Everyone, DENY
+ * Read, Admin, Allow
+ *
+ * Step 3:
+ * Remove a permission
+ * Inherit:false
+ * Read, Admin, Allow
+ *
+ * Step 4:
+ * Revert to inherit all permissions
+ * Inherit:true
+ *
+ * This is a unit test so it does some shenanigans to send to the same instance of alfresco.
+ */
+ public void testTransferWithPermissions() throws Exception
+ {
+ setDefaultRollback(false);
+
+ String CONTENT_TITLE = "ContentTitle";
+ String CONTENT_TITLE_UPDATED = "ContentTitleUpdated";
+ Locale CONTENT_LOCALE = Locale.GERMAN;
+ String CONTENT_STRING = "Hello";
+
+ /**
+ * For unit test
+ * - replace the HTTP transport with the in-process transport
+ * - replace the node factory with one that will map node refs, paths etc.
+ */
+ TransferTransmitter transmitter = new UnitTestInProcessTransmitterImpl(receiver, contentService, transactionService);
+ transferServiceImpl.setTransmitter(transmitter);
+ UnitTestTransferManifestNodeFactory testNodeFactory = new UnitTestTransferManifestNodeFactory(this.transferManifestNodeFactory);
+ transferServiceImpl.setTransferManifestNodeFactory(testNodeFactory);
+ List> pathMap = testNodeFactory.getPathMap();
+ // Map company_home/guest_home to company_home so tranferred nodes and moved "up" one level.
+ pathMap.add(new Pair(PathHelper.stringToPath(GUEST_HOME_XPATH_QUERY), PathHelper.stringToPath(COMPANY_HOME_XPATH_QUERY)));
+
+ /**
+ * Now go ahead and create our transfer target
+ */
+ String targetName = "testTransferWithPermissions";
+ TransferTarget transferMe;
+ NodeRef contentNodeRef;
+ NodeRef destNodeRef;
+
+ startNewTransaction();
+ try
+ {
+ /**
+ * Get guest home
+ */
+ String guestHomeQuery = "/app:company_home/app:guest_home";
+ ResultSet guestHomeResult = searchService.query(StoreRef.STORE_REF_WORKSPACE_SPACESSTORE, SearchService.LANGUAGE_XPATH, guestHomeQuery);
+ assertEquals("", 1, guestHomeResult.length());
+ NodeRef guestHome = guestHomeResult.getNodeRef(0);
+
+ /**
+ * Create a test node that we will read and write
+ */
+ String name = GUID.generate();
+ ChildAssociationRef child = nodeService.createNode(guestHome, ContentModel.ASSOC_CONTAINS, QName.createQName(name), ContentModel.TYPE_CONTENT);
+ contentNodeRef = child.getChildRef();
+ nodeService.setProperty(contentNodeRef, ContentModel.PROP_TITLE, CONTENT_TITLE);
+ nodeService.setProperty(contentNodeRef, ContentModel.PROP_NAME, name);
+
+ ContentWriter writer = contentService.getWriter(contentNodeRef, ContentModel.PROP_CONTENT, true);
+ writer.setLocale(CONTENT_LOCALE);
+ writer.putContent(CONTENT_STRING);
+
+ permissionService.setInheritParentPermissions(contentNodeRef, false);
+ permissionService.setPermission(contentNodeRef, "admin", PermissionService.READ, true);
+
+ if(!transferService.targetExists(targetName))
+ {
+ transferMe = createTransferTarget(targetName);
+ }
+ else
+ {
+ transferMe = transferService.getTransferTarget(targetName);
+ }
+ }
+ finally
+ {
+ endTransaction();
+ }
+
+ /**
+ * Step 1
+ */
+ logger.debug("First transfer - create new node with inheritParent permission off");
+ startNewTransaction();
+ try
+ {
+ /**
+ * Transfer our transfer target node
+ */
+ {
+ TransferDefinition definition = new TransferDefinition();
+ Setnodes = new HashSet();
+ nodes.add(contentNodeRef);
+ definition.setNodes(nodes);
+ transferService.transfer(targetName, definition);
+ }
+ }
+ finally
+ {
+ endTransaction();
+ }
+
+ startNewTransaction();
+ try
+ {
+ // Now validate that the target node exists with the correct permissions
+ destNodeRef = testNodeFactory.getMappedNodeRef(contentNodeRef);
+ assertFalse("unit test stuffed up - comparing with self", destNodeRef.equals(transferMe.getNodeRef()));
+ assertTrue("dest node ref does not exist", nodeService.exists(destNodeRef));
+ assertEquals("title is wrong", (String)nodeService.getProperty(destNodeRef, ContentModel.PROP_TITLE), CONTENT_TITLE);
+ assertEquals("type is wrong", nodeService.getType(contentNodeRef), nodeService.getType(destNodeRef));
+
+ // Check ACL of destination node
+ boolean srcInherit = permissionService.getInheritParentPermissions(contentNodeRef);
+ Set srcPerm = permissionService.getAllSetPermissions(contentNodeRef);
+
+ boolean destInherit = permissionService.getInheritParentPermissions(destNodeRef);
+ Set destPerm = permissionService.getAllSetPermissions(destNodeRef);
+
+ assertFalse("inherit parent permissions (src) flag is incorrect", srcInherit);
+ assertFalse("inherit parent permissions (dest) flag is incorrect", destInherit);
+
+ // Check destination has the source's permissions
+ for (AccessPermission p : srcPerm)
+ {
+ logger.debug("checking permission :" + p);
+ assertTrue("permission is missing", destPerm.contains(p));
+ }
+ }
+ finally
+ {
+ endTransaction();
+ }
+
+ /**
+ * Step 2
+ * Update it to have several permissions
+ * Inherit:false
+ * Read, Everyone, DENY
+ * Read, Admin, Allow
+ */
+ startNewTransaction();
+ try
+ {
+ permissionService.setPermission(contentNodeRef, "EVERYONE", PermissionService.READ, false);
+ permissionService.setPermission(contentNodeRef, "admin", PermissionService.FULL_CONTROL, true);
+ }
+ finally
+ {
+ endTransaction();
+ }
+
+ startNewTransaction();
+ try
+ {
+ /**
+ * Transfer our transfer target node
+ */
+ {
+ TransferDefinition definition = new TransferDefinition();
+ Setnodes = new HashSet();
+ nodes.add(contentNodeRef);
+ definition.setNodes(nodes);
+ transferService.transfer(targetName, definition);
+ }
+ }
+ finally
+ {
+ endTransaction();
+ }
+
+
+ startNewTransaction();
+ try
+ {
+ // Now validate that the target node exists with the correct permissions
+ destNodeRef = testNodeFactory.getMappedNodeRef(contentNodeRef);
+
+ // Check ACL of destination node
+ boolean srcInherit = permissionService.getInheritParentPermissions(contentNodeRef);
+ Set srcPerm = permissionService.getAllSetPermissions(contentNodeRef);
+
+ boolean destInherit = permissionService.getInheritParentPermissions(destNodeRef);
+ Set destPerm = permissionService.getAllSetPermissions(destNodeRef);
+
+ assertFalse("inherit parent permissions (src) flag is incorrect", srcInherit);
+ assertFalse("inherit parent permissions (dest) flag is incorrect", destInherit);
+
+ // Check destination has the source's permissions
+ for (AccessPermission p : srcPerm)
+ {
+ logger.debug("checking permission :" + p);
+ assertTrue("Step2, permission is missing", destPerm.contains(p));
+ }
+ }
+ finally
+ {
+ endTransaction();
+ }
+
+ /**
+ * Step 3 Remove a permission
+ */
+ startNewTransaction();
+ try
+ {
+ permissionService.deletePermission(contentNodeRef, "admin", PermissionService.FULL_CONTROL);
+ }
+ finally
+ {
+ endTransaction();
+ }
+
+ startNewTransaction();
+ try
+ {
+ /**
+ * Transfer our transfer target node
+ */
+ {
+ TransferDefinition definition = new TransferDefinition();
+ Setnodes = new HashSet();
+ nodes.add(contentNodeRef);
+ definition.setNodes(nodes);
+ transferService.transfer(targetName, definition);
+ }
+ }
+ finally
+ {
+ endTransaction();
+ }
+
+ startNewTransaction();
+ try
+ {
+ // Now validate that the target node exists with the correct permissions
+ destNodeRef = testNodeFactory.getMappedNodeRef(contentNodeRef);
+
+ // Check ACL of destination node
+ boolean srcInherit = permissionService.getInheritParentPermissions(contentNodeRef);
+ Set srcPerm = permissionService.getAllSetPermissions(contentNodeRef);
+
+ boolean destInherit = permissionService.getInheritParentPermissions(destNodeRef);
+ Set destPerm = permissionService.getAllSetPermissions(destNodeRef);
+
+ assertFalse("inherit parent permissions (src) flag is incorrect", srcInherit);
+ assertFalse("inherit parent permissions (dest) flag is incorrect", destInherit);
+
+ // Check destination has the source's permissions
+ for (AccessPermission p : srcPerm)
+ {
+ logger.debug("checking permission :" + p);
+ assertTrue("permission is missing", destPerm.contains(p));
+ }
+ }
+ finally
+ {
+ endTransaction();
+ }
+
+ /**
+ * Step 4
+ * Revert to inherit all permissions
+ */
+ startNewTransaction();
+ try
+ {
+ permissionService.setInheritParentPermissions(contentNodeRef, true);
+ }
+ finally
+ {
+ endTransaction();
+ }
+
+ startNewTransaction();
+ try
+ {
+ /**
+ * Transfer our transfer target node
+ */
+ {
+ TransferDefinition definition = new TransferDefinition();
+ Setnodes = new HashSet();
+ nodes.add(contentNodeRef);
+ definition.setNodes(nodes);
+ transferService.transfer(targetName, definition);
+ }
+ }
+ finally
+ {
+ endTransaction();
+ }
+
+ startNewTransaction();
+ try
+ {
+ // Now validate that the target node exists with the correct permissions
+ destNodeRef = testNodeFactory.getMappedNodeRef(contentNodeRef);
+ assertFalse("unit test stuffed up - comparing with self", destNodeRef.equals(transferMe.getNodeRef()));
+ assertTrue("dest node ref does not exist", nodeService.exists(destNodeRef));
+ assertEquals("title is wrong", (String)nodeService.getProperty(destNodeRef, ContentModel.PROP_TITLE), CONTENT_TITLE);
+ assertEquals("type is wrong", nodeService.getType(contentNodeRef), nodeService.getType(destNodeRef));
+
+ // Check ACL of destination node
+ boolean srcInherit = permissionService.getInheritParentPermissions(contentNodeRef);
+ Set srcPerm = permissionService.getAllSetPermissions(contentNodeRef);
+
+ boolean destInherit = permissionService.getInheritParentPermissions(destNodeRef);
+ Set destPerm = permissionService.getAllSetPermissions(destNodeRef);
+
+ assertTrue("inherit parent permissions (src) flag is incorrect", srcInherit);
+ assertTrue("inherit parent permissions (dest) flag is incorrect", destInherit);
+
+ // Check destination has the source's permissions
+ for (AccessPermission p : srcPerm)
+ {
+ if(p.isSetDirectly())
+ {
+ logger.debug("checking permission :" + p);
+ assertTrue("permission is missing:" + p, destPerm.contains(p));
+ }
+ }
+ }
+ finally
+ {
+ endTransaction();
+ }
+ }
+
private TransferTarget createTransferTarget(String name)
{
diff --git a/source/java/org/alfresco/repo/transfer/manifest/ManifestModel.java b/source/java/org/alfresco/repo/transfer/manifest/ManifestModel.java
index a05fdd57d8..08f1a62217 100644
--- a/source/java/org/alfresco/repo/transfer/manifest/ManifestModel.java
+++ b/source/java/org/alfresco/repo/transfer/manifest/ManifestModel.java
@@ -30,6 +30,7 @@ public interface ManifestModel extends TransferModel
static final String LOCALNAME_HEADER_CREATED_DATE = "createdDate";
static final String LOCALNAME_HEADER_NODE_COUNT = "nodeCount";
static final String LOCALNAME_HEADER_SYNC = "sync";
+ static final String LOCALNAME_HEADER_RONLY = "readOnly";
static final String LOCALNAME_HEADER_REPOSITORY_ID = "repositoryId";
static final String LOCALNAME_ELEMENT_NODES = "nodes";
static final String LOCALNAME_ELEMENT_NODE = "node";
@@ -53,6 +54,8 @@ public interface ManifestModel extends TransferModel
static final String LOCALNAME_ELEMENT_VALUE_SERIALIZED = "serializedValue";
static final String LOCALNAME_ELEMENT_MLVALUE = "mlvalue";
static final String LOCALNAME_ELEMENT_CONTENT_HEADER = "content";
+ static final String LOCALNAME_ELEMENT_ACL = "acl";
+ static final String LOCALNAME_ELEMENT_ACL_PERMISSION = "permission";
// Manifest file prefix
static final String MANIFEST_PREFIX = "xfer";
diff --git a/source/java/org/alfresco/repo/transfer/manifest/TransferManifestHeader.java b/source/java/org/alfresco/repo/transfer/manifest/TransferManifestHeader.java
index 8881712191..b02c90e131 100644
--- a/source/java/org/alfresco/repo/transfer/manifest/TransferManifestHeader.java
+++ b/source/java/org/alfresco/repo/transfer/manifest/TransferManifestHeader.java
@@ -32,6 +32,7 @@ public class TransferManifestHeader
private int nodeCount;
private String repositoryId;
private boolean isSync;
+ private boolean isReadOnly;
public void setCreatedDate(Date createDate)
{
@@ -87,5 +88,15 @@ public class TransferManifestHeader
return isSync;
}
+ public void setReadOnly(boolean isReadOnly)
+ {
+ this.isReadOnly = isReadOnly;
+ }
+
+ public boolean isReadOnly()
+ {
+ return isReadOnly;
+ }
+
}
diff --git a/source/java/org/alfresco/repo/transfer/manifest/TransferManifestNodeFactoryImpl.java b/source/java/org/alfresco/repo/transfer/manifest/TransferManifestNodeFactoryImpl.java
index 99c187000f..59df1f7f7a 100644
--- a/source/java/org/alfresco/repo/transfer/manifest/TransferManifestNodeFactoryImpl.java
+++ b/source/java/org/alfresco/repo/transfer/manifest/TransferManifestNodeFactoryImpl.java
@@ -18,12 +18,18 @@
*/
package org.alfresco.repo.transfer.manifest;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Set;
+
import org.alfresco.model.ContentModel;
import org.alfresco.service.cmr.repository.ChildAssociationRef;
import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.cmr.repository.NodeService;
import org.alfresco.service.cmr.repository.Path;
import org.alfresco.service.cmr.repository.StoreRef;
+import org.alfresco.service.cmr.security.AccessPermission;
+import org.alfresco.service.cmr.security.PermissionService;
import org.alfresco.service.cmr.transfer.TransferException;
import org.alfresco.service.namespace.RegexQNamePattern;
@@ -36,6 +42,7 @@ import org.alfresco.service.namespace.RegexQNamePattern;
public class TransferManifestNodeFactoryImpl implements TransferManifestNodeFactory
{
private NodeService nodeService;
+ private PermissionService permissionService;
public void init()
{
@@ -113,6 +120,28 @@ public class TransferManifestNodeFactoryImpl implements TransferManifestNodeFact
node.setTargetAssocs(nodeService.getTargetAssocs(nodeRef, RegexQNamePattern.MATCH_ALL ));
node.setSourceAssocs(nodeService.getSourceAssocs(nodeRef, RegexQNamePattern.MATCH_ALL));
+ boolean inherit = permissionService.getInheritParentPermissions(nodeRef);
+
+ ManifestAccessControl acl = new ManifestAccessControl();
+ acl.setInherited(inherit);
+ node.setAccessControl(acl);
+
+ Set permissions = permissionService.getAllSetPermissions(nodeRef);
+
+ List mps = new ArrayList(permissions.size());
+ for(AccessPermission permission : permissions)
+ {
+ if(permission.isSetDirectly())
+ {
+ ManifestPermission mp = new ManifestPermission();
+ mp.setStatus(permission.getAccessStatus().toString());
+ mp.setAuthority(permission.getAuthority());
+ mp.setPermission(permission.getPermission());
+ mps.add(mp);
+ }
+ }
+ acl.setPermissions(mps);
+
return node;
}
}
@@ -127,4 +156,14 @@ public class TransferManifestNodeFactoryImpl implements TransferManifestNodeFact
{
return nodeService;
}
+
+ public void setPermissionService(PermissionService permissionService)
+ {
+ this.permissionService = permissionService;
+ }
+
+ public PermissionService getPermissionService()
+ {
+ return permissionService;
+ }
}
diff --git a/source/java/org/alfresco/repo/transfer/manifest/TransferManifestNormalNode.java b/source/java/org/alfresco/repo/transfer/manifest/TransferManifestNormalNode.java
index 840443a58b..0a8660baea 100644
--- a/source/java/org/alfresco/repo/transfer/manifest/TransferManifestNormalNode.java
+++ b/source/java/org/alfresco/repo/transfer/manifest/TransferManifestNormalNode.java
@@ -49,6 +49,7 @@ public class TransferManifestNormalNode implements TransferManifestNode
private List sourceAssocs;
private List targetAssocs;
private Path parentPath;
+ private ManifestAccessControl accessControl;
public void setNodeRef(NodeRef nodeRef)
{
@@ -79,29 +80,6 @@ public class TransferManifestNormalNode implements TransferManifestNode
{
return properties;
}
-//
-// /**
-// * Gets the property data type
-// *
-// * @param propertyName name of property
-// * @return data type of named property
-// */
-// public DataTypeDefinition getPropertyDataType(QName propertyName);
-//
-// /**
-// * @return the aspects of this node
-// */
-// public Set getNodeAspects();
-//
-// /**
-// * @return true => the node inherits permissions from its parent
-// */
-// public boolean getInheritPermissions();
-//
-// /**
-// * @return the permissions applied to this node
-// */
-// public List getAccessControlEntries();
public void setProperties(Map properties)
{
@@ -188,4 +166,14 @@ public class TransferManifestNormalNode implements TransferManifestNode
return primaryParentAssoc;
}
+ public void setAccessControl(ManifestAccessControl accessControl)
+ {
+ this.accessControl = accessControl;
+ }
+
+ public ManifestAccessControl getAccessControl()
+ {
+ return accessControl;
+ }
+
}
diff --git a/source/java/org/alfresco/repo/transfer/manifest/XMLTransferManifestReader.java b/source/java/org/alfresco/repo/transfer/manifest/XMLTransferManifestReader.java
index 302c24ba91..45bf8e8fca 100644
--- a/source/java/org/alfresco/repo/transfer/manifest/XMLTransferManifestReader.java
+++ b/source/java/org/alfresco/repo/transfer/manifest/XMLTransferManifestReader.java
@@ -312,6 +312,29 @@ public class XMLTransferManifestReader extends DefaultHandler implements Content
ContentData contentHeader = new ContentData(contentURL, mimetype, size.longValue(), encoding, locale);
props.put("contentHeader", contentHeader);
}
+ else if(elementName.equals(ManifestModel.LOCALNAME_ELEMENT_ACL))
+ {
+ String isInherited = (String)atts.getValue("", "isInherited");
+ ManifestAccessControl acl = new ManifestAccessControl();
+
+ if("TRUE".equalsIgnoreCase(isInherited))
+ {
+ acl.setInherited(true);
+ }
+ props.put("acl", acl);
+ }
+ else if(elementName.equals(ManifestModel.LOCALNAME_ELEMENT_ACL_PERMISSION))
+ {
+
+ String authority = (String)atts.getValue("", "authority");
+ String permission = (String)atts.getValue("", "permission");
+ String status = (String)atts.getValue("", "status");
+ ManifestPermission perm = new ManifestPermission();
+ perm.setAuthority(authority);
+ perm.setPermission(permission);
+ perm.setStatus(status);
+ props.put("permission", perm);
+ }
} // if transfer URI
} // startElement
@@ -392,6 +415,11 @@ public class XMLTransferManifestReader extends DefaultHandler implements Content
TransferManifestHeader header = (TransferManifestHeader)props.get("header");
header.setSync(true);
}
+ else if(elementName.equals(ManifestModel.LOCALNAME_HEADER_RONLY))
+ {
+ TransferManifestHeader header = (TransferManifestHeader)props.get("header");
+ header.setReadOnly(true);
+ }
else if(elementName.equals(ManifestModel.LOCALNAME_HEADER_REPOSITORY_ID))
{
TransferManifestHeader header = (TransferManifestHeader)props.get("header");
@@ -574,6 +602,20 @@ public class XMLTransferManifestReader extends DefaultHandler implements Content
ContentData data = (ContentData)props.get("contentHeader");
props.put("value", data);
}
+ else if(elementName.equals(ManifestModel.LOCALNAME_ELEMENT_ACL))
+ {
+ TransferManifestNormalNode node = (TransferManifestNormalNode)props.get("node");
+ ManifestAccessControl acl = (ManifestAccessControl)props.get("acl");
+ node.setAccessControl(acl);
+ }
+ else if(elementName.equals(ManifestModel.LOCALNAME_ELEMENT_ACL_PERMISSION))
+ {
+ ManifestAccessControl acl = (ManifestAccessControl)props.get("acl");
+ ManifestPermission permission = (ManifestPermission)props.get("permission");
+ acl.addPermission(permission);
+ }
+
+
} // if transfer URI
} // end element
diff --git a/source/java/org/alfresco/repo/transfer/manifest/XMLTransferManifestWriter.java b/source/java/org/alfresco/repo/transfer/manifest/XMLTransferManifestWriter.java
index 883221e6ab..562a008154 100644
--- a/source/java/org/alfresco/repo/transfer/manifest/XMLTransferManifestWriter.java
+++ b/source/java/org/alfresco/repo/transfer/manifest/XMLTransferManifestWriter.java
@@ -168,6 +168,17 @@ public class XMLTransferManifestWriter implements TransferManifestWriter
ManifestModel.LOCALNAME_HEADER_SYNC, PREFIX + ":"
+ ManifestModel.LOCALNAME_HEADER_SYNC);
}
+
+ if(header.isReadOnly())
+ {
+ // Is this a read only transfer
+ writer.startElement(TransferModel.TRANSFER_MODEL_1_0_URI,
+ ManifestModel.LOCALNAME_HEADER_RONLY, PREFIX + ":"
+ + ManifestModel.LOCALNAME_HEADER_RONLY, EMPTY_ATTRIBUTES);
+ writer.endElement(TransferModel.TRANSFER_MODEL_1_0_URI,
+ ManifestModel.LOCALNAME_HEADER_RONLY, PREFIX + ":"
+ + ManifestModel.LOCALNAME_HEADER_RONLY);
+ }
// End Header
@@ -259,6 +270,8 @@ public class XMLTransferManifestWriter implements TransferManifestWriter
writeTargetAssocs(node.getTargetAssocs());
writeSourceAssocs(node.getSourceAssocs());
+
+ writeAccessControl(node.getAccessControl());
writer.endElement(TransferModel.TRANSFER_MODEL_1_0_URI,
ManifestModel.LOCALNAME_ELEMENT_NODE, PREFIX + ":"
@@ -654,4 +667,49 @@ public class XMLTransferManifestWriter implements TransferManifestWriter
ManifestModel.LOCALNAME_ELEMENT_ASSOC, PREFIX + ":"
+ ManifestModel.LOCALNAME_ELEMENT_ASSOC);
}
+
+ private void writeAccessControl(ManifestAccessControl acl) throws SAXException
+ {
+ if(acl != null)
+ {
+ AttributesImpl attributes = new AttributesImpl();
+ attributes.addAttribute(TransferModel.TRANSFER_MODEL_1_0_URI, "isInherited", "isInherited", "boolean",
+ acl.isInherited()?"true":"false");
+
+ writer.startElement(TransferModel.TRANSFER_MODEL_1_0_URI,
+ ManifestModel.LOCALNAME_ELEMENT_ACL, PREFIX + ":"
+ + ManifestModel.LOCALNAME_ELEMENT_ACL, attributes);
+
+ if(acl.getPermissions() != null)
+ {
+ for(ManifestPermission permission : acl.getPermissions())
+ {
+ writePermission(permission);
+ }
+ }
+
+ writer.endElement(TransferModel.TRANSFER_MODEL_1_0_URI,
+ ManifestModel.LOCALNAME_ELEMENT_ACL, PREFIX + ":"
+ + ManifestModel.LOCALNAME_ELEMENT_ACL);
+ }
+ }
+
+ private void writePermission(ManifestPermission permission) throws SAXException
+ {
+ AttributesImpl attributes = new AttributesImpl();
+ attributes.addAttribute(TransferModel.TRANSFER_MODEL_1_0_URI, "status", "status", "String",
+ permission.getStatus());
+ attributes.addAttribute(TransferModel.TRANSFER_MODEL_1_0_URI, "authority", "authority", "String",
+ permission.getAuthority());
+ attributes.addAttribute(TransferModel.TRANSFER_MODEL_1_0_URI, "permission", "permission", "String",
+ permission.getPermission());
+
+ writer.startElement(TransferModel.TRANSFER_MODEL_1_0_URI,
+ ManifestModel.LOCALNAME_ELEMENT_ACL_PERMISSION, PREFIX + ":"
+ + ManifestModel.LOCALNAME_ELEMENT_ACL_PERMISSION, attributes);
+
+ writer.endElement(TransferModel.TRANSFER_MODEL_1_0_URI,
+ ManifestModel.LOCALNAME_ELEMENT_ACL_PERMISSION, PREFIX + ":"
+ + ManifestModel.LOCALNAME_ELEMENT_ACL_PERMISSION);
+ }
}
diff --git a/source/java/org/alfresco/service/cmr/transfer/TransferDefinition.java b/source/java/org/alfresco/service/cmr/transfer/TransferDefinition.java
index 9c3470b1bb..58302ed57d 100644
--- a/source/java/org/alfresco/service/cmr/transfer/TransferDefinition.java
+++ b/source/java/org/alfresco/service/cmr/transfer/TransferDefinition.java
@@ -47,9 +47,20 @@ public class TransferDefinition implements Serializable
// Which nodes to deploy
private Set nodes;
-
- // is complete
+
+ /**
+ * isSync specifies whether the list of nodes is to be sync'ed. If sync then the transfer
+ * machinery can determine by the absence of a node or association in the transfer that the missing
+ * nodes should be deleted on the destination.
+ * Else with a non sync transfer then the archive node ref is required to remote a node on the destination.
+ */
private boolean isSync = false;
+
+ /**
+ * isReadOnly specifies whether the transferred nodes should be editable on the destination system.
+ */
+ private boolean isReadOnly = false;
+
/**
* Set which nodes to transfer
@@ -96,4 +107,20 @@ public class TransferDefinition implements Serializable
{
return isSync;
}
+
+ /**
+ * isReadOnly specifies whether the transferred nodes should be editable on the destination system.
+ */
+ public void setReadOnly(boolean isReadOnly)
+ {
+ this.isReadOnly = isReadOnly;
+ }
+
+ /**
+ * isReadOnly specifies whether the transferred nodes should be editable on the destination system.
+ */
+ public boolean isReadOnly()
+ {
+ return isReadOnly;
+ }
}