archivedNodeSorter = new ArchivedDateComparator();
diff --git a/source/java/org/alfresco/repo/web/scripts/bean/ADMRemoteStore.java b/source/java/org/alfresco/repo/web/scripts/bean/ADMRemoteStore.java
index bb86479ef1..af1ad1dcad 100644
--- a/source/java/org/alfresco/repo/web/scripts/bean/ADMRemoteStore.java
+++ b/source/java/org/alfresco/repo/web/scripts/bean/ADMRemoteStore.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2005-2012 Alfresco Software Limited.
+ * Copyright (C) 2005-2013 Alfresco Software Limited.
*
* This file is part of Alfresco
*
@@ -26,7 +26,9 @@ import java.io.Writer;
import java.net.SocketException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
+import java.util.Arrays;
import java.util.HashMap;
+import java.util.HashSet;
import java.util.List;
import java.util.Locale;
import java.util.Map;
@@ -47,6 +49,7 @@ import org.alfresco.query.PagingRequest;
import org.alfresco.query.PagingResults;
import org.alfresco.repo.content.MimetypeMap;
import org.alfresco.repo.model.filefolder.HiddenAspect;
+import org.alfresco.repo.policy.BehaviourFilter;
import org.alfresco.repo.security.authentication.AuthenticationUtil;
import org.alfresco.repo.security.authentication.AuthenticationUtil.RunAsWork;
import org.alfresco.repo.security.permissions.AccessDeniedException;
@@ -119,6 +122,7 @@ public class ADMRemoteStore extends BaseRemoteStore
protected SiteService siteService;
protected ContentService contentService;
protected HiddenAspect hiddenAspect;
+ private BehaviourFilter behaviourFilter;
/**
* Date format pattern used to parse HTTP date headers in RFC 1123 format.
@@ -179,7 +183,12 @@ public class ADMRemoteStore extends BaseRemoteStore
{
this.hiddenAspect = hiddenAspect;
}
-
+
+ public void setBehaviourFilter(BehaviourFilter behaviourFilter)
+ {
+ this.behaviourFilter = behaviourFilter;
+ }
+
/**
* Gets the last modified timestamp for the document.
*
@@ -459,17 +468,30 @@ public class ADMRemoteStore extends BaseRemoteStore
{
throw new IllegalStateException("Unable to aquire parent folder reference for path: " + path);
}
- FileInfo fileInfo = fileFolderService.create(
- parentFolder.getNodeRef(), encpath.substring(off + 1), ContentModel.TYPE_CONTENT);
- Map aspectProperties = new HashMap(1, 1.0f);
- aspectProperties.put(ContentModel.PROP_IS_INDEXED, false);
- unprotNodeService.addAspect(fileInfo.getNodeRef(), ContentModel.ASPECT_INDEX_CONTROL, aspectProperties);
- ContentWriter writer = contentService.getWriter(
- fileInfo.getNodeRef(), ContentModel.PROP_CONTENT, true);
- writer.guessMimetype(fileInfo.getName());
- writer.putContent(content);
- if (logger.isDebugEnabled())
- logger.debug("createDocument: " + fileInfo.toString());
+
+ // ALF-17729 / ALF-17796 - disable auditable on parent folder
+ NodeRef parentFolderRef = parentFolder.getNodeRef();
+ behaviourFilter.disableBehaviour(parentFolderRef, ContentModel.ASPECT_AUDITABLE);
+
+ try
+ {
+ FileInfo fileInfo = fileFolderService.create(
+ parentFolderRef, encpath.substring(off + 1), ContentModel.TYPE_CONTENT);
+ Map aspectProperties = new HashMap(1, 1.0f);
+ aspectProperties.put(ContentModel.PROP_IS_INDEXED, false);
+ unprotNodeService.addAspect(fileInfo.getNodeRef(), ContentModel.ASPECT_INDEX_CONTROL, aspectProperties);
+ ContentWriter writer = contentService.getWriter(
+ fileInfo.getNodeRef(), ContentModel.PROP_CONTENT, true);
+ writer.guessMimetype(fileInfo.getName());
+ writer.putContent(content);
+ if (logger.isDebugEnabled())
+ logger.debug("createDocument: " + fileInfo.toString());
+ }
+ finally
+ {
+ behaviourFilter.enableBehaviour(parentFolderRef, ContentModel.ASPECT_AUDITABLE);
+ }
+
return null;
}
}, runAsUser);
@@ -532,7 +554,20 @@ public class ADMRemoteStore extends BaseRemoteStore
{
final NodeRef fileRef = fileInfo.getNodeRef();
this.nodeService.addAspect(fileRef, ContentModel.ASPECT_TEMPORARY, null);
- this.nodeService.deleteNode(fileRef);
+
+ // ALF-17729
+ NodeRef parentFolderRef = unprotNodeService.getPrimaryParent(fileRef).getParentRef();
+ behaviourFilter.disableBehaviour(parentFolderRef, ContentModel.ASPECT_AUDITABLE);
+
+ try
+ {
+ this.nodeService.deleteNode(fileRef);
+ }
+ finally
+ {
+ behaviourFilter.enableBehaviour(parentFolderRef, ContentModel.ASPECT_AUDITABLE);
+ }
+
if (logger.isDebugEnabled())
logger.debug("deleteDocument: " + fileInfo.toString());
}
@@ -736,11 +771,14 @@ public class ADMRemoteStore extends BaseRemoteStore
if (create)
{
// ensure folders exist down to the specified parent
+ // ALF-17729 / ALF-17796 - disable auditable on parent folders
result = FileFolderUtil.makeFolders(
this.fileFolderService,
surfConfigRef,
isFolder ? pathElements : pathElements.subList(0, pathElements.size() - 1),
- ContentModel.TYPE_FOLDER);
+ ContentModel.TYPE_FOLDER,
+ behaviourFilter,
+ new HashSet(Arrays.asList(new QName[]{ContentModel.ASPECT_AUDITABLE})));
}
else
{
diff --git a/source/java/org/alfresco/repo/web/scripts/discussion/DiscussionRestApiTest.java b/source/java/org/alfresco/repo/web/scripts/discussion/DiscussionRestApiTest.java
index e2f55c3fff..d259440f35 100644
--- a/source/java/org/alfresco/repo/web/scripts/discussion/DiscussionRestApiTest.java
+++ b/source/java/org/alfresco/repo/web/scripts/discussion/DiscussionRestApiTest.java
@@ -50,6 +50,7 @@ import org.alfresco.service.transaction.TransactionService;
import org.alfresco.util.PropertyMap;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
+import org.json.JSONArray;
import org.json.JSONObject;
import org.springframework.extensions.webscripts.Status;
import org.springframework.extensions.webscripts.TestWebScriptServer.DeleteRequest;
@@ -1205,4 +1206,35 @@ public class DiscussionRestApiTest extends BaseWebScriptTest
assertEquals(1, result.getJSONArray("items").getJSONObject(0).getInt("replyCount"));
}
+ /**
+ * https://issues.alfresco.com/jira/browse/ALF-17443 reports that site contributors are unable
+ * to edit replies that they have made.
+ */
+ public void testContributorCanEditReply() throws Exception
+ {
+ authenticationComponent.setCurrentUser(USER_ONE);
+ JSONObject post = createSitePost("Can contributors edit replies?", "The title says it all", Status.STATUS_OK);
+ NodeRef postNodeRef = new NodeRef(post.getString("nodeRef"));
+
+ authenticationComponent.setCurrentUser(USER_TWO);
+ JSONObject reply = createReply(postNodeRef, "", "Let's see.", Status.STATUS_OK);
+ NodeRef replyNodeRef = new NodeRef(reply.getString("nodeRef"));
+ updateComment(replyNodeRef, "", "Yes I can", Status.STATUS_OK);
+
+ authenticationComponent.setCurrentUser(USER_ONE);
+
+ post = getPost(postNodeRef, Status.STATUS_OK);
+ assertEquals("Can contributors edit replies?", post.getString("title"));
+ assertEquals("The title says it all", post.getString("content"));
+ assertEquals(1, post.getInt("replyCount"));
+
+ JSONObject replies = getReplies(postNodeRef, Status.STATUS_OK);
+ JSONArray items = replies.getJSONArray("items");
+ assertEquals(1, items.length());
+
+ reply = items.getJSONObject(0);
+ assertEquals("Yes I can", reply.getString("content"));
+
+ }
+
}
diff --git a/source/java/org/alfresco/repo/web/scripts/discussion/ForumPostPut.java b/source/java/org/alfresco/repo/web/scripts/discussion/ForumPostPut.java
index a79b45d7b8..c3394e7f83 100644
--- a/source/java/org/alfresco/repo/web/scripts/discussion/ForumPostPut.java
+++ b/source/java/org/alfresco/repo/web/scripts/discussion/ForumPostPut.java
@@ -89,15 +89,17 @@ public class ForumPostPut extends AbstractDiscussionWebScript
private void doUpdatePost(PostInfo post, TopicInfo topic, WebScriptRequest req,
JSONObject json)
{
+ boolean updateTopic = false;
// Fetch the details from the JSON
-
- // Update the titles on the post and it's topic
+
+ // Update the titles on the post and it's topic
if (json.containsKey("title"))
{
String title = (String)json.get("title");
post.setTitle(title);
if (title.length() > 0)
{
+ updateTopic = true;
topic.setTitle(title);
}
}
@@ -118,10 +120,14 @@ public class ForumPostPut extends AbstractDiscussionWebScript
{
topic.getTags().addAll(tags);
}
+ updateTopic = true;
}
// Save the topic and the post
- discussionService.updateTopic(topic);
+ if (updateTopic == true)
+ {
+ discussionService.updateTopic(topic);
+ }
discussionService.updatePost(post);
}
}
diff --git a/source/java/org/alfresco/repo/web/scripts/solr/SOLRSerializer.java b/source/java/org/alfresco/repo/web/scripts/solr/SOLRSerializer.java
index 28fe1f100a..ad28845912 100644
--- a/source/java/org/alfresco/repo/web/scripts/solr/SOLRSerializer.java
+++ b/source/java/org/alfresco/repo/web/scripts/solr/SOLRSerializer.java
@@ -128,7 +128,9 @@ import org.springframework.extensions.webscripts.json.JSONUtils;
// Treat it as text
return new PropertyValue(true, serializeToJSONString(value));
}
- else if (propertyDef.isMultiValued())
+ DataTypeDefinition dataType = propertyDef.getDataType();
+ QName dataTypeName = dataType.getName();
+ if (propertyDef.isMultiValued())
{
if(!(value instanceof Collection))
{
@@ -140,7 +142,28 @@ import org.springframework.extensions.webscripts.json.JSONUtils;
JSONArray body = new JSONArray();
for(Serializable o : c)
{
- body.put(serializeToJSONString(o));
+ if(dataTypeName.equals(DataTypeDefinition.MLTEXT))
+ {
+ MLText source = (MLText)o;
+ JSONArray array = new JSONArray();
+ for(Locale locale : source.getLocales())
+ {
+ JSONObject json = new JSONObject();
+ json.put("locale", DefaultTypeConverter.INSTANCE.convert(String.class, locale));
+ json.put("value", source.getValue(locale));
+ array.put(json);
+ }
+ body.put(array);
+ }
+ else if(dataTypeName.equals(DataTypeDefinition.CONTENT))
+ {
+ throw new RuntimeException("Multi-valued content properties are not supported");
+ }
+ else
+ {
+ body.put(serializeToJSONString(o));
+ }
+
}
return new PropertyValue(false, body.toString());
@@ -148,8 +171,6 @@ import org.springframework.extensions.webscripts.json.JSONUtils;
else
{
boolean encodeString = true;
- DataTypeDefinition dataType = propertyDef.getDataType();
- QName dataTypeName = dataType.getName();
if(dataTypeName.equals(DataTypeDefinition.MLTEXT))
{
encodeString = false;
diff --git a/source/java/org/alfresco/repo/web/scripts/wiki/WikiPageListGet.java b/source/java/org/alfresco/repo/web/scripts/wiki/WikiPageListGet.java
index 6ffd82ea56..27d186bb90 100644
--- a/source/java/org/alfresco/repo/web/scripts/wiki/WikiPageListGet.java
+++ b/source/java/org/alfresco/repo/web/scripts/wiki/WikiPageListGet.java
@@ -174,6 +174,20 @@ public class WikiPageListGet extends AbstractWikiWebScript
wiki.put("pages", items); // Old style
wiki.put("container", container);
+ if (userFiltering)
+ {
+ // We need to get all the wiki pages for "My Pages" filter otherwise
+ // the links for renamed wiki pages won't be rendered correctly,
+ // which were created by other users
+ pages = wikiService.listWikiPages(site.getShortName(), paging);
+ List pageTitles = new ArrayList(pages.getPage().size());
+ for (WikiPageInfo page : pages.getPage())
+ {
+ pageTitles.add(page.getTitle());
+ }
+ wiki.put("pageTitles", pageTitles);
+ }
+
Map model = new HashMap();
model.put("data", data); // New style
model.put("wiki", wiki);
diff --git a/source/java/org/alfresco/repo/web/scripts/workflow/AbstractWorkflowRestApiTest.java b/source/java/org/alfresco/repo/web/scripts/workflow/AbstractWorkflowRestApiTest.java
index 452bb9f41a..1a40973c12 100644
--- a/source/java/org/alfresco/repo/web/scripts/workflow/AbstractWorkflowRestApiTest.java
+++ b/source/java/org/alfresco/repo/web/scripts/workflow/AbstractWorkflowRestApiTest.java
@@ -307,13 +307,14 @@ public abstract class AbstractWorkflowRestApiTest extends BaseWebScriptTest
// Retrieve tasks using the workflow instance
String baseUrl = MessageFormat.format(URL_WORKFLOW_TASKS, workflowId);
- // Check returns the completed start task and the current task.
+ // Check returns the completed start task.
String adhocTaskId = task.getId();
- checkTasksMatch(baseUrl, startTaskId, adhocTaskId);
+ checkTasksMatch(baseUrl, startTaskId);
String completedUrl = baseUrl + "?state=" + WorkflowTaskState.COMPLETED;
checkTasksMatch(completedUrl, startTaskId);
+ personManager.setUser(USER2);
String inProgressUrl = baseUrl + "?state=" + WorkflowTaskState.IN_PROGRESS;
checkTasksMatch(inProgressUrl, adhocTaskId);
diff --git a/source/java/org/alfresco/repo/web/scripts/workflow/TaskInstancesGet.java b/source/java/org/alfresco/repo/web/scripts/workflow/TaskInstancesGet.java
index d80279d2c5..0053e870cb 100644
--- a/source/java/org/alfresco/repo/web/scripts/workflow/TaskInstancesGet.java
+++ b/source/java/org/alfresco/repo/web/scripts/workflow/TaskInstancesGet.java
@@ -32,8 +32,9 @@ import javax.servlet.http.HttpServletResponse;
import org.alfresco.repo.workflow.WorkflowModel;
import org.alfresco.service.cmr.workflow.WorkflowTask;
import org.alfresco.service.cmr.workflow.WorkflowTaskQuery;
-import org.alfresco.service.cmr.workflow.WorkflowTaskState;
import org.alfresco.service.cmr.workflow.WorkflowTaskQuery.OrderBy;
+import org.alfresco.service.cmr.workflow.WorkflowTaskState;
+import org.alfresco.util.ModelUtil;
import org.springframework.extensions.webscripts.Cache;
import org.springframework.extensions.webscripts.Status;
import org.springframework.extensions.webscripts.WebScriptException;
@@ -68,6 +69,12 @@ public class TaskInstancesGet extends AbstractWorkflowWebscript
// authority is not included into filters list as it will be taken into account before filtering
String authority = getAuthority(req);
+ if (authority == null)
+ {
+ // ALF-11036 fix, if authority argument is omitted the tasks for the current user should be returned.
+ authority = authenticationService.getCurrentUserName();
+ }
+
// state is also not included into filters list, for the same reason
WorkflowTaskState state = getState(req);
@@ -120,8 +127,8 @@ public class TaskInstancesGet extends AbstractWorkflowWebscript
// no workflow instance id is present so get all tasks
if (authority != null)
{
- List tasks = workflowService.getAssignedTasks(authority, state);
- List pooledTasks = workflowService.getPooledTasks(authority);
+ List tasks = workflowService.getAssignedTasks(authority, state, true);
+ List pooledTasks = workflowService.getPooledTasks(authority, true);
if (pooledTasksOnly != null)
{
if (pooledTasksOnly.booleanValue())
@@ -159,18 +166,40 @@ public class TaskInstancesGet extends AbstractWorkflowWebscript
}
}
- // filter results
+ int maxItems = getIntParameter(req, PARAM_MAX_ITEMS, DEFAULT_MAX_ITEMS);
+ int skipCount = getIntParameter(req, PARAM_SKIP_COUNT, DEFAULT_SKIP_COUNT);
+ int totalCount = 0;
ArrayList