Merged HEAD (5.2) to 5.2.N (5.2.1)

126565 jkaabimofrad: Merged FILE-FOLDER-API (5.2.0) to HEAD (5.2)
      124562 gjames: RA-884: Posting activities for file/folder added/updated


git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/BRANCHES/DEV/5.2.N/root@126911 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
This commit is contained in:
Ancuta Morarasu
2016-05-11 12:09:51 +00:00
parent 587a169e0e
commit 490e2345da
3 changed files with 185 additions and 5 deletions

View File

@@ -471,6 +471,7 @@
<property name="behaviourFilter" ref="policyBehaviourFilter"/> <property name="behaviourFilter" ref="policyBehaviourFilter"/>
<property name="ignoreTypes" ref="nodes.ignoreTypes"/> <property name="ignoreTypes" ref="nodes.ignoreTypes"/>
<property name="nonAttachContentTypes" ref="nodes.nonAttachContentTypes"/> <property name="nonAttachContentTypes" ref="nodes.nonAttachContentTypes"/>
<property name="poster" ref="activitiesPoster" />
</bean> </bean>
<bean id="Nodes" class="org.springframework.aop.framework.ProxyFactoryBean"> <bean id="Nodes" class="org.springframework.aop.framework.ProxyFactoryBean">

View File

@@ -47,7 +47,9 @@ import org.alfresco.model.ContentModel;
import org.alfresco.model.QuickShareModel; import org.alfresco.model.QuickShareModel;
import org.alfresco.query.PagingRequest; import org.alfresco.query.PagingRequest;
import org.alfresco.query.PagingResults; import org.alfresco.query.PagingResults;
import org.alfresco.repo.Client;
import org.alfresco.repo.action.executer.ContentMetadataExtracter; import org.alfresco.repo.action.executer.ContentMetadataExtracter;
import org.alfresco.repo.activities.ActivityType;
import org.alfresco.repo.content.ContentLimitViolationException; import org.alfresco.repo.content.ContentLimitViolationException;
import org.alfresco.repo.content.MimetypeMap; import org.alfresco.repo.content.MimetypeMap;
import org.alfresco.repo.model.Repository; import org.alfresco.repo.model.Repository;
@@ -99,6 +101,7 @@ import org.alfresco.service.ServiceRegistry;
import org.alfresco.service.cmr.action.Action; import org.alfresco.service.cmr.action.Action;
import org.alfresco.service.cmr.action.ActionDefinition; import org.alfresco.service.cmr.action.ActionDefinition;
import org.alfresco.service.cmr.action.ActionService; import org.alfresco.service.cmr.action.ActionService;
import org.alfresco.service.cmr.activities.ActivityPoster;
import org.alfresco.service.cmr.dictionary.AspectDefinition; import org.alfresco.service.cmr.dictionary.AspectDefinition;
import org.alfresco.service.cmr.dictionary.DataTypeDefinition; import org.alfresco.service.cmr.dictionary.DataTypeDefinition;
import org.alfresco.service.cmr.dictionary.DictionaryService; import org.alfresco.service.cmr.dictionary.DictionaryService;
@@ -159,6 +162,7 @@ import org.springframework.http.MediaType;
public class NodesImpl implements Nodes public class NodesImpl implements Nodes
{ {
private static final Log logger = LogFactory.getLog(NodesImpl.class); private static final Log logger = LogFactory.getLog(NodesImpl.class);
private static final String APP_TOOL = "API";
private enum Type private enum Type
{ {
@@ -181,6 +185,7 @@ public class NodesImpl implements Nodes
private OwnableService ownableService; private OwnableService ownableService;
private AuthorityService authorityService; private AuthorityService authorityService;
private ThumbnailService thumbnailService; private ThumbnailService thumbnailService;
private ActivityPoster poster;
private BehaviourFilter behaviourFilter; private BehaviourFilter behaviourFilter;
@@ -254,6 +259,11 @@ public class NodesImpl implements Nodes
this.defaultIgnoreTypesAndAspects = ignoreTypesAndAspects; this.defaultIgnoreTypesAndAspects = ignoreTypesAndAspects;
} }
public void setPoster(ActivityPoster poster)
{
this.poster = poster;
}
// excluded namespaces (aspects and properties) // excluded namespaces (aspects and properties)
private static final List<String> EXCLUDED_NS = Arrays.asList(NamespaceService.SYSTEM_MODEL_1_0_URI); private static final List<String> EXCLUDED_NS = Arrays.asList(NamespaceService.SYSTEM_MODEL_1_0_URI);
@@ -1482,6 +1492,7 @@ public class NodesImpl implements Nodes
private NodeRef createNodeImpl(NodeRef parentNodeRef, String nodeName, QName nodeTypeQName, Map<QName, Serializable> props) private NodeRef createNodeImpl(NodeRef parentNodeRef, String nodeName, QName nodeTypeQName, Map<QName, Serializable> props)
{ {
NodeRef newNode = null;
if (props == null) if (props == null)
{ {
props = new HashMap<>(1); props = new HashMap<>(1);
@@ -1493,13 +1504,24 @@ public class NodesImpl implements Nodes
QName assocQName = QName.createQName(NamespaceService.CONTENT_MODEL_1_0_URI, QName.createValidLocalName(nodeName)); QName assocQName = QName.createQName(NamespaceService.CONTENT_MODEL_1_0_URI, QName.createValidLocalName(nodeName));
try try
{ {
return nodeService.createNode(parentNodeRef, ContentModel.ASSOC_CONTAINS, assocQName, nodeTypeQName, props).getChildRef(); newNode = nodeService.createNode(parentNodeRef, ContentModel.ASSOC_CONTAINS, assocQName, nodeTypeQName, props).getChildRef();
} }
catch (DuplicateChildNodeNameException dcne) catch (DuplicateChildNodeNameException dcne)
{ {
// duplicate - name clash // duplicate - name clash
throw new ConstraintViolatedException(dcne.getMessage()); throw new ConstraintViolatedException(dcne.getMessage());
} }
boolean isFolder = isSubClass(nodeTypeQName, ContentModel.TYPE_FOLDER);
boolean isContent = isSubClass(nodeTypeQName, ContentModel.TYPE_CONTENT);
if (isFolder || isContent)
{
FileInfo fileInfo = fileFolderService.getFileInfo(newNode);
poster.postSiteAwareFileFolderActivity(isFolder?ActivityType.FOLDER_ADDED:ActivityType.FILE_ADDED, null, TenantUtil.getCurrentDomain(),
null, parentNodeRef, newNode, nodeName, APP_TOOL, Client.asType(Client.ClientType.script), fileInfo);
}
return newNode;
} }
// check cm:cmobject (but *not* cm:systemfolder) // check cm:cmobject (but *not* cm:systemfolder)
@@ -1715,7 +1737,16 @@ public class NodesImpl implements Nodes
} }
} }
return getFolderOrDocument(nodeRef.getId(), parameters); Node updatedNode = getFolderOrDocument(nodeRef.getId(), parameters);
boolean isContent = isSubClass(nodeTypeQName, ContentModel.TYPE_CONTENT);
if (isContent)
{
FileInfo fileInfo = fileFolderService.getFileInfo(nodeRef);
poster.postSiteAwareFileFolderActivity(ActivityType.FILE_UPDATED, null, TenantUtil.getCurrentDomain(),
null, updatedNode.getParentId(), updatedNode.getNodeRef(), updatedNode.getName(), APP_TOOL, Client.asType(Client.ClientType.script), fileInfo);
}
return updatedNode;
} }
@Override @Override
@@ -1855,12 +1886,14 @@ public class NodesImpl implements Nodes
} }
String versionComment = parameters.getParameter(PARAM_VERSION_COMMENT); String versionComment = parameters.getParameter(PARAM_VERSION_COMMENT);
return updateExistingFile(nodeRef, contentInfo, stream, parameters, versionMajor, versionComment); final String fileName = (String) nodeService.getProperty(nodeRef, ContentModel.PROP_NAME);
return updateExistingFile(null, nodeRef, fileName, contentInfo, stream, parameters, versionMajor, versionComment);
} }
private Node updateExistingFile(NodeRef nodeRef, BasicContentInfo contentInfo, InputStream stream, Parameters parameters, Boolean versionMajor, String versionComment) private Node updateExistingFile(NodeRef parentNodeRef, NodeRef nodeRef, String fileName, BasicContentInfo contentInfo, InputStream stream, Parameters parameters, Boolean versionMajor, String versionComment)
{ {
boolean isVersioned = versionService.isVersioned(nodeRef); boolean isVersioned = versionService.isVersioned(nodeRef);
FileInfo fileInfo = fileFolderService.getFileInfo(nodeRef);
behaviourFilter.disableBehaviour(nodeRef, ContentModel.ASPECT_VERSIONABLE); behaviourFilter.disableBehaviour(nodeRef, ContentModel.ASPECT_VERSIONABLE);
try try
@@ -1877,6 +1910,9 @@ public class NodesImpl implements Nodes
createVersion(nodeRef, isVersioned, versionType, versionComment); createVersion(nodeRef, isVersioned, versionType, versionComment);
} }
poster.postSiteAwareFileFolderActivity(ActivityType.FILE_UPDATED, null, TenantUtil.getCurrentDomain(),
null, parentNodeRef, nodeRef, fileName, APP_TOOL, Client.asType(Client.ClientType.script), fileInfo);
extractMetadata(nodeRef); extractMetadata(nodeRef);
} }
finally finally
@@ -2081,7 +2117,7 @@ public class NodesImpl implements Nodes
{ {
// overwrite existing (versionable) file // overwrite existing (versionable) file
BasicContentInfo contentInfo = new ContentInfoImpl(content.getMimetype(), content.getEncoding(), -1, null); BasicContentInfo contentInfo = new ContentInfoImpl(content.getMimetype(), content.getEncoding(), -1, null);
return updateExistingFile(existingFile, contentInfo, content.getInputStream(), parameters, majorVersion, versionComment); return updateExistingFile(parentNodeRef, existingFile, fileName, contentInfo, content.getInputStream(), parameters, majorVersion, versionComment);
} }
else else
{ {

View File

@@ -0,0 +1,143 @@
package org.alfresco.rest.api.tests;
import static org.alfresco.rest.api.tests.util.RestApiUtil.toJsonAsStringNonNull;
import static org.junit.Assert.*;
import org.alfresco.repo.activities.ActivityType;
import org.alfresco.repo.security.authentication.AuthenticationUtil;
import org.alfresco.repo.tenant.TenantUtil;
import org.alfresco.repo.transaction.RetryingTransactionHelper;
import org.alfresco.rest.api.Activities;
import org.alfresco.rest.api.tests.client.HttpResponse;
import org.alfresco.rest.api.tests.client.PublicApiClient;
import org.alfresco.rest.api.tests.client.data.Activity;
import org.alfresco.rest.api.tests.client.data.ContentInfo;
import org.alfresco.rest.api.tests.client.data.Document;
import org.alfresco.rest.api.tests.client.data.Folder;
import org.alfresco.rest.api.tests.util.RestApiUtil;
import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.cmr.security.MutableAuthenticationService;
import org.alfresco.service.cmr.security.PersonService;
import org.alfresco.service.cmr.site.SiteVisibility;
import org.json.simple.JSONObject;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* Created by gethin on 22/03/16.
*/
public class ActivitiesPostingTest extends AbstractBaseApiTest
{
protected MutableAuthenticationService authenticationService;
protected PersonService personService;
RepoService.TestNetwork networkOne;
RepoService.TestPerson u1;
RepoService.TestSite tSite;
NodeRef docLibNodeRef;
@Override
public String getScope()
{
return "public";
}
@Before
public void setup() throws Exception
{
authenticationService = applicationContext.getBean("authenticationService", MutableAuthenticationService.class);
personService = applicationContext.getBean("personService", PersonService.class);
networkOne = getTestFixture().getRandomNetwork();
u1 = networkOne.createUser();
tSite = createSite(networkOne, u1, SiteVisibility.PRIVATE);
AuthenticationUtil.setFullyAuthenticatedUser(u1.getId());
docLibNodeRef = tSite.getContainerNodeRef("documentLibrary");
AuthenticationUtil.clearCurrentSecurityContext();
}
@After
public void tearDown() throws Exception
{
AuthenticationUtil.setAdminUserAsFullyAuthenticatedUser();
transactionHelper.doInTransaction(new RetryingTransactionHelper.RetryingTransactionCallback<Void>()
{
@Override
public Void execute() throws Throwable
{
if (personService.personExists(u1.getId()))
{
authenticationService.deleteAuthentication(u1.getId());
personService.deletePerson(u1.getId());
}
return null;
}
});
AuthenticationUtil.clearCurrentSecurityContext();
}
@Test
public void testCreateUpdate() throws Exception
{
String folder1 = "folder" + System.currentTimeMillis() + "_1";
Folder createdFolder = createFolder(u1.getId(), docLibNodeRef.getId(), folder1, null);
assertNotNull(createdFolder);
Document d1 = new Document();
d1.setName("d1.txt");
d1.setNodeType("cm:content");
ContentInfo ci = new ContentInfo();
ci.setMimeType("text/plain");
d1.setContent(ci);
// create empty file
HttpResponse response = post(getNodeChildrenUrl(createdFolder.getId()), u1.getId(), toJsonAsStringNonNull(d1), 201);
Document documentResp = RestApiUtil.parseRestApiEntry(response.getJsonResponse(), Document.class);
//Update the file
Document dUpdate = new Document();
dUpdate.setName("d1b.txt");
response = put(URL_NODES, u1.getId(), documentResp.getId(), toJsonAsStringNonNull(dUpdate), null, 200);
repoService.generateFeed();
Map<String, String> meParams = new HashMap<>();
meParams.put("who", String.valueOf(Activities.ActivityWho.me));
PublicApiClient.ListResponse<Activity> activities = publicApiClient.people().getActivities(u1.getId(), meParams);
assertEquals(activities.getList().size(),3);
Activity act = matchActivity(activities.getList(), ActivityType.FOLDER_ADDED, u1.getId(), tSite.getSiteId(), docLibNodeRef.getId(), folder1);
assertNotNull(act);
act = matchActivity(activities.getList(), ActivityType.FILE_ADDED, u1.getId(), tSite.getSiteId(), createdFolder.getId(), d1.getName());
assertNotNull(act);
act = matchActivity(activities.getList(), ActivityType.FILE_UPDATED, u1.getId(), tSite.getSiteId(), createdFolder.getId(), dUpdate.getName());
assertNotNull(act);
}
private Activity matchActivity(List<Activity> list, String type, String user, String siteId, String parentId, String title)
{
for (Activity act:list)
{
if (type.equals(act.getActivityType())
&& user.equals(act.getPostPersonId())
&& siteId.equals(act.getSiteId())
&& parentId.equals(act.getSummary().get("parentObjectId"))
&& title.equals((act.getSummary().get("title"))))
{
return act;
}
}
return null;
}
}