diff --git a/config/alfresco/templates/webscripts/org/alfresco/repository/discussions/posts/forum-post.get.js b/config/alfresco/templates/webscripts/org/alfresco/repository/discussions/posts/forum-post.get.js deleted file mode 100644 index f6668b6e96..0000000000 --- a/config/alfresco/templates/webscripts/org/alfresco/repository/discussions/posts/forum-post.get.js +++ /dev/null @@ -1,41 +0,0 @@ - - - -/* - * Fetches the correct post data (either topic post or post depending on the node type - */ -function fetchPostData(node) -{ - // we have to differentiate here whether this is a top-level post or a reply - // only in the first case we fetch all information (as returned by forum/.../posts) - if (node.type == "{http://www.alfresco.org/model/forum/1.0}topic") - { - model.postData = getTopicPostData(node); - } - else if (node.type == "{http://www.alfresco.org/model/forum/1.0}post") - { - model.postData = getReplyPostData(node); - } - else - { - status.setCode(STATUS_BAD_REQUEST, "Incompatible node type. Required either fm:topic or fm:post. Received: " + node.type); - } -} - -function main() -{ - // get requested node - var node = getRequestNode(); - if (status.getCode() != status.STATUS_OK) - { - return; - } - - fetchPostData(node); - - // fetch the contentLength param - var contentLength = args["contentLength"] != undefined ? parseInt(args["contentLength"]) : -1; - model.contentLength = isNaN(contentLength) ? -1 : contentLength; -} - -main(); diff --git a/config/alfresco/web-scripts-application-context.xml b/config/alfresco/web-scripts-application-context.xml index 24dbd6f6ca..d776a0d924 100644 --- a/config/alfresco/web-scripts-application-context.xml +++ b/config/alfresco/web-scripts-application-context.xml @@ -1568,15 +1568,14 @@ + - renderTopic(TopicInfo topic) + /* + * Was topicpost.lib.js getReplyPostData + * + * TODO Switch the FTL to prefer the Info object rather than the ScriptNode + */ + protected Map renderPost(PostInfo post, SiteInfo site) { - Map res = new HashMap(); - res.put("topic", topic); - res.put("node", topic.getNodeRef()); - res.put("name", topic.getSystemName()); - res.put("title", topic.getTitle()); - res.put("tags", topic.getTags()); + Map item = new HashMap(); + item.put(KEY_IS_TOPIC_POST, false); + item.put(KEY_POST, post.getNodeRef()); + item.put(KEY_CAN_EDIT, canUserEditPost(post, site)); + item.put(KEY_AUTHOR, buildPerson(post.getCreator())); + return item; + } + + /* + * Was topicpost.lib.js getTopicPostData / getTopicPostDataFromTopicAndPosts + * + * TODO Switch the FTL to prefer the Info object rather than the ScriptNode + */ + protected Map renderTopic(TopicInfo topic, SiteInfo site) + { + // Fetch all the posts for the topic + // TODO We actually only need the count, the first and the last + // In the interest of keeping our life simply, get all of them + PagingRequest paging = new PagingRequest(MAX_QUERY_ENTRY_COUNT); + paging.setRequestTotalCountMax(MAX_QUERY_ENTRY_COUNT); + PagingResults posts = discussionService.listPosts(topic, paging); - // Both forms used for dates - res.put("createdOn", topic.getCreatedAt()); - res.put("modifiedOn", topic.getModifiedAt()); - res.put("created", topic.getCreatedAt()); - res.put("modified", topic.getModifiedAt()); - - // FTL needs a script node of the people - res.put("createdBy", buildPerson(topic.getCreator())); - res.put("modifiedBY", buildPerson(topic.getModifier())); - - // We want blank instead of null - for(String key : res.keySet()) + // Ensure we got a primary post + if(posts.getPage().size() == 0) { - if(res.get(key) == null) - { - res.put(key, ""); - } + throw new WebScriptException(Status.STATUS_PRECONDITION_FAILED, + "First (primary) post was missing from the topic, can't fetch"); } - return res; + // Grab the posts of interest + PostInfo primaryPost = posts.getPage().get(0); + // The posts in a topic listing are ordered by created date + PostInfo mostRecentPost = posts.getPage().get(posts.getPage().size()-1); + + // Build the details + Map item = new HashMap(); + item.put(KEY_IS_TOPIC_POST, true); + item.put(KEY_TOPIC, topic.getNodeRef()); + item.put(KEY_POST, primaryPost.getNodeRef()); + item.put(KEY_CAN_EDIT, canUserEditPost(primaryPost, site)); + item.put(KEY_AUTHOR, buildPerson(topic.getCreator())); + + // The reply count is one less than all posts (first is the primary one) + item.put("totalReplyCount", posts.getTotalResultCount().getFirst() - 1); + + // We want details on the most recent post + if(posts.getPage().size() > 1) + { + item.put("lastReply", mostRecentPost.getNodeRef()); + item.put("lastReplyBy", buildPerson(mostRecentPost.getCreator())); + } + + // Include the tags + item.put("tags", topic.getTags()); + + // All done + return item; + } + + protected Map buildCommonModel(SiteInfo site, TopicInfo topic, + PostInfo post, WebScriptRequest req) + { + // Build the common model parts + Map model = new HashMap(); + model.put(KEY_TOPIC, topic); + model.put(KEY_POST, post); + + // Capture the site details only if site based + if(site != null) + { + model.put("siteId", site.getShortName()); + model.put("site", site); + } + + // The limit on the length of the content to be returned + int contentLength = -1; + String contentLengthS = req.getParameter("contentLength"); + if(contentLengthS != null) + { + try + { + contentLength = Integer.parseInt(contentLengthS); + } + catch(NumberFormatException e) + { + logger.info("Skipping invalid length " + contentLengthS); + } + } + model.put("contentLength", contentLength); + + // All done + return model; } @Override @@ -310,6 +430,13 @@ public abstract class AbstractDiscussionWebScript extends DeclarativeWebScript { String name = templateVars.get("path"); topic = discussionService.getTopic(site.getShortName(), name); + + if(topic == null) + { + String error = "Could not find topic: " + name; + throw new WebScriptException(Status.STATUS_NOT_FOUND, error); + } + nodeRef = topic.getNodeRef(); } } else if(templateVars.containsKey("store_type") && diff --git a/source/java/org/alfresco/repo/web/scripts/discussion/ForumPostDelete.java b/source/java/org/alfresco/repo/web/scripts/discussion/ForumPostDelete.java index d8783f419a..90f5ce377f 100644 --- a/source/java/org/alfresco/repo/web/scripts/discussion/ForumPostDelete.java +++ b/source/java/org/alfresco/repo/web/scripts/discussion/ForumPostDelete.java @@ -18,7 +18,6 @@ */ package org.alfresco.repo.web.scripts.discussion; -import java.util.HashMap; import java.util.Map; import org.alfresco.service.cmr.discussion.PostInfo; @@ -47,14 +46,7 @@ public class ForumPostDelete extends AbstractDiscussionWebScript Status status, Cache cache) { // Build the common model parts - Map model = new HashMap(); - model.put("topic", topic); - model.put("post", post); - if(site != null) - { - model.put("siteId", site.getShortName()); - model.put("site", site); - } + Map model = buildCommonModel(site, topic, post, req); // Are we deleting a topic, or a post in it? diff --git a/source/java/org/alfresco/repo/web/scripts/discussion/ForumPostGet.java b/source/java/org/alfresco/repo/web/scripts/discussion/ForumPostGet.java new file mode 100644 index 0000000000..64aa967c50 --- /dev/null +++ b/source/java/org/alfresco/repo/web/scripts/discussion/ForumPostGet.java @@ -0,0 +1,69 @@ +/* + * Copyright (C) 2005-2011 Alfresco Software Limited. + * + * This file is part of Alfresco + * + * Alfresco is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Alfresco is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with Alfresco. If not, see . + */ +package org.alfresco.repo.web.scripts.discussion; + +import java.util.Map; + +import org.alfresco.service.cmr.discussion.PostInfo; +import org.alfresco.service.cmr.discussion.TopicInfo; +import org.alfresco.service.cmr.repository.NodeRef; +import org.alfresco.service.cmr.site.SiteInfo; +import org.json.JSONObject; +import org.springframework.extensions.webscripts.Cache; +import org.springframework.extensions.webscripts.Status; +import org.springframework.extensions.webscripts.WebScriptException; +import org.springframework.extensions.webscripts.WebScriptRequest; + +/** + * This class is the controller for the discussions page fetching forum-post.get webscript. + * + * @author Nick Burch + * @since 4.0 + */ +public class ForumPostGet extends AbstractDiscussionWebScript +{ + private static final String KEY_POSTDATA = "postData"; + + @Override + protected Map executeImpl(SiteInfo site, NodeRef nodeRef, + TopicInfo topic, PostInfo post, WebScriptRequest req, JSONObject json, + Status status, Cache cache) + { + // Build the common model parts + Map model = buildCommonModel(site, topic, post, req); + + // Did they want just one post, or the whole of the topic? + if(post != null) + { + model.put(KEY_POSTDATA, renderPost(post, site)); + } + else if(topic != null) + { + model.put(KEY_POSTDATA, renderTopic(topic, site)); + } + else + { + String error = "Node was of the wrong type, only Topic and Post are supported"; + throw new WebScriptException(Status.STATUS_BAD_REQUEST, error); + } + + // All done + return model; + } +}