View Javadoc
1   /*
2    * Copyright (C) 2003-2008 eXo Platform SAS.
3    *
4    * This program is free software; you can redistribute it and/or
5    * modify it under the terms of the GNU Affero General Public License
6    * as published by the Free Software Foundation; either version 3
7    * of the License, or (at your option) any later version.
8    *
9    * This program is distributed in the hope that it will be useful,
10   * but WITHOUT ANY WARRANTY; without even the implied warranty of
11   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12   * GNU General Public License for more details.
13   *
14   * You should have received a copy of the GNU General Public License
15   * along with this program; if not, see<http://www.gnu.org/licenses/>.
16   */
17  package org.exoplatform.wcm.connector.collaboration;
18  
19  import java.net.URLDecoder;
20  import java.text.DateFormat;
21  import java.text.SimpleDateFormat;
22  import java.util.Date;
23  import java.util.List;
24  
25  import javax.jcr.Node;
26  import javax.ws.rs.*;
27  import javax.ws.rs.core.MediaType;
28  import javax.ws.rs.core.Response;
29  import javax.xml.parsers.DocumentBuilderFactory;
30  import javax.xml.transform.dom.DOMSource;
31  
32  import org.apache.commons.lang.StringUtils;
33  import org.exoplatform.ecm.connector.fckeditor.FCKUtils;
34  import org.exoplatform.services.cms.comments.CommentsService;
35  import org.exoplatform.services.rest.resource.ResourceContainer;
36  import org.exoplatform.services.wcm.portal.PortalFolderSchemaHandler;
37  import org.exoplatform.services.wcm.webcontent.WebContentSchemaHandler;
38  import org.exoplatform.wcm.connector.BaseConnector;
39  import org.w3c.dom.Document;
40  import org.w3c.dom.Element;
41  
42  
43  /**
44   * The CommentConnector aims to manage and use comments for the content.
45   *
46   * @LevelAPI Experimental
47   *
48   * @anchor CommentConnector
49   */
50  @Path("/contents/comment/")
51  public class CommentConnector extends BaseConnector implements ResourceContainer {
52  
53    CommentsService commentsService;
54  
55    /**
56     * Instantiates a new tag connector.
57     *
58     * @param commentsService Service instantiation.
59     */
60    public CommentConnector(CommentsService commentsService) {
61      this.commentsService = commentsService;
62    }
63  
64  
65    /**
66     *
67     * Adds a new comment to the content.
68     *
69     * @param jcrPath The JCR path of the content.
70     * @param comment The comment to add.
71     * @return The last modified date as a property to check the result.
72     * @throws Exception The exception
73     *
74     * @anchor CommentConnector.addComment
75     */
76    @POST
77    @Path("/add")
78    public Response addComment(
79            @FormParam("jcrPath") String jcrPath,
80            @FormParam("comment") String comment
81            ) throws Exception {
82  
83      Node content = getNode(jcrPath);
84  
85      commentsService.addComment(content, content.getSession().getUserID(), null, null, comment,null);
86  
87      DateFormat dateFormat = new SimpleDateFormat(IF_MODIFIED_SINCE_DATE_FORMAT);
88      return Response.ok().header(LAST_MODIFIED_PROPERTY, dateFormat.format(new Date())).build();
89  
90    }
91  
92    /**
93     * Gets all comments for a specific content.
94     *
95     * @param jcrPath The JCR path of the content.
96     * @return All comments
97     * @throws Exception The exception
98     *
99     * @anchor CommentConnector.getComments
100    */
101   @GET
102   @Path("/all")
103   public Response getComments(
104           @QueryParam("jcrPath") String jcrPath
105           ) throws Exception {
106 
107     try {
108       Node content = getNode(jcrPath);
109 
110       List<Node> comments = commentsService.getComments(content, null);
111 
112       Document document =
113         DocumentBuilderFactory.newInstance().newDocumentBuilder().newDocument();
114       Element tagsElt = document.createElement("comments");
115 
116       for (Node comment:comments) {
117         Element tagElt = document.createElement("comment");
118         //exo:name
119         Element id = document.createElement("id");
120         id.setTextContent(comment.getName());
121         //exo:commentor
122         Element commentor = document.createElement("commentor");
123         commentor.setTextContent(comment.getProperty("exo:commentor").getString());
124         //exo:commentorEmail
125         Element commentorEmail = document.createElement("email");
126         if (comment.hasProperty("exo:commentorEmail")) {
127           commentorEmail.setTextContent(comment.getProperty("exo:commentorEmail").getString());
128         }
129         //exo:commentDate
130         Element date = document.createElement("date");
131         date.setTextContent(DateFormat.getDateTimeInstance().format(comment.getProperty("exo:commentDate").getDate().getTime()));
132 
133         //exo:commentContent
134         Element commentElt = document.createElement("content");
135         commentElt.setTextContent(comment.getProperty("exo:commentContent").getString());
136 
137         tagElt.appendChild(id);
138         tagElt.appendChild(commentor);
139         tagElt.appendChild(commentorEmail);
140         tagElt.appendChild(date);
141         tagElt.appendChild(commentElt);
142         tagsElt.appendChild(tagElt);
143       }
144       document.appendChild(tagsElt);
145 
146       DateFormat dateFormat = new SimpleDateFormat(IF_MODIFIED_SINCE_DATE_FORMAT);
147       return Response.ok(new DOMSource(document), MediaType.TEXT_XML)
148                      .header(LAST_MODIFIED_PROPERTY, dateFormat.format(new Date()))
149                      .build();
150     } catch (Exception e){
151       Response.serverError().build();
152     }
153 
154 
155     DateFormat dateFormat = new SimpleDateFormat(IF_MODIFIED_SINCE_DATE_FORMAT);
156     return Response.ok().header(LAST_MODIFIED_PROPERTY, dateFormat.format(new Date())).build();
157 
158   }
159 
160   /**
161    *
162    * Delete a comment of a content.
163    *
164    * @param jcrPath The JCR path of the content.
165    * @param commentId The id of the comment to delete.
166    * @return
167    * @throws Exception The exception
168    *
169    * @anchor CommentConnector.deleteComment
170    */
171   @DELETE
172   @Path("/delete")
173   public Response deleteComment(
174           @QueryParam("jcrPath") String jcrPath,
175           @QueryParam("commentId") String commentId
176   ) throws Exception {
177 
178     if(StringUtils.isEmpty(jcrPath) || StringUtils.isEmpty(commentId)) {
179       return Response.status(400).entity("jcrPath and commentId query parameters are mandatory").build();
180     }
181 
182     Node content = getNode(jcrPath);
183 
184     if(content.hasNode("comments")) {
185       Node commentsNode = content.getNode("comments");
186       if(commentsNode.hasNode(commentId)) {
187         commentsService.deleteComment(commentsNode.getNode(commentId));
188       } else {
189         return Response.noContent().build();
190       }
191     } else {
192       return Response.noContent().build();
193     }
194 
195     return Response.ok().build();
196   }
197 
198   /**
199    * Get the jcr node of the given jcr path
200    * @param jcrPath
201    * @return The node of the given jcr path
202    * @throws Exception
203    */
204   protected Node getNode(@QueryParam("jcrPath") String jcrPath) throws Exception {
205     if (jcrPath.contains("%20")) {
206       jcrPath = URLDecoder.decode(jcrPath, "UTF-8");
207     }
208     String[] path = jcrPath.split("/");
209     String repositoryName = path[1];
210     String workspaceName = path[2];
211     jcrPath = jcrPath.substring(repositoryName.length()+workspaceName.length()+2);
212     if (jcrPath.charAt(1)=='/') {
213       jcrPath.substring(1);
214     }
215     return getContent(workspaceName, jcrPath, null, false);
216   }
217 
218 
219   /*
220    * (non-Javadoc)
221    * @see
222    * org.exoplatform.wcm.connector.fckeditor.BaseConnector#getRootContentStorage
223    * (javax.jcr.Node)
224    */
225   @Override
226   protected Node getRootContentStorage(Node parentNode) throws Exception {
227     try {
228       PortalFolderSchemaHandler folderSchemaHandler =
229         webSchemaConfigService.getWebSchemaHandlerByType(PortalFolderSchemaHandler.class);
230       return folderSchemaHandler.getDocumentStorage(parentNode);
231     } catch (Exception e) {
232       WebContentSchemaHandler webContentSchemaHandler =
233         webSchemaConfigService.getWebSchemaHandlerByType(WebContentSchemaHandler.class);
234       return webContentSchemaHandler.getDocumentFolder(parentNode);
235     }
236   }
237 
238   /*
239    * (non-Javadoc)
240    * @see
241    * org.exoplatform.wcm.connector.fckeditor.BaseConnector#getContentStorageType
242    * ()
243    */
244   @Override
245   protected String getContentStorageType() throws Exception {
246     return FCKUtils.DOCUMENT_TYPE;
247   }
248 
249 }