View Javadoc
1   /***************************************************************************
2    * Copyright (C) 2003-2009 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   **************************************************************************/
18  package org.exoplatform.wcm.connector.collaboration;
19  
20  import java.text.DateFormat;
21  import java.text.SimpleDateFormat;
22  import java.util.ArrayList;
23  import java.util.Arrays;
24  import java.util.Calendar;
25  import java.util.Collections;
26  import java.util.Date;
27  import java.util.List;
28  
29  import javax.jcr.Node;
30  import javax.jcr.NodeIterator;
31  import javax.jcr.RepositoryException;
32  import javax.jcr.Session;
33  import javax.jcr.query.Query;
34  import javax.jcr.query.QueryManager;
35  import javax.jcr.query.QueryResult;
36  import javax.ws.rs.GET;
37  import javax.ws.rs.Path;
38  import javax.ws.rs.PathParam;
39  import javax.ws.rs.QueryParam;
40  import javax.ws.rs.core.MediaType;
41  import javax.ws.rs.core.Response;
42  
43  import org.apache.commons.lang.StringUtils;
44  import org.exoplatform.ecm.utils.comparator.PropertyValueComparator;
45  import org.exoplatform.services.cms.drives.DriveData;
46  import org.exoplatform.services.cms.drives.ManageDriveService;
47  import org.exoplatform.services.cms.folksonomy.NewFolksonomyService;
48  import org.exoplatform.services.cms.templates.TemplateService;
49  import org.exoplatform.services.jcr.RepositoryService;
50  import org.exoplatform.services.jcr.core.ManageableRepository;
51  import org.exoplatform.services.jcr.ext.common.SessionProvider;
52  import org.exoplatform.services.jcr.impl.core.query.QueryImpl;
53  import org.exoplatform.services.log.ExoLogger;
54  import org.exoplatform.services.log.Log;
55  import org.exoplatform.services.rest.resource.ResourceContainer;
56  import org.exoplatform.services.wcm.utils.WCMCoreUtils;
57  
58  /**
59   * Returns the latest edited documents.
60   *
61   * @LevelAPI Provisional
62   *
63   * @anchor GetEditedDocumentRESTService
64   */
65  
66  @Path("/presentation/document/edit/")
67  public class GetEditedDocumentRESTService implements ResourceContainer {
68  
69    /** The Constant LAST_MODIFIED_PROPERTY. */
70    private static final String LAST_MODIFIED_PROPERTY = "Last-Modified";
71  
72    /** The Constant IF_MODIFIED_SINCE_DATE_FORMAT. */
73    private static final String IF_MODIFIED_SINCE_DATE_FORMAT = "EEE, dd MMM yyyy HH:mm:ss z";
74  
75    private RepositoryService   repositoryService;
76  
77    private TemplateService     templateService;
78  
79    private NewFolksonomyService   newFolksonomyService;
80  
81    private ManageDriveService   manageDriveService;
82  
83    private static final String DATE_MODIFIED   = "exo:dateModified";
84  
85    private static final String JCR_PRIMARYTYPE = "jcr:primaryType";
86  
87    private static final String NT_BASE         = "nt:base";
88  
89    private static final String EXO_OWNER       = "exo:owner";
90  
91    private static final int    NO_PER_PAGE     = 5;
92  
93    private static final String QUERY_STATEMENT = "SELECT * FROM $0 WHERE $1 ORDER BY $2 DESC";
94  
95    private static final String GADGET          = "gadgets";
96  
97    private boolean             show_gadget     = false;
98  
99    private static final Log LOG = ExoLogger.getLogger(GetEditedDocumentRESTService.class.getName());
100 
101 
102   public GetEditedDocumentRESTService(RepositoryService repositoryService,
103       TemplateService templateService, NewFolksonomyService newFolksonomyService, ManageDriveService manageDriveService) {
104     this.repositoryService = repositoryService;
105     this.templateService = templateService;
106     this.newFolksonomyService = newFolksonomyService;
107     this.manageDriveService = manageDriveService;
108   }
109 
110   /**
111    * Returns the latest edited documents.
112    * 
113    * @param repository The repository name.
114    * @param showItems Returns the number of items in each page.
115    * @param showGadgetWs Shows the gadget workspace or not.
116    * @return Response inputstream.
117    * @throws Exception
118    * 
119    * @anchor GetEditedDocumentRESTService.getLastEditedDoc
120    */
121   @Path("/{repository}/")
122   @GET
123   public Response getLastEditedDoc(@PathParam("repository") String repository,
124       @QueryParam("showItems") String showItems, @QueryParam("showGadgetWs") String showGadgetWs) throws Exception {
125     List<Node> lstLastEditedNode = getLastEditedNode(showItems, showGadgetWs);
126     List<DocumentNode> lstDocNode = getDocumentData(lstLastEditedNode);
127     ListEditDocumentNode listEditDocumentNode = new ListEditDocumentNode();
128     listEditDocumentNode.setLstDocNode(lstDocNode);
129 
130     DateFormat dateFormat = new SimpleDateFormat(IF_MODIFIED_SINCE_DATE_FORMAT);
131     return Response.ok(listEditDocumentNode, new MediaType("application", "json"))
132                    .header(LAST_MODIFIED_PROPERTY, dateFormat.format(new Date()))
133                    .build();
134   }
135 
136   private List<Node> getLastEditedNode(String noOfItem, String showGadgetWs) throws Exception{
137     if (showGadgetWs != null && showGadgetWs.length() > 0) {
138       show_gadget = Boolean.parseBoolean(showGadgetWs);
139     }
140     ArrayList<Node>  lstNode = new ArrayList<Node>();
141     StringBuffer bf = new StringBuffer(1024);
142     List<String> lstNodeType = templateService.getDocumentTemplates();
143     if (lstNodeType != null) {
144       for (String nodeType : lstNodeType) {
145         bf.append("(").append(JCR_PRIMARYTYPE).append("=").append("'").append(nodeType).append("'")
146             .append(")").append(" OR ");
147       }
148     }
149 
150     if (bf.length() == 1) return null;
151     bf.delete(bf.lastIndexOf("OR") - 1, bf.length());
152     if (noOfItem == null || noOfItem.trim().length() == 0) noOfItem = String.valueOf(NO_PER_PAGE);
153     String queryStatement = StringUtils.replace(QUERY_STATEMENT, "$0", NT_BASE);
154     queryStatement = StringUtils.replace(queryStatement, "$1", bf.toString());
155     queryStatement = StringUtils.replace(queryStatement, "$2", DATE_MODIFIED);
156     ManageableRepository manageableRepository = repositoryService.getCurrentRepository();
157     try {
158       String[] workspaces = manageableRepository.getWorkspaceNames();
159       List<String> lstWorkspace = new ArrayList<String>();
160       //Arrays.asList() return fixed size list;
161       lstWorkspace.addAll(Arrays.asList(workspaces));
162       if (!show_gadget && lstWorkspace.contains(GADGET)) {
163         lstWorkspace.remove(GADGET);
164       }
165       SessionProvider provider = WCMCoreUtils.createAnonimProvider();
166       QueryImpl query = null;
167       Session session = null;
168       QueryResult queryResult = null;
169       QueryManager queryManager = null;
170       for (String workspace : lstWorkspace) {
171         session = provider.getSession(workspace, manageableRepository);
172         queryManager = session.getWorkspace().getQueryManager();
173         query = (QueryImpl) queryManager.createQuery(queryStatement, Query.SQL);
174         query.setLimit(Integer.parseInt(noOfItem));
175         query.setOffset(0);
176         queryResult = query.execute();
177         puttoList(lstNode, queryResult.getNodes());
178         session.logout();
179       }
180     } catch (RepositoryException e) {
181       if (LOG.isErrorEnabled()) {
182         LOG.error("Exception when execute SQL " + queryStatement, e);
183       }
184     }
185     return lstNode;
186   }
187 
188   private void puttoList(List<Node> lstNode, NodeIterator nodeIter) {
189     if (nodeIter != null) {
190       while (nodeIter.hasNext()) {
191         lstNode.add(nodeIter.nextNode());
192       }
193     }
194   }
195 
196   private List<DocumentNode> getDocumentData(List<Node> lstNode) throws Exception {
197     return getDocumentData(lstNode, String.valueOf(NO_PER_PAGE));
198   }
199 
200   private String getDateFormat(Calendar date) {
201     return String.valueOf(date.getTimeInMillis());
202   }
203 
204   private List<DocumentNode> getDocumentData(List<Node> lstNode, String noOfItem) throws Exception {
205     if (lstNode == null || lstNode.size() == 0) return null;
206     List<DocumentNode> lstDocNode = new ArrayList<DocumentNode>();
207     DocumentNode docNode = null;
208     StringBuilder tags = null;
209 
210     Collections.sort(lstNode, new PropertyValueComparator(DATE_MODIFIED, PropertyValueComparator.DESCENDING_ORDER));
211     ManageableRepository manageableRepository = repositoryService.getCurrentRepository();
212     List<DriveData> lstDrive = manageDriveService.getAllDrives();
213     for (Node node : lstNode) {
214       docNode = new DocumentNode();
215       docNode.setName(node.getName());
216       docNode.setPath(node.getPath());
217       docNode.setLastAuthor(node.getProperty(EXO_OWNER).getString());
218       docNode.setLstAuthor(node.getProperty(EXO_OWNER).getString());
219       docNode.setDateEdited(getDateFormat(node.getProperty(DATE_MODIFIED).getDate()));
220       tags = new StringBuilder(1024);
221 
222       List<Node> tagList = newFolksonomyService.getLinkedTagsOfDocumentByScope(NewFolksonomyService.PUBLIC,
223                                                                                "",
224                                                                                node,
225                                                                                manageableRepository.getConfiguration()
226                                                                                                    .getDefaultWorkspaceName());
227       for(Node tag : tagList) {
228         tags.append(tag.getName()).append(", ");
229       }
230 
231       if (tags.lastIndexOf(",") > 0) {
232         tags.delete(tags.lastIndexOf(","), tags.length());
233       }
234 
235       docNode.setTags(tags.toString());
236       docNode.setDriveName(getDriveName(lstDrive, node));
237       if (lstDocNode.size() < Integer.parseInt(noOfItem))  lstDocNode.add(docNode);
238     }
239     return lstDocNode;
240   }
241 
242   private String getDriveName(List<DriveData> lstDrive, Node node) throws RepositoryException{
243     String driveName = "";
244     for (DriveData drive : lstDrive) {
245       if (node.getSession().getWorkspace().getName().equals(drive.getWorkspace())
246           && node.getPath().contains(drive.getHomePath()) && drive.getHomePath().equals("/")) {
247         driveName = drive.getName();
248         break;
249       }
250     }
251     return driveName;
252   }
253 
254   public class DocumentNode {
255 
256     private String nodeName_;
257 
258     private String nodePath_;
259 
260     private String driveName_;
261 
262     private String   dateEdited_;
263 
264     private String tags;
265 
266     private String   lastAuthor;
267 
268     private String lstAuthor;
269 
270     public String getTags() {
271       return tags;
272     }
273 
274     public void setTags(String tags) {
275       this.tags = tags;
276     }
277 
278     public String getLastAuthor() {
279       return lastAuthor;
280     }
281 
282     public void setLastAuthor(String lastAuthor) {
283       this.lastAuthor = lastAuthor;
284     }
285 
286     public String getLstAuthor() {
287       return lstAuthor;
288     }
289 
290     public void setLstAuthor(String lstAuthor) {
291       this.lstAuthor = lstAuthor;
292     }
293 
294     public void setName(String nodeName) {
295       nodeName_ = nodeName;
296     }
297 
298     public String getName() {
299       return nodeName_;
300     }
301 
302     public void setPath(String nodePath) {
303       nodePath_ = nodePath;
304     }
305 
306     public String getPath() {
307       return nodePath_;
308     }
309 
310     public void setDriveName(String driveName) {
311       driveName_ = driveName;
312     }
313 
314     public String getDriveName() {
315       return driveName_;
316     }
317 
318     public String getDateEdited() {
319       return dateEdited_;
320     }
321 
322     public void setDateEdited(String dateEdited_) {
323       this.dateEdited_ = dateEdited_;
324     }
325   }
326 
327   public class ListEditDocumentNode {
328 
329     private List<DocumentNode> lstDocNode;
330 
331     public List<DocumentNode> getLstDocNode() {
332       return lstDocNode;
333     }
334 
335     public void setLstDocNode(List<DocumentNode> lstDocNode) {
336       this.lstDocNode = lstDocNode;
337     }
338   }
339 
340 }