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.ecm.webui.presentation;
18  
19  import com.google.common.collect.Lists;
20  import org.exoplatform.container.xml.PortalContainerInfo;
21  import org.exoplatform.download.DownloadService;
22  import org.exoplatform.download.InputStreamDownloadResource;
23  import org.exoplatform.ecm.webui.utils.Utils;
24  import org.exoplatform.portal.webui.container.UIContainer;
25  import org.exoplatform.services.cms.comments.CommentsService;
26  import org.exoplatform.services.cms.folksonomy.NewFolksonomyService;
27  import org.exoplatform.services.cms.i18n.MultiLanguageService;
28  import org.exoplatform.services.cms.taxonomy.TaxonomyService;
29  import org.exoplatform.services.cms.templates.TemplateService;
30  import org.exoplatform.services.cms.voting.VotingService;
31  import org.exoplatform.services.jcr.core.ManageableRepository;
32  import org.exoplatform.services.jcr.ext.common.SessionProvider;
33  import org.exoplatform.services.log.ExoLogger;
34  import org.exoplatform.services.log.Log;
35  import org.exoplatform.services.wcm.utils.WCMCoreUtils;
36  import org.exoplatform.web.application.Parameter;
37  import org.exoplatform.webui.application.WebuiRequestContext;
38  import org.exoplatform.webui.application.portlet.PortletRequestContext;
39  import org.exoplatform.webui.core.UIPopupContainer;
40  import org.exoplatform.webui.core.lifecycle.WebuiBindingContext;
41  import org.exoplatform.webui.event.Event;
42  import org.exoplatform.webui.event.EventListener;
43  
44  import javax.jcr.*;
45  import java.io.InputStream;
46  import java.util.ArrayList;
47  import java.util.Date;
48  import java.util.List;
49  
50  /*
51   * Created by The eXo Platform SAS
52   * @author : Hoa.Pham
53   *          hoa.pham@exoplatform.com
54   * Jun 23, 2008
55   */
56  /**
57   * The Class UIBaseNodePresentation should implement some common method in
58   * NodePresentation like getIcons,getWebDavLink....
59   */
60  public abstract class UIBaseNodePresentation extends UIContainer implements NodePresentation {
61  
62    /** The language_. */
63    private String language_ ;
64    private boolean enableVote;
65    private boolean enableComment;
66    private String mediaState = MEDIA_STATE_NONE;
67    private static final Log LOG  = ExoLogger.getLogger(UIBaseNodePresentation.class.getName());
68  
69    /* (non-Javadoc)
70     * @see org.exoplatform.ecm.webui.presentation.NodePresentation#getNode()
71     */
72    public abstract Node getNode() throws Exception ;
73  
74    /* (non-Javadoc)
75     * @see org.exoplatform.ecm.webui.presentation.NodePresentation#getTemplatePath()
76     */
77    public abstract String getTemplatePath() throws Exception ;
78  
79    /* (non-Javadoc)
80     * @see org.exoplatform.ecm.webui.presentation.NodePresentation#getOriginalNode()
81     */
82    public abstract Node getOriginalNode() throws Exception ;
83  
84    /**
85     * Gets the repository name.
86     *
87     * @return the repository name
88     *
89     * @throws Exception the exception
90     */
91    public String getRepositoryName() throws Exception {
92      return WCMCoreUtils.getRepository().getConfiguration().getName();
93    }
94  
95    /* (non-Javadoc)
96     * @see org.exoplatform.ecm.webui.presentation.NodePresentation#encodeHTML(java.lang.String)
97     */
98    public String encodeHTML(String text) throws Exception { return Utils.encodeHTML(text) ; }
99  
100   /* (non-Javadoc)
101    * @see org.exoplatform.ecm.webui.presentation.NodePresentation#getAttachments()
102    */
103   public List<Node> getAttachments() throws Exception {
104     List<Node> attachments = new ArrayList<Node>() ;
105     NodeIterator childrenIterator = getNode().getNodes();;
106     TemplateService templateService = getApplicationComponent(TemplateService.class) ;
107     while (childrenIterator.hasNext()) {
108       Node childNode = childrenIterator.nextNode();
109       String nodeType = childNode.getPrimaryNodeType().getName();
110       List<String> listCanCreateNodeType =
111         Utils.getListAllowedFileType(getNode(), templateService) ;
112       if (listCanCreateNodeType.contains(nodeType)) attachments.add(childNode);
113     }
114     return attachments;
115   }
116 
117   public String getViewableLink(Node attNode, Parameter[] params) throws Exception {
118     return "";
119   }
120 
121   /* (non-Javadoc)
122    * @see org.exoplatform.ecm.webui.presentation.NodePresentation#getComments()
123    */
124   public List<Node> getComments() throws Exception {
125     return getApplicationComponent(CommentsService.class).getComments(getOriginalNode(), getLanguage()) ;
126   }
127 
128   public List<Node> getSortedComments() throws Exception {
129     return Lists.reverse(this.getComments());
130   }
131 
132   /* (non-Javadoc)
133    * @see org.exoplatform.ecm.webui.presentation.NodePresentation#getComponentInstanceOfType(java.lang.String)
134    */
135   public Object getComponentInstanceOfType(String className) {
136     Object service = null;
137     try {
138       ClassLoader loader =  Thread.currentThread().getContextClassLoader();
139       Class object = loader.loadClass(className);
140       service = getApplicationComponent(object);
141     } catch (ClassNotFoundException ex) {
142       if (LOG.isErrorEnabled()) {
143         LOG.error("Unexpected error", ex);
144       }
145     }
146     return service;
147   }
148 
149   /* (non-Javadoc)
150    * @see org.exoplatform.ecm.webui.presentation.NodePresentation#getDownloadLink(javax.jcr.Node)
151    */
152   public String getDownloadLink(Node node) throws Exception {
153     return org.exoplatform.wcm.webui.Utils.getDownloadLink(node);
154   }
155 
156   /* (non-Javadoc)
157    * @see org.exoplatform.ecm.webui.presentation.NodePresentation#getIcons(javax.jcr.Node, java.lang.String)
158    */
159   public String getIcons(Node node, String size) throws Exception { return Utils.getNodeTypeIcon(node, size) ; }
160 
161   /* (non-Javadoc)
162    * @see org.exoplatform.ecm.webui.presentation.NodePresentation#getImage(javax.jcr.Node)
163    */
164   public String getImage(Node node) throws Exception {
165     DownloadService dservice = getApplicationComponent(DownloadService.class) ;
166     InputStreamDownloadResource dresource ;
167     Node imageNode = node.getNode(Utils.EXO_IMAGE) ;
168     InputStream input = imageNode.getProperty(Utils.JCR_DATA).getStream() ;
169     dresource = new InputStreamDownloadResource(input, "image") ;
170     dresource.setDownloadName(node.getName()) ;
171     return dservice.getDownloadLink(dservice.addDownloadResource(dresource)) ;
172   }
173 
174   /* (non-Javadoc)
175    * @see org.exoplatform.ecm.webui.presentation.NodePresentation#getLanguage()
176    */
177   public String getLanguage() { return language_ ; }
178 
179   /* (non-Javadoc)
180    * @see org.exoplatform.ecm.webui.presentation.NodePresentation#setLanguage(java.lang.String)
181    */
182   public void setLanguage(String language) { language_ = language ; }
183 
184   /* (non-Javadoc)
185    * @see org.exoplatform.ecm.webui.presentation.NodePresentation#getPortalName()
186    */
187   public String getPortalName() {
188     PortalContainerInfo containerInfo = WCMCoreUtils.getService(PortalContainerInfo.class);
189     return containerInfo.getContainerName();
190   }
191 
192   /* (non-Javadoc)
193    * @see org.exoplatform.ecm.webui.presentation.NodePresentation#getRelations()
194    */
195   public List<Node> getRelations() throws Exception {
196     List<Node> relations = new ArrayList<Node>() ;
197     if (getNode().hasProperty(Utils.EXO_RELATION)) {
198       Value[] vals = getNode().getProperty(Utils.EXO_RELATION).getValues();
199       for (int i = 0; i < vals.length; i++) {
200         String uuid = vals[i].getString();
201         Node node = getNodeByUUID(uuid);
202         relations.add(node);
203       }
204     }
205     return relations;
206   }
207 
208   /* (non-Javadoc)
209    * @see org.exoplatform.ecm.webui.presentation.NodePresentation#getRepository()
210    */
211   public String getRepository() throws Exception {
212     return ((ManageableRepository)getNode().getSession().getRepository()).getConfiguration().getName() ;
213   }
214 
215   /* (non-Javadoc)
216    * @see org.exoplatform.ecm.webui.presentation.NodePresentation#getRssLink()
217    */
218   public String getRssLink() { return null ; }
219 
220   /* (non-Javadoc)
221    * @see org.exoplatform.ecm.webui.presentation.NodePresentation#isRssLink()
222    */
223   public boolean isRssLink() { return false ; }
224   
225   /**
226    * Checks if allow render fast publish link for the inline editting
227    *
228    * @return true, if need to render fast publish link
229    */
230   public boolean isFastPublishLink() { return false ; }
231 
232   /* (non-Javadoc)
233    * @see org.exoplatform.ecm.webui.presentation.NodePresentation#getSupportedLocalise()
234    */
235   public List getSupportedLocalise() throws Exception {
236     MultiLanguageService multiLanguageService = getApplicationComponent(MultiLanguageService.class) ;
237     return multiLanguageService.getSupportedLanguages(getNode()) ;
238   }
239 
240   /* (non-Javadoc)
241    * @see org.exoplatform.ecm.webui.presentation.NodePresentation#getViewTemplate(java.lang.String, java.lang.String)
242    */
243   public String getViewTemplate(String nodeTypeName, String templateName) throws Exception {
244     TemplateService tempServ = getApplicationComponent(TemplateService.class) ;
245     return tempServ.getTemplatePath(false, nodeTypeName, templateName) ;
246   }
247 
248   /* (non-Javadoc)
249    * @see org.exoplatform.ecm.webui.presentation.NodePresentation#getWebDAVServerPrefix()
250    */
251   public String getWebDAVServerPrefix() throws Exception {
252     PortletRequestContext portletRequestContext = PortletRequestContext.getCurrentInstance() ;
253     String prefixWebDAV = portletRequestContext.getRequest().getScheme() + "://" +
254     portletRequestContext.getRequest().getServerName() + ":" +
255     String.format("%s",portletRequestContext.getRequest().getServerPort()) ;
256     return prefixWebDAV ;
257   }
258 
259   /* (non-Javadoc)
260    * @see org.exoplatform.ecm.webui.presentation.NodePresentation#getWorkspaceName()
261    */
262   public String getWorkspaceName() throws Exception {
263     return getNode().getSession().getWorkspace().getName();
264   }
265 
266   /**
267    * Gets the node by uuid.
268    *
269    * @param uuid the uuid
270    *
271    * @return the node by uuid
272    */
273   public Node getNodeByUUID(String uuid) {
274     ManageableRepository manageRepo = WCMCoreUtils.getRepository();
275     String[] workspaces = manageRepo.getWorkspaceNames() ;
276     //TODO: SystemProvider or SessionProvider
277     SessionProvider provider = WCMCoreUtils.getSystemSessionProvider();
278     for(String ws : workspaces) {
279       try {
280         return provider.getSession(ws, manageRepo).getNodeByUUID(uuid) ;
281       } catch (ItemNotFoundException e) {
282         continue;
283       } catch (RepositoryException e) {
284         continue;
285       }
286     }
287     return null;
288   }
289 
290   /**
291    * Retrieve all categories of a node.
292    *
293    * @param node the node
294    *
295    * @return the categories
296    *
297    * @throws Exception the exception
298    */
299   public List<Node> getCategories(Node node) throws Exception {
300     TaxonomyService taxonomyService = getApplicationComponent(TaxonomyService.class);
301     return taxonomyService.getCategories(node,getRepositoryName());
302   }
303 
304   /**
305    * Retrieve all tags of a node.
306    *
307    * @param node the node
308    *
309    * @return the tags
310    *
311    * @throws Exception the exception
312    */
313   public List<Node> getTags(Node node) throws Exception {
314     NewFolksonomyService folksonomyService = getApplicationComponent(NewFolksonomyService.class);
315     return folksonomyService.getLinkedTagsOfDocumentByScope(NewFolksonomyService.PRIVATE,
316                                                             getStrValue(Utils.PRIVATE, node),
317                                                             node,
318                                                             getWorkspaceName());
319   }
320 
321   /**
322    * Retrieve the voting rate.
323    *
324    * @param node the node
325    *
326    * @return the votes
327    *
328    * @throws Exception the exception
329    */
330   public long getVotingRate(Node node) throws Exception {
331     VotingService votingService = getApplicationComponent(VotingService.class);
332     return votingService.getVoteTotal(node);
333   }
334 
335   /**
336    * Retrieve the image in property value.
337    *
338    * @param node the node
339    * @param propertyName the property name
340    *
341    * @return the image in property
342    *
343    * @throws Exception the exception
344    */
345   public String getImageURIInProperty(Node node, String propertyName) throws Exception {
346     try {
347       InputStream input = node.getProperty(propertyName).getStream() ;
348       InputStreamDownloadResource dresource = new InputStreamDownloadResource(input, "image") ;
349       dresource.setDownloadName(node.getName()) ;
350       DownloadService dservice = getApplicationComponent(DownloadService.class) ;
351       return dservice.getDownloadLink(dservice.addDownloadResource(dresource)) ;
352     } catch (Exception e) {
353       return null;
354     }
355   }
356 
357   /**
358    * Retrieve the portlet preference value.
359    *
360    * @param preferenceName the preference name
361    *
362    * @return the portlet preference value
363    */
364   public String getPortletPreferenceValue(String preferenceName) {
365     WebuiRequestContext requestContext = WebuiRequestContext.getCurrentInstance();
366     if(requestContext instanceof PortletRequestContext) {
367       PortletRequestContext context = PortletRequestContext.class.cast(requestContext);
368       return context.getRequest().getPreferences().getValue(preferenceName,null);
369     }
370     return null;
371   }
372 
373   /**
374    * Retrieve the portlet preference values.
375    *
376    * @param preferenceName the preference name
377    *
378    * @return the portlet preference values
379    */
380   public String[] getPortletPreferenceValues(String preferenceName) {
381     WebuiRequestContext requestContext = WebuiRequestContext.getCurrentInstance();
382     if(requestContext instanceof PortletRequestContext) {
383       PortletRequestContext context = PortletRequestContext.class.cast(requestContext);
384       return context.getRequest().getPreferences().getValues(preferenceName,null);
385     }
386     return null;
387   }
388 
389   public String getTemplateSkin(String nodeTypeName, String skinName) throws Exception {
390     TemplateService tempServ = getApplicationComponent(TemplateService.class) ;
391     return tempServ.getSkinPath(nodeTypeName, skinName, getLanguage()) ;
392   }
393 
394   private String getStrValue(String scope, Node node) throws Exception {
395     StringBuilder ret = new StringBuilder();
396     if (Utils.PRIVATE.equals(scope))
397       ret.append(node.getSession().getUserID());
398     else if (Utils.GROUP.equals(scope)) {
399       for (String group : Utils.getGroups())
400         ret.append(group).append(';');
401       ret.deleteCharAt(ret.length() - 1);
402     }
403 
404     return ret.toString();
405   }
406 
407   public boolean isEnableComment() {
408     return enableComment;
409   }
410 
411   public boolean isEnableVote() {
412    return enableVote;
413   }
414 
415   public void setEnableComment(boolean value) {
416     enableComment = value;
417   }
418 
419   public void setEnableVote(boolean value) {
420     enableVote = value;
421   }
422 
423   /**
424   * @param orgNode         Processed node
425   * @param propertyName    which property used for editing
426   * @param inputType       input type for editing: TEXT, TEXTAREA, WYSIWYG
427   * @param cssClass        class name for CSS, should implement: cssClass, [cssClass]Title
428   *                        Edit[cssClass] as relative css
429   *                        Should create the function: InlineEditor.presentationRequestChange[cssClass]
430   *                        to request the rest-service
431   * @param isGenericProperty  set as true to use generic javascript function, other wise, must create
432   *                        the correctspond function InlineEditor.presentationRequestChange[cssClass]
433   * @param arguments       Extra parameter for Input component (toolbar, width, height,.. for CKEditor/TextArea)
434   * @return                String that can be put on groovy template
435   * @throws                Exception
436   */
437   public String getInlineEditingField(Node orgNode, String propertyName, String defaultValue, String inputType,
438       String idGenerator, String cssClass, boolean isGenericProperty, String... arguments) throws Exception {
439     return org.exoplatform.ecm.webui.utils.Utils.getInlineEditingField(orgNode, propertyName, defaultValue,
440                                                       inputType, idGenerator, cssClass, isGenericProperty, arguments);
441   }
442   public String getInlineEditingField(Node orgNode, String propertyName) throws Exception {
443     return org.exoplatform.ecm.webui.utils.Utils.getInlineEditingField(orgNode, propertyName);
444   }
445 
446   public String getMediaState() { return mediaState; }
447 
448   public void switchMediaState() {
449     mediaState = MEDIA_STATE_DISPLAY.equals(mediaState) ? MEDIA_STATE_NONE : MEDIA_STATE_DISPLAY;
450   }
451 
452   public boolean isDisplayAlternativeText() {
453     return false;
454   }
455 
456   @Override
457   public boolean playAudioDescription() {
458     return false;
459   }
460 
461   @Override
462   public boolean switchBackAudioDescription() {
463     return false;
464   }
465   
466   @Override
467   public String getActionOpenDocInDesktop() throws Exception {
468     return this.event("OpenDocInDesktop");
469   }
470   
471   @Override
472   public UIPopupContainer getPopupContainer() throws Exception {
473     return null;
474   }
475   
476   static public class OpenDocInDesktopActionListener extends EventListener<UIBaseNodePresentation> {
477     public void execute(Event<UIBaseNodePresentation> event) throws Exception {
478       UIBaseNodePresentation uicomp = event.getSource() ;
479       Node node = uicomp.getNode();
480       Utils.openDocumentInDesktop(node, uicomp.getPopupContainer(), event);
481     }
482   }
483 
484   public String getPostedTimeString(WebuiBindingContext resourceBundle, Date postedTime) throws Exception {
485     long time = (new Date().getTime() - postedTime.getTime()) / 1000;
486     long value;
487     if (time < 60) {
488       return resourceBundle.appRes("Comment.view.label.Less_Than_A_Minute");
489     } else {
490       if (time < 120) {
491         return resourceBundle.appRes("Comment.view.label.About_A_Minute");
492       } else {
493         if (time < 3600) {
494           value = Math.round(time / 60);
495           return resourceBundle.appRes("Comment.view.label.About_x_Minutes").replaceFirst("\\{0\\}", String.valueOf(value));
496         } else {
497           if (time < 7200) {
498             return resourceBundle.appRes("Comment.view.label.About_An_Hour");
499           } else {
500             if (time < 86400) {
501               value = Math.round(time / 3600);
502               return resourceBundle.appRes("Comment.view.label.About_x_Hours").replaceFirst("\\{0\\}", String.valueOf(value));
503             } else {
504               if (time < 172800) {
505                 return resourceBundle.appRes("Comment.view.label.About_A_Day");
506               } else {
507                 if (time < 2592000) {
508                   value = Math.round(time / 86400);
509                   return resourceBundle.appRes("Comment.view.label.About_x_Days").replaceFirst("\\{0\\}", String.valueOf(value));
510                 } else {
511                   if (time < 5184000) {
512                     return resourceBundle.appRes("Comment.view.label.About_A_Month");
513                   } else {
514                     value = Math.round(time / 2592000);
515                     return resourceBundle.appRes("Comment.view.label.About_x_Months")
516                         .replaceFirst("\\{0\\}", String.valueOf(value));
517                   }
518                 }
519               }
520             }
521           }
522         }
523       }
524     }
525   }
526 
527 }