transfer service : transfers permissions.

now sets cm:modifiedDate on update + unit test.
    new permissions unit test.
    added "readOnly" flag to API  does nothing yet.

git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@21204 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
This commit is contained in:
Mark Rogers
2010-07-15 15:53:07 +00:00
parent 37e0b65814
commit f805895f51
11 changed files with 664 additions and 31 deletions

View File

@@ -51,6 +51,7 @@
<bean id="transferManifestNodeFactory" class="org.alfresco.repo.transfer.manifest.TransferManifestNodeFactoryImpl" init-method="init" > <bean id="transferManifestNodeFactory" class="org.alfresco.repo.transfer.manifest.TransferManifestNodeFactoryImpl" init-method="init" >
<property name="nodeService" ref="NodeService" /> <property name="nodeService" ref="NodeService" />
<property name="permissionService" ref="PermissionService" />
</bean> </bean>
@@ -101,8 +102,9 @@
<bean id="transferManifestProcessorFactory" <bean id="transferManifestProcessorFactory"
class="org.alfresco.repo.transfer.DefaultManifestProcessorFactoryImpl"> class="org.alfresco.repo.transfer.DefaultManifestProcessorFactoryImpl">
<property name="nodeService" ref="NodeService" /> <property name="nodeService" ref="NodeService" />
<property name="contentService" ref="ContentService" /> <property name="contentService" ref="ContentService"></property>
<property name="dictionaryService" ref="DictionaryService" /> <property name="dictionaryService" ref="DictionaryService" />
<property name="permissionService" ref="PermissionService" />
<property name="nodeResolverFactory" ref="transferNodeResolverFactory" /> <property name="nodeResolverFactory" ref="transferNodeResolverFactory" />
</bean> </bean>

View File

@@ -27,17 +27,18 @@ import org.alfresco.repo.transfer.requisite.TransferRequsiteWriter;
import org.alfresco.service.cmr.dictionary.DictionaryService; import org.alfresco.service.cmr.dictionary.DictionaryService;
import org.alfresco.service.cmr.repository.ContentService; import org.alfresco.service.cmr.repository.ContentService;
import org.alfresco.service.cmr.repository.NodeService; import org.alfresco.service.cmr.repository.NodeService;
import org.alfresco.service.cmr.security.PermissionService;
import org.alfresco.service.cmr.transfer.TransferReceiver; import org.alfresco.service.cmr.transfer.TransferReceiver;
/** /**
* @author brian * @author brian
*
*/ */
public class DefaultManifestProcessorFactoryImpl implements ManifestProcessorFactory public class DefaultManifestProcessorFactoryImpl implements ManifestProcessorFactory
{ {
private NodeService nodeService; private NodeService nodeService;
private ContentService contentService; private ContentService contentService;
private DictionaryService dictionaryService; private DictionaryService dictionaryService;
private PermissionService permissionService;
private CorrespondingNodeResolverFactory nodeResolverFactory; private CorrespondingNodeResolverFactory nodeResolverFactory;
/* /*
@@ -55,6 +56,7 @@ public class DefaultManifestProcessorFactoryImpl implements ManifestProcessorFac
primaryProcessor.setNodeResolver(nodeResolver); primaryProcessor.setNodeResolver(nodeResolver);
primaryProcessor.setNodeService(nodeService); primaryProcessor.setNodeService(nodeService);
primaryProcessor.setDictionaryService(dictionaryService); primaryProcessor.setDictionaryService(dictionaryService);
primaryProcessor.setPermissionService(getPermissionService());
processors.add(primaryProcessor); processors.add(primaryProcessor);
RepoSecondaryManifestProcessorImpl secondaryProcessor = new RepoSecondaryManifestProcessorImpl(receiver, transferId); RepoSecondaryManifestProcessorImpl secondaryProcessor = new RepoSecondaryManifestProcessorImpl(receiver, transferId);
@@ -119,4 +121,14 @@ public class DefaultManifestProcessorFactoryImpl implements ManifestProcessorFac
return processor; return processor;
} }
public void setPermissionService(PermissionService permissionService)
{
this.permissionService = permissionService;
}
public PermissionService getPermissionService()
{
return permissionService;
}
} }

View File

@@ -30,6 +30,8 @@ import java.util.Set;
import org.alfresco.model.ContentModel; import org.alfresco.model.ContentModel;
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.ManifestPermission;
import org.alfresco.repo.transfer.manifest.TransferManifestDeletedNode; import org.alfresco.repo.transfer.manifest.TransferManifestDeletedNode;
import org.alfresco.repo.transfer.manifest.TransferManifestHeader; import org.alfresco.repo.transfer.manifest.TransferManifestHeader;
import org.alfresco.repo.transfer.manifest.TransferManifestNode; 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.NodeRef;
import org.alfresco.service.cmr.repository.NodeService; import org.alfresco.service.cmr.repository.NodeService;
import org.alfresco.service.cmr.repository.StoreRef; 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.cmr.transfer.TransferReceiver;
import org.alfresco.service.namespace.QName; import org.alfresco.service.namespace.QName;
import org.apache.commons.logging.Log; import org.apache.commons.logging.Log;
@@ -78,6 +83,7 @@ public class RepoPrimaryManifestProcessorImpl extends AbstractManifestProcessorB
} }
private NodeService nodeService; private NodeService nodeService;
private PermissionService permissionService;
private ContentService contentService; private ContentService contentService;
private DictionaryService dictionaryService; private DictionaryService dictionaryService;
private CorrespondingNodeResolver nodeResolver; private CorrespondingNodeResolver nodeResolver;
@@ -319,6 +325,27 @@ public class RepoPrimaryManifestProcessorImpl extends AbstractManifestProcessorB
{ {
nodeService.addAspect(newNode.getChildRef(), aspect, null); 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 // Is the node that we've just added the parent of any orphans that
// we've found earlier? // we've found earlier?
@@ -435,6 +462,70 @@ public class RepoPrimaryManifestProcessorImpl extends AbstractManifestProcessorB
{ {
nodeService.removeAspect(nodeToUpdate, aspect); 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<AccessPermission> existingPermissions = permissionService.getAllSetPermissions(nodeToUpdate);
List<ManifestPermission> newPermissions = acl.getPermissions();
if(existingPermissions.size() > 0 || newPermissions != null)
{
// Yes we have explicit permissions on this node.
log.debug("have to check permissions");
Set<ManifestPermission>work = new HashSet<ManifestPermission>();
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; this.nodeResolver = nodeResolver;
} }
public void setPermissionService(PermissionService permissionService)
{
this.permissionService = permissionService;
}
public PermissionService getPermissionService()
{
return permissionService;
}
} }

View File

@@ -48,7 +48,9 @@ import org.alfresco.service.cmr.repository.Path;
import org.alfresco.service.cmr.repository.StoreRef; import org.alfresco.service.cmr.repository.StoreRef;
import org.alfresco.service.cmr.search.ResultSet; import org.alfresco.service.cmr.search.ResultSet;
import org.alfresco.service.cmr.search.SearchService; 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.MutableAuthenticationService;
import org.alfresco.service.cmr.security.PermissionService;
import org.alfresco.service.cmr.transfer.TransferCallback; import org.alfresco.service.cmr.transfer.TransferCallback;
import org.alfresco.service.cmr.transfer.TransferDefinition; import org.alfresco.service.cmr.transfer.TransferDefinition;
import org.alfresco.service.cmr.transfer.TransferEvent; import org.alfresco.service.cmr.transfer.TransferEvent;
@@ -86,6 +88,7 @@ public class TransferServiceImplTest extends BaseAlfrescoSpringTest
private TransactionService transactionService; private TransactionService transactionService;
private TransferReceiver receiver; private TransferReceiver receiver;
private TransferManifestNodeFactory transferManifestNodeFactory; private TransferManifestNodeFactory transferManifestNodeFactory;
private PermissionService permissionService;
String COMPANY_HOME_XPATH_QUERY = "/{http://www.alfresco.org/model/application/1.0}company_home"; 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"; 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.contentService = (ContentService) this.applicationContext.getBean("contentService");
this.authenticationService = (MutableAuthenticationService) this.applicationContext.getBean("authenticationService"); this.authenticationService = (MutableAuthenticationService) this.applicationContext.getBean("authenticationService");
this.actionService = (ActionService)this.applicationContext.getBean("actionService"); this.actionService = (ActionService)this.applicationContext.getBean("actionService");
this.permissionService = (PermissionService)this.applicationContext.getBean("permissionService");
this.receiver = (TransferReceiver)this.applicationContext.getBean("transferReceiver"); this.receiver = (TransferReceiver)this.applicationContext.getBean("transferReceiver");
this.transferManifestNodeFactory = (TransferManifestNodeFactory)this.applicationContext.getBean("transferManifestNodeFactory"); this.transferManifestNodeFactory = (TransferManifestNodeFactory)this.applicationContext.getBean("transferManifestNodeFactory");
this.authenticationComponent = (AuthenticationComponent) this.applicationContext.getBean("authenticationComponent"); 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); Date srcModifiedDate = (Date)nodeService.getProperty(contentNodeRef, ContentModel.PROP_MODIFIED);
logger.debug("srcModifiedDate : " + srcModifiedDate + " destModifiedDate : " + destModifiedDate); logger.debug("srcModifiedDate : " + srcModifiedDate + " destModifiedDate : " + destModifiedDate);
assertTrue("after update, modified date is not correct", destModifiedDate.compareTo(srcModifiedDate) == 0);
// BUGBUG - MER 14/07/2010 - can't set modified date
// assertTrue("after update, modified date is not correct", destModifiedDate.compareTo(srcModifiedDate) == 0);
Date destCreatedDate = (Date)nodeService.getProperty(destNodeRef, ContentModel.PROP_CREATED); Date destCreatedDate = (Date)nodeService.getProperty(destNodeRef, ContentModel.PROP_CREATED);
Date srcCreatedDate = (Date)nodeService.getProperty(contentNodeRef, 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<Pair<Path, Path>> pathMap = testNodeFactory.getPathMap();
// Map company_home/guest_home to company_home so tranferred nodes and moved "up" one level.
pathMap.add(new Pair<Path, Path>(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();
Set<NodeRef>nodes = new HashSet<NodeRef>();
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<AccessPermission> srcPerm = permissionService.getAllSetPermissions(contentNodeRef);
boolean destInherit = permissionService.getInheritParentPermissions(destNodeRef);
Set<AccessPermission> 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();
Set<NodeRef>nodes = new HashSet<NodeRef>();
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<AccessPermission> srcPerm = permissionService.getAllSetPermissions(contentNodeRef);
boolean destInherit = permissionService.getInheritParentPermissions(destNodeRef);
Set<AccessPermission> 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();
Set<NodeRef>nodes = new HashSet<NodeRef>();
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<AccessPermission> srcPerm = permissionService.getAllSetPermissions(contentNodeRef);
boolean destInherit = permissionService.getInheritParentPermissions(destNodeRef);
Set<AccessPermission> 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();
Set<NodeRef>nodes = new HashSet<NodeRef>();
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<AccessPermission> srcPerm = permissionService.getAllSetPermissions(contentNodeRef);
boolean destInherit = permissionService.getInheritParentPermissions(destNodeRef);
Set<AccessPermission> 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) private TransferTarget createTransferTarget(String name)
{ {

View File

@@ -30,6 +30,7 @@ public interface ManifestModel extends TransferModel
static final String LOCALNAME_HEADER_CREATED_DATE = "createdDate"; static final String LOCALNAME_HEADER_CREATED_DATE = "createdDate";
static final String LOCALNAME_HEADER_NODE_COUNT = "nodeCount"; static final String LOCALNAME_HEADER_NODE_COUNT = "nodeCount";
static final String LOCALNAME_HEADER_SYNC = "sync"; 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_HEADER_REPOSITORY_ID = "repositoryId";
static final String LOCALNAME_ELEMENT_NODES = "nodes"; static final String LOCALNAME_ELEMENT_NODES = "nodes";
static final String LOCALNAME_ELEMENT_NODE = "node"; 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_VALUE_SERIALIZED = "serializedValue";
static final String LOCALNAME_ELEMENT_MLVALUE = "mlvalue"; static final String LOCALNAME_ELEMENT_MLVALUE = "mlvalue";
static final String LOCALNAME_ELEMENT_CONTENT_HEADER = "content"; 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 // Manifest file prefix
static final String MANIFEST_PREFIX = "xfer"; static final String MANIFEST_PREFIX = "xfer";

View File

@@ -32,6 +32,7 @@ public class TransferManifestHeader
private int nodeCount; private int nodeCount;
private String repositoryId; private String repositoryId;
private boolean isSync; private boolean isSync;
private boolean isReadOnly;
public void setCreatedDate(Date createDate) public void setCreatedDate(Date createDate)
{ {
@@ -87,5 +88,15 @@ public class TransferManifestHeader
return isSync; return isSync;
} }
public void setReadOnly(boolean isReadOnly)
{
this.isReadOnly = isReadOnly;
}
public boolean isReadOnly()
{
return isReadOnly;
}
} }

View File

@@ -18,12 +18,18 @@
*/ */
package org.alfresco.repo.transfer.manifest; 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.model.ContentModel;
import org.alfresco.service.cmr.repository.ChildAssociationRef; import org.alfresco.service.cmr.repository.ChildAssociationRef;
import org.alfresco.service.cmr.repository.NodeRef; import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.cmr.repository.NodeService; import org.alfresco.service.cmr.repository.NodeService;
import org.alfresco.service.cmr.repository.Path; import org.alfresco.service.cmr.repository.Path;
import org.alfresco.service.cmr.repository.StoreRef; 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.cmr.transfer.TransferException;
import org.alfresco.service.namespace.RegexQNamePattern; import org.alfresco.service.namespace.RegexQNamePattern;
@@ -36,6 +42,7 @@ import org.alfresco.service.namespace.RegexQNamePattern;
public class TransferManifestNodeFactoryImpl implements TransferManifestNodeFactory public class TransferManifestNodeFactoryImpl implements TransferManifestNodeFactory
{ {
private NodeService nodeService; private NodeService nodeService;
private PermissionService permissionService;
public void init() public void init()
{ {
@@ -113,6 +120,28 @@ public class TransferManifestNodeFactoryImpl implements TransferManifestNodeFact
node.setTargetAssocs(nodeService.getTargetAssocs(nodeRef, RegexQNamePattern.MATCH_ALL )); node.setTargetAssocs(nodeService.getTargetAssocs(nodeRef, RegexQNamePattern.MATCH_ALL ));
node.setSourceAssocs(nodeService.getSourceAssocs(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<AccessPermission> permissions = permissionService.getAllSetPermissions(nodeRef);
List<ManifestPermission> mps = new ArrayList<ManifestPermission>(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; return node;
} }
} }
@@ -127,4 +156,14 @@ public class TransferManifestNodeFactoryImpl implements TransferManifestNodeFact
{ {
return nodeService; return nodeService;
} }
public void setPermissionService(PermissionService permissionService)
{
this.permissionService = permissionService;
}
public PermissionService getPermissionService()
{
return permissionService;
}
} }

View File

@@ -49,6 +49,7 @@ public class TransferManifestNormalNode implements TransferManifestNode
private List<AssociationRef> sourceAssocs; private List<AssociationRef> sourceAssocs;
private List<AssociationRef> targetAssocs; private List<AssociationRef> targetAssocs;
private Path parentPath; private Path parentPath;
private ManifestAccessControl accessControl;
public void setNodeRef(NodeRef nodeRef) public void setNodeRef(NodeRef nodeRef)
{ {
@@ -79,29 +80,6 @@ public class TransferManifestNormalNode implements TransferManifestNode
{ {
return properties; 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<QName> getNodeAspects();
//
// /**
// * @return true => the node inherits permissions from its parent
// */
// public boolean getInheritPermissions();
//
// /**
// * @return the permissions applied to this node
// */
// public List<AccessPermission> getAccessControlEntries();
public void setProperties(Map<QName,Serializable> properties) public void setProperties(Map<QName,Serializable> properties)
{ {
@@ -188,4 +166,14 @@ public class TransferManifestNormalNode implements TransferManifestNode
return primaryParentAssoc; return primaryParentAssoc;
} }
public void setAccessControl(ManifestAccessControl accessControl)
{
this.accessControl = accessControl;
}
public ManifestAccessControl getAccessControl()
{
return accessControl;
}
} }

View File

@@ -312,6 +312,29 @@ public class XMLTransferManifestReader extends DefaultHandler implements Content
ContentData contentHeader = new ContentData(contentURL, mimetype, size.longValue(), encoding, locale); ContentData contentHeader = new ContentData(contentURL, mimetype, size.longValue(), encoding, locale);
props.put("contentHeader", contentHeader); 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 } // if transfer URI
} // startElement } // startElement
@@ -392,6 +415,11 @@ public class XMLTransferManifestReader extends DefaultHandler implements Content
TransferManifestHeader header = (TransferManifestHeader)props.get("header"); TransferManifestHeader header = (TransferManifestHeader)props.get("header");
header.setSync(true); 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)) else if(elementName.equals(ManifestModel.LOCALNAME_HEADER_REPOSITORY_ID))
{ {
TransferManifestHeader header = (TransferManifestHeader)props.get("header"); TransferManifestHeader header = (TransferManifestHeader)props.get("header");
@@ -574,6 +602,20 @@ public class XMLTransferManifestReader extends DefaultHandler implements Content
ContentData data = (ContentData)props.get("contentHeader"); ContentData data = (ContentData)props.get("contentHeader");
props.put("value", data); 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 } // if transfer URI
} // end element } // end element

View File

@@ -168,6 +168,17 @@ public class XMLTransferManifestWriter implements TransferManifestWriter
ManifestModel.LOCALNAME_HEADER_SYNC, PREFIX + ":" ManifestModel.LOCALNAME_HEADER_SYNC, PREFIX + ":"
+ ManifestModel.LOCALNAME_HEADER_SYNC); + 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 // End Header
@@ -259,6 +270,8 @@ public class XMLTransferManifestWriter implements TransferManifestWriter
writeTargetAssocs(node.getTargetAssocs()); writeTargetAssocs(node.getTargetAssocs());
writeSourceAssocs(node.getSourceAssocs()); writeSourceAssocs(node.getSourceAssocs());
writeAccessControl(node.getAccessControl());
writer.endElement(TransferModel.TRANSFER_MODEL_1_0_URI, writer.endElement(TransferModel.TRANSFER_MODEL_1_0_URI,
ManifestModel.LOCALNAME_ELEMENT_NODE, PREFIX + ":" ManifestModel.LOCALNAME_ELEMENT_NODE, PREFIX + ":"
@@ -654,4 +667,49 @@ public class XMLTransferManifestWriter implements TransferManifestWriter
ManifestModel.LOCALNAME_ELEMENT_ASSOC, PREFIX + ":" ManifestModel.LOCALNAME_ELEMENT_ASSOC, PREFIX + ":"
+ ManifestModel.LOCALNAME_ELEMENT_ASSOC); + 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);
}
} }

View File

@@ -47,9 +47,20 @@ public class TransferDefinition implements Serializable
// Which nodes to deploy // Which nodes to deploy
private Set<NodeRef> nodes; private Set<NodeRef> 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; 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 * Set which nodes to transfer
@@ -96,4 +107,20 @@ public class TransferDefinition implements Serializable
{ {
return isSync; 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;
}
} }