View Javadoc
1   /*
2    * Copyright (C) 2003-2007 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.component.explorer;
18  
19  import org.apache.commons.lang.StringUtils;
20  import org.exoplatform.commons.utils.LazyPageList;
21  import org.exoplatform.commons.utils.ListAccess;
22  import org.exoplatform.commons.utils.ListAccessImpl;
23  import org.exoplatform.commons.utils.PageList;
24  import org.exoplatform.container.component.ComponentPlugin;
25  import org.exoplatform.download.DownloadService;
26  import org.exoplatform.download.InputStreamDownloadResource;
27  import org.exoplatform.ecm.jcr.model.Preference;
28  import org.exoplatform.ecm.utils.lock.LockUtil;
29  import org.exoplatform.ecm.webui.component.explorer.control.UIActionBar;
30  import org.exoplatform.ecm.webui.component.explorer.sidebar.UITreeExplorer;
31  import org.exoplatform.ecm.webui.component.explorer.sidebar.UITreeNodePageIterator;
32  import org.exoplatform.ecm.webui.presentation.AbstractActionComponent;
33  import org.exoplatform.ecm.webui.presentation.NodePresentation;
34  import org.exoplatform.ecm.webui.presentation.UIBaseNodePresentation;
35  import org.exoplatform.ecm.webui.presentation.removeattach.RemoveAttachmentComponent;
36  import org.exoplatform.ecm.webui.presentation.removecomment.RemoveCommentComponent;
37  import org.exoplatform.ecm.webui.utils.JCRExceptionManager;
38  import org.exoplatform.ecm.webui.utils.PermissionUtil;
39  import org.exoplatform.ecm.webui.utils.Utils;
40  import org.exoplatform.portal.webui.util.Util;
41  import org.exoplatform.portal.webui.workspace.UIPortalApplication;
42  import org.exoplatform.resolver.ResourceResolver;
43  import org.exoplatform.services.cms.clipboard.ClipboardService;
44  import org.exoplatform.services.cms.comments.CommentsService;
45  import org.exoplatform.services.cms.documents.AutoVersionService;
46  import org.exoplatform.services.cms.documents.DocumentTypeService;
47  import org.exoplatform.services.cms.documents.FavoriteService;
48  import org.exoplatform.services.cms.drives.DriveData;
49  import org.exoplatform.services.cms.drives.ManageDriveService;
50  import org.exoplatform.services.cms.i18n.MultiLanguageService;
51  import org.exoplatform.services.cms.link.*;
52  import org.exoplatform.services.cms.templates.TemplateService;
53  import org.exoplatform.services.cms.thumbnail.ThumbnailPlugin;
54  import org.exoplatform.services.cms.thumbnail.ThumbnailService;
55  import org.exoplatform.services.cms.timeline.TimelineService;
56  import org.exoplatform.services.cms.voting.VotingService;
57  import org.exoplatform.services.jcr.RepositoryService;
58  import org.exoplatform.services.jcr.core.ExtendedNode;
59  import org.exoplatform.services.jcr.core.ManageableRepository;
60  import org.exoplatform.services.jcr.ext.audit.AuditHistory;
61  import org.exoplatform.services.jcr.ext.audit.AuditService;
62  import org.exoplatform.services.jcr.ext.common.SessionProvider;
63  import org.exoplatform.services.log.ExoLogger;
64  import org.exoplatform.services.log.Log;
65  import org.exoplatform.services.security.ConversationState;
66  import org.exoplatform.services.security.IdentityConstants;
67  import org.exoplatform.services.wcm.core.NodeLocation;
68  import org.exoplatform.services.wcm.core.NodetypeConstant;
69  import org.exoplatform.services.wcm.utils.WCMCoreUtils;
70  import org.exoplatform.web.application.ApplicationMessage;
71  import org.exoplatform.web.application.Parameter;
72  import org.exoplatform.web.application.RequireJS;
73  import org.exoplatform.webui.application.WebuiRequestContext;
74  import org.exoplatform.webui.application.portlet.PortletRequestContext;
75  import org.exoplatform.webui.config.annotation.ComponentConfig;
76  import org.exoplatform.webui.config.annotation.EventConfig;
77  import org.exoplatform.webui.core.*;
78  import org.exoplatform.webui.event.Event;
79  import org.exoplatform.webui.event.EventListener;
80  import org.exoplatform.webui.exception.MessageException;
81  import org.exoplatform.webui.ext.UIExtensionManager;
82  
83  import javax.imageio.ImageIO;
84  import javax.jcr.*;
85  import javax.jcr.lock.LockException;
86  import javax.jcr.nodetype.ConstraintViolationException;
87  import javax.jcr.nodetype.NodeDefinition;
88  import javax.jcr.nodetype.NodeType;
89  import javax.jcr.query.Query;
90  import javax.jcr.query.QueryManager;
91  import javax.jcr.query.QueryResult;
92  import javax.jcr.version.VersionException;
93  import java.awt.*;
94  import java.io.InputStream;
95  import java.text.DateFormat;
96  import java.text.SimpleDateFormat;
97  import java.util.*;
98  import java.util.List;
99  import java.util.regex.Matcher;
100 
101 /**
102  * Created by The eXo Platform SARL
103  * Author : Dang Van Minh
104  *          minh.dang@exoplatform.com
105  * Sep 3, 2006
106  * 10:07:15 AM
107  * Editor : Pham Tuan
108  *          phamtuanchip@gmail.com
109  * Nov 10, 2006
110  */
111 @ComponentConfig(
112     events = {
113         @EventConfig(listeners = UIDocumentInfo.ChangeNodeActionListener.class),
114         @EventConfig(listeners = UIDocumentInfo.ViewNodeActionListener.class),
115         @EventConfig(listeners = UIDocumentInfo.SortActionListener.class),
116         @EventConfig(listeners = UIDocumentInfo.VoteActionListener.class),
117         @EventConfig(listeners = UIDocumentInfo.ChangeLanguageActionListener.class),
118         @EventConfig(listeners = UIDocumentInfo.DownloadActionListener.class),
119         @EventConfig(listeners = UIDocumentInfo.StarClickActionListener.class),
120         @EventConfig(listeners = UIDocumentInfo.ShowPageActionListener.class),
121         @EventConfig(listeners = UIDocumentInfo.SortTimelineASCActionListener.class),
122         @EventConfig(listeners = UIDocumentInfo.SortTimelineDESCActionListener.class),
123         @EventConfig(listeners = UIDocumentInfo.ExpandTimelineCatergoryActionListener.class),
124         @EventConfig(listeners = UIDocumentInfo.CollapseTimelineCatergoryActionListener.class),
125         @EventConfig(listeners = UIDocumentInfo.SwitchToAudioDescriptionActionListener.class),
126         @EventConfig(listeners = UIDocumentInfo.SwitchToOriginalActionListener.class),
127         @EventConfig(listeners = UIBaseNodePresentation.OpenDocInDesktopActionListener.class)
128     }
129 )
130 public class UIDocumentInfo extends UIBaseNodePresentation {
131 
132   final protected static String   NO                                 = "NO";
133 
134   final protected static String   YES                                = "YES";
135 
136   final protected static String   COMMENT_COMPONENT                  = "Comment";
137 
138   final protected static String   Contents_Document_Type             = "Content";
139 
140   final protected static String CATEGORY_ALL                       = "All";
141 
142   final protected static String CATEGORY_TODAY                     = "UIDocumentInfo.label.Today";
143 
144   final protected static String CATEGORY_YESTERDAY                 = "UIDocumentInfo.label.Yesterday";
145 
146   final protected static String CATEGORY_WEEK                      = "UIDocumentInfo.label.EarlierThisWeek";
147 
148   final protected static String CATEGORY_MONTH                     = "UIDocumentInfo.label.EarlierThisMonth";
149 
150   final protected static String CATEGORY_YEAR                      = "UIDocumentInfo.label.EarlierThisYear";
151 
152   final public static String CONTENT_PAGE_ITERATOR_ID           = "ContentPageIterator";
153 
154   final protected static String CONTENT_TODAY_PAGE_ITERATOR_ID     = "ContentTodayPageIterator";
155 
156   final protected static String CONTENT_YESTERDAY_PAGE_ITERATOR_ID = "ContentYesterdayPageIterator";
157 
158   final protected static String CONTENT_WEEK_PAGE_ITERATOR_ID      = "ContentWeekPageIterator";
159 
160   final protected static String CONTENT_MONTH_PAGE_ITERATOR_ID     = "ContentMonthPageIterator";
161 
162   final protected static String CONTENT_YEAR_PAGE_ITERATOR_ID      = "ContentYearPageIterator";
163 
164   protected UIDocumentNodeList    documentNodeList_;
165 
166   private static final Log      LOG                                = ExoLogger.getLogger(UIDocumentInfo.class.getName());
167 
168   private String                typeSort_                          = NodetypeConstant.SORT_BY_NODENAME;
169 
170   private String                sortOrder_                         = Preference.BLUE_DOWN_ARROW;
171 
172   private String                displayCategory_;
173 
174   private int                   itemsPerTimeline;
175 
176   private NodeLocation          currentNode_;
177 
178   private UIPageIterator        pageIterator_;
179 
180   private UIPageIterator        todayPageIterator_;
181 
182   private UIPageIterator        yesterdayPageIterator_;
183 
184   private UIPageIterator        earlierThisWeekPageIterator_;
185 
186   private UIPageIterator        earlierThisMonthPageIterator_;
187 
188   private UIPageIterator        earlierThisYearPageIterator_;
189 
190   private String                timeLineSortByFavourite            = "";
191 
192   private String                timeLineSortByName                 = "";
193 
194   private String                timeLineSortByDate                 = Preference.BLUE_UP_ARROW;
195 
196   private FavoriteService       favoriteService;
197 
198   private DocumentTypeService   documentTypeService;
199 
200   private TemplateService       templateService;
201 
202   //used for timeline view, indicating which type of content is shown(daily, this week, this month, this year)
203   private HashMap<String, String> isExpanded_;
204 
205   //flag indicating if we need to update data for Timeline
206   private boolean updateTimeLineData_ = false;
207 
208   //used in File View, indicating which folders are expanded
209   private Set<String> expandedFolders_;
210 
211   public UIDocumentInfo() throws Exception {
212     pageIterator_ = addChild(UIPageIterator.class, null, CONTENT_PAGE_ITERATOR_ID);
213     documentNodeList_ = addChild(UIDocumentNodeList.class, null, null);
214     documentNodeList_.setShowMoreButton(false);
215     todayPageIterator_ = addChild(UIPageIterator.class, null, CONTENT_TODAY_PAGE_ITERATOR_ID);
216     yesterdayPageIterator_ = addChild(UIPageIterator.class, null, CONTENT_YESTERDAY_PAGE_ITERATOR_ID);
217     earlierThisWeekPageIterator_ = addChild(UIPageIterator.class, null, CONTENT_WEEK_PAGE_ITERATOR_ID);
218     earlierThisMonthPageIterator_ = addChild(UIPageIterator.class, null, CONTENT_MONTH_PAGE_ITERATOR_ID);
219     earlierThisYearPageIterator_ = addChild(UIPageIterator.class, null, CONTENT_YEAR_PAGE_ITERATOR_ID);
220     favoriteService = this.getApplicationComponent(FavoriteService.class);
221     documentTypeService = this.getApplicationComponent(DocumentTypeService.class);
222     templateService = getApplicationComponent(TemplateService.class) ;
223     displayCategory_ = UIDocumentInfo.CATEGORY_ALL;
224     isExpanded_ = new HashMap<String, String>();
225     expandedFolders_ = new HashSet<String>();
226   }
227 
228   /**
229    * checks if the data for Timeline view is needed to update
230    * @throws Exception
231    */
232   public void checkTimelineUpdate() throws Exception {
233     if (this.updateTimeLineData_) {
234        updateNodeLists();
235        this.updateTimeLineData_ = false;
236      }
237    }
238 
239   public String getTimeLineSortByFavourite() { return timeLineSortByFavourite; }
240   public void setTimeLineSortByFavourite(String timeLineSortByFavourite) {
241     this.timeLineSortByFavourite = timeLineSortByFavourite;
242   }
243 
244   public String getTimeLineSortByName() { return timeLineSortByName; }
245   public void setTimeLineSortByName(String timeLineSortByName) {
246     this.timeLineSortByName = timeLineSortByName;
247   }
248 
249   public String getTimeLineSortByDate() { return timeLineSortByDate; }
250   public void setTimeLineSortByDate(String timeLineSortByDate) {
251     this.timeLineSortByDate = timeLineSortByDate;
252   }
253 
254   public void updateNodeLists() throws Exception {
255     TimelineService timelineService = getApplicationComponent(TimelineService.class);
256     itemsPerTimeline = timelineService.getItemPerTimeline();
257 
258     UIJCRExplorer uiExplorer = this.getAncestorOfType(UIJCRExplorer.class);
259     SessionProvider sessionProvider = uiExplorer.getSessionProvider();
260     Session session = uiExplorer.getSession();
261     String workspace = this.getWorkspaceName();
262     String userName = session.getUserID();
263     String nodePath = uiExplorer.getCurrentPath();
264     String tagPath = uiExplorer.getTagPath();
265     boolean isViewTag = uiExplorer.isViewTag();
266     boolean isLimit = false;
267     int nodesPerPage;
268     List<NodeLocation> todayNodes = new ArrayList<NodeLocation>();
269     List<NodeLocation> yesterdayNodes = new ArrayList<NodeLocation>();
270     List<NodeLocation> earlierThisWeekNodes = new ArrayList<NodeLocation>();
271     List<NodeLocation> earlierThisMonthNodes = new ArrayList<NodeLocation>();
272     List<NodeLocation> earlierThisYearNodes = new ArrayList<NodeLocation>();
273     isExpanded_ = new HashMap<String, String>();
274     if (CATEGORY_ALL.equalsIgnoreCase(displayCategory_))  {
275       nodesPerPage = Integer.MAX_VALUE; // always display in one page (no paginator)
276       todayNodes = NodeLocation.getLocationsByNodeList(timelineService.
277                                                        getDocumentsOfToday(nodePath, workspace,
278                                                                            sessionProvider, userName, false, isLimit));
279       if (todayNodes.size() > this.getItemsPerTimeline()) {
280         isExpanded_.put(UIDocumentInfo.CATEGORY_TODAY, YES);
281         todayNodes = todayNodes.subList(0, this.getItemsPerTimeline());
282       } else {
283         isExpanded_.put(UIDocumentInfo.CATEGORY_TODAY, NO);
284       }
285       yesterdayNodes = NodeLocation.getLocationsByNodeList(timelineService.getDocumentsOfYesterday(nodePath,
286                                                                                                    workspace,
287                                                                                                    sessionProvider,
288                                                                                                    userName,
289                                                                                                    false,
290                                                                                                    isLimit));
291       if (yesterdayNodes.size() > this.getItemsPerTimeline()) {
292         isExpanded_.put(UIDocumentInfo.CATEGORY_YESTERDAY, YES);
293         yesterdayNodes = yesterdayNodes.subList(0, this.getItemsPerTimeline());
294       } else {
295         isExpanded_.put(UIDocumentInfo.CATEGORY_YESTERDAY, NO);
296       }
297       earlierThisWeekNodes = NodeLocation.getLocationsByNodeList(timelineService.
298                                                                  getDocumentsOfEarlierThisWeek(nodePath,
299                                                                                                workspace,
300                                                                                                sessionProvider,
301                                                                                                userName,
302                                                                                                false,
303                                                                                                isLimit));
304       if (earlierThisWeekNodes.size() > this.getItemsPerTimeline()) {
305         isExpanded_.put(UIDocumentInfo.CATEGORY_WEEK, YES);
306         earlierThisWeekNodes = earlierThisWeekNodes.subList(0, this.getItemsPerTimeline());
307       } else {
308         isExpanded_.put(UIDocumentInfo.CATEGORY_WEEK, NO);
309       }
310       earlierThisMonthNodes = NodeLocation.getLocationsByNodeList(timelineService.
311                                                                   getDocumentsOfEarlierThisMonth(nodePath,
312                                                                                                  workspace,
313                                                                                                  sessionProvider,
314                                                                                                  userName,
315                                                                                                  false,
316                                                                                                  isLimit));
317       if (earlierThisMonthNodes.size() > this.getItemsPerTimeline()) {
318         isExpanded_.put(UIDocumentInfo.CATEGORY_MONTH, YES);
319         earlierThisMonthNodes = earlierThisMonthNodes.subList(0, this.getItemsPerTimeline());
320       } else {
321         isExpanded_.put(UIDocumentInfo.CATEGORY_MONTH, NO);
322       }
323       earlierThisYearNodes = NodeLocation.getLocationsByNodeList(timelineService.
324                                                                  getDocumentsOfEarlierThisYear(nodePath,
325                                                                                                workspace,
326                                                                                                sessionProvider,
327                                                                                                userName,
328                                                                                                false,
329                                                                                                isLimit));
330       if (earlierThisYearNodes.size() > this.getItemsPerTimeline()) {
331         isExpanded_.put(UIDocumentInfo.CATEGORY_YEAR, YES);
332         earlierThisYearNodes = earlierThisYearNodes.subList(0, this.getItemsPerTimeline());
333       } else {
334         isExpanded_.put(UIDocumentInfo.CATEGORY_YEAR, NO);
335       }
336     } else {
337       nodesPerPage = uiExplorer.getPreference().getNodesPerPage();
338       if (CATEGORY_TODAY.equalsIgnoreCase(displayCategory_)) {
339         todayNodes = NodeLocation.getLocationsByNodeList(timelineService.getDocumentsOfToday(nodePath,
340                                                                                              workspace,
341                                                                                              sessionProvider,
342                                                                                              userName,
343                                                                                              false,
344                                                                                              isLimit));
345       } else if (CATEGORY_YESTERDAY.equalsIgnoreCase(displayCategory_)) {
346         yesterdayNodes = NodeLocation.getLocationsByNodeList(timelineService.getDocumentsOfYesterday(nodePath,
347                                                                                                      workspace,
348                                                                                                      sessionProvider,
349                                                                                                      userName,
350                                                                                                      false,
351                                                                                                      isLimit));
352       } else if (CATEGORY_WEEK.equalsIgnoreCase(displayCategory_)) {
353         earlierThisWeekNodes = NodeLocation.getLocationsByNodeList(timelineService.
354                                                                    getDocumentsOfEarlierThisWeek(nodePath,
355                                                                                                  workspace,
356                                                                                                  sessionProvider,
357                                                                                                  userName,
358                                                                                                  false,
359                                                                                                  isLimit));
360       } else if (CATEGORY_MONTH.equalsIgnoreCase(displayCategory_)) {
361         earlierThisMonthNodes = NodeLocation.getLocationsByNodeList(timelineService.
362                                                                     getDocumentsOfEarlierThisMonth(nodePath,
363                                                                                                    workspace,
364                                                                                                    sessionProvider,
365                                                                                                    userName,
366                                                                                                    false,
367                                                                                                    isLimit));
368       } else if (CATEGORY_YEAR.equalsIgnoreCase(displayCategory_)) {
369         earlierThisYearNodes = NodeLocation.getLocationsByNodeList(timelineService.
370                                                                    getDocumentsOfEarlierThisYear(nodePath,
371                                                                                                  workspace,
372                                                                                                  sessionProvider,
373                                                                                                  userName,
374                                                                                                  false,
375                                                                                                  isLimit));
376       }
377     }
378 
379     if(isViewTag && tagPath != null) {
380       if(todayNodes.size() > 0) todayNodes = filterDocumentsByTag(todayNodes, tagPath);
381       if(yesterdayNodes.size() > 0) yesterdayNodes = filterDocumentsByTag(yesterdayNodes, tagPath);
382       if(earlierThisWeekNodes.size() > 0) earlierThisWeekNodes = filterDocumentsByTag(earlierThisWeekNodes, tagPath);
383       if(earlierThisMonthNodes.size() > 0) earlierThisMonthNodes = filterDocumentsByTag(earlierThisMonthNodes, tagPath);
384       if(earlierThisYearNodes.size() > 0) earlierThisYearNodes = filterDocumentsByTag(earlierThisYearNodes, tagPath);
385     }
386 
387     Collections.sort(todayNodes, new SearchComparator());
388     Collections.sort(yesterdayNodes, new SearchComparator());
389     Collections.sort(earlierThisWeekNodes, new SearchComparator());
390     Collections.sort(earlierThisMonthNodes, new SearchComparator());
391     Collections.sort(earlierThisYearNodes, new SearchComparator());
392 
393     ListAccess<NodeLocation> todayNodesList = new ListAccessImpl<NodeLocation>(NodeLocation.class, todayNodes);
394     todayPageIterator_.setPageList(new LazyPageList<NodeLocation>(todayNodesList, nodesPerPage));
395 
396     ListAccess<NodeLocation> yesterdayNodesList = new ListAccessImpl<NodeLocation>(NodeLocation.class, yesterdayNodes);
397     yesterdayPageIterator_.setPageList(new LazyPageList<NodeLocation>(yesterdayNodesList, nodesPerPage));
398 
399     ListAccess<NodeLocation> earlierThisWeekList = new ListAccessImpl<NodeLocation>(NodeLocation.class, earlierThisWeekNodes);
400     earlierThisWeekPageIterator_.setPageList(new LazyPageList<NodeLocation>(earlierThisWeekList, nodesPerPage));
401 
402     ListAccess<NodeLocation> earlierThisMonthList = new ListAccessImpl<NodeLocation>(NodeLocation.class, earlierThisMonthNodes);
403     earlierThisMonthPageIterator_.setPageList(new LazyPageList<NodeLocation>(earlierThisMonthList, nodesPerPage));
404 
405     ListAccess<NodeLocation> earlierThisYearList = new ListAccessImpl<NodeLocation>(NodeLocation.class, earlierThisYearNodes);
406     earlierThisYearPageIterator_.setPageList(new LazyPageList<NodeLocation>(earlierThisYearList, nodesPerPage));
407   }
408 
409   public List<NodeLocation> filterDocumentsByTag(List<NodeLocation> nodes, String path) throws Exception {
410     List<Node> documents = new ArrayList<Node>();
411     Session session = null;
412     Node node = null;
413     QueryManager queryManager = null;
414     QueryResult queryResult = null;
415     Query query = null;
416     NodeIterator nodeIterator = null;
417     for (int i = 0; i < nodes.size(); i++) {
418       node = NodeLocation.getNodeByLocation(nodes.get(i));
419       if (node.isNodeType(NodetypeConstant.MIX_REFERENCEABLE)) {
420         session = node.getSession();
421         String queryString = "SELECT * FROM exo:symlink where jcr:path like '" + path
422             + "/%' and exo:uuid = '" + node.getUUID() + "' and exo:workspace='"
423             + node.getSession().getWorkspace().getName() + "'";
424         queryManager = session.getWorkspace().getQueryManager();
425         query = queryManager.createQuery(queryString, Query.SQL);
426         queryResult = query.execute();
427         nodeIterator = queryResult.getNodes();
428         if (nodeIterator.getSize() > 0)
429           documents.add(node);
430       }
431     }
432     return NodeLocation.getLocationsByNodeList(documents);
433   }
434 
435   public String getDisplayCategory() {
436     if (displayCategory_ == null || displayCategory_.trim().length() == 0) {
437       return CATEGORY_ALL;
438     }
439     return displayCategory_;
440   }
441 
442   public UIPageIterator getContentPageIterator() {
443     return pageIterator_;
444   }
445 
446   /**
447    * @return the todayPageIterator_
448    */
449   public UIPageIterator getTodayPageIterator() {
450     return todayPageIterator_;
451   }
452 
453   public UIPageIterator getYesterdayPageIterator() {
454     return yesterdayPageIterator_;
455   }
456 
457   public UIPageIterator getWeekPageIterator() {
458     return earlierThisWeekPageIterator_;
459   }
460 
461   public UIPageIterator getMonthPageIterator() {
462     return earlierThisMonthPageIterator_;
463   }
464 
465   public UIPageIterator getYearPageIterator() {
466     return earlierThisYearPageIterator_;
467   }
468 
469   public UIComponent getUIComponent(String mimeType) throws Exception {
470     return Utils.getUIComponent(mimeType, this);
471   }
472 
473   public String getTemplate() {
474     UIJCRExplorer uiExplorer = getAncestorOfType(UIJCRExplorer.class) ;
475     if(uiExplorer.getPreference().isJcrEnable())
476       return uiExplorer.getDocumentInfoTemplate();
477     try {
478       Node node = uiExplorer.getCurrentNode();
479       String template = templateService.getTemplatePath(node,false) ;
480       if(template != null) return template ;
481     } catch(AccessDeniedException ace) {
482       try {
483         uiExplorer.setSelectRootNode() ;
484         Object[] args = { uiExplorer.getCurrentNode().getName() } ;
485         throw new MessageException(new ApplicationMessage("UIDocumentInfo.msg.access-denied", args,
486             ApplicationMessage.WARNING)) ;
487       } catch(Exception exc) {
488         if (LOG.isWarnEnabled()) {
489           LOG.warn(exc.getMessage());
490         }
491       }
492     } catch(Exception e) {
493       return uiExplorer.getDocumentInfoTemplate();
494     }
495     return uiExplorer.getDocumentInfoTemplate();
496   }
497 
498   public ResourceResolver getTemplateResourceResolver(WebuiRequestContext context, String template) {
499     return getAncestorOfType(UIJCRExplorer.class).getJCRTemplateResourceResolver();
500   }
501 
502   public UIRightClickPopupMenu getContextMenu() {
503     return getAncestorOfType(UIWorkingArea.class).getChild(UIRightClickPopupMenu.class) ;
504   }
505 
506   public Node getNodeByUUID(String uuid) {
507     ManageableRepository manageRepo = WCMCoreUtils.getRepository();
508     String[] workspaces = manageRepo.getWorkspaceNames() ;
509     for(String ws : workspaces) {
510       try{
511         return WCMCoreUtils.getSystemSessionProvider().getSession(ws, manageRepo).getNodeByUUID(uuid) ;
512       } catch(Exception e) {
513         continue;
514       }
515     }
516     return null;
517   }
518 
519   public String getCapacityOfFile(Node file) throws Exception {
520     Node contentNode = file.getNode(Utils.JCR_CONTENT);
521     long size = contentNode.getProperty(Utils.JCR_DATA).getLength() ;
522     long capacity = size/1024 ;
523     String strCapacity = Long.toString(capacity) ;
524     if(strCapacity.indexOf(".") > -1) return strCapacity.substring(0, strCapacity.lastIndexOf(".")) ;
525     return strCapacity ;
526   }
527 
528   public List<String> getMultiValues(Node node, String name) throws Exception {
529     return getAncestorOfType(UIJCRExplorer.class).getMultiValues(node, name) ;
530   }
531 
532   public boolean isSystemWorkspace() throws Exception {
533     UIJCRExplorer uiExplorer = getAncestorOfType(UIJCRExplorer.class) ;
534     ManageableRepository manaRepoService =
535       getApplicationComponent(RepositoryService.class).getCurrentRepository();
536     String systemWsName = manaRepoService.getConfiguration().getSystemWorkspaceName() ;
537     if(systemWsName.equals(uiExplorer.getCurrentWorkspace())) return true ;
538     return false ;
539   }
540 
541   public boolean isSupportedThumbnailImage(Node node) throws Exception {
542     if(node.isNodeType(Utils.NT_FILE)) {
543       Node contentNode = node.getNode(Utils.JCR_CONTENT);
544       ThumbnailService thumbnailService = getApplicationComponent(ThumbnailService.class);
545       for(ComponentPlugin plugin : thumbnailService.getComponentPlugins()) {
546         if(plugin instanceof ThumbnailPlugin) {
547           ThumbnailPlugin thumbnailPlugin = (ThumbnailPlugin) plugin;
548           if(thumbnailPlugin.getMimeTypes().contains(
549               contentNode.getProperty(Utils.JCR_MIMETYPE).getString())) {
550             return true;
551           }
552         }
553       }
554       return false;
555     }
556     return false;
557   }
558 
559   public boolean isImageType(Node node) throws Exception {
560     if(node.isNodeType(Utils.NT_FILE)) {
561       Node contentNode = node.getNode(Utils.JCR_CONTENT);
562       if(contentNode.getProperty(Utils.JCR_MIMETYPE).getString().startsWith("image")) return true;
563     }
564     return false;
565   }
566 
567   public String getThumbnailImage(Node node) throws Exception {
568     node = node instanceof NodeLinkAware ? ((NodeLinkAware) node).getTargetNode().getRealNode() : node;
569     return Utils.getThumbnailImage(node, ThumbnailService.MEDIUM_SIZE);
570   }
571 
572   public Node getThumbnailNode(Node node) throws Exception {
573     ThumbnailService thumbnailService = getApplicationComponent(ThumbnailService.class);
574     LinkManager linkManager = this.getApplicationComponent(LinkManager.class);
575     if (!linkManager.isLink(node) || linkManager.isTargetReachable(node))
576       node = node instanceof NodeLinkAware ? ((NodeLinkAware) node).getTargetNode().getRealNode() : node;
577     return thumbnailService.getThumbnailNode(node);
578   }
579 
580   public String getDownloadLink(Node node) throws Exception {
581     return org.exoplatform.wcm.webui.Utils.getDownloadLink(node);
582   }
583 
584   public String getImage(Node node) throws Exception {
585     return getImage(node, Utils.EXO_IMAGE);
586   }
587 
588   public String getImage(Node node, String nodeTypeName) throws Exception {
589     DownloadService dservice = getApplicationComponent(DownloadService.class) ;
590     InputStreamDownloadResource dresource ;
591     Node imageNode = node.getNode(nodeTypeName) ;
592     InputStream input = imageNode.getProperty(Utils.JCR_DATA).getStream() ;
593     dresource = new InputStreamDownloadResource(input, "image") ;
594     dresource.setDownloadName(node.getName()) ;
595     return dservice.getDownloadLink(dservice.addDownloadResource(dresource)) ;
596   }
597 
598   public String getImage(InputStream input, String nodeName) throws Exception {
599     DownloadService dservice = getApplicationComponent(DownloadService.class);
600     InputStreamDownloadResource dresource = new InputStreamDownloadResource(input, "image");
601     dresource.setDownloadName(nodeName);
602     return dservice.getDownloadLink(dservice.addDownloadResource(dresource));
603   }
604 
605   public String getWebDAVServerPrefix() throws Exception {
606     PortletRequestContext portletRequestContext = PortletRequestContext.getCurrentInstance() ;
607     String prefixWebDAV = portletRequestContext.getRequest().getScheme() + "://"
608             + portletRequestContext.getRequest().getServerName() ;
609     int serverPort = portletRequestContext.getRequest().getServerPort();
610     if (serverPort!=80) {
611       prefixWebDAV += ":" + String.format("%s",serverPort);
612     }
613     return prefixWebDAV ;
614   }
615 
616   public Node getViewNode(String nodeType) throws Exception {
617     return getAncestorOfType(UIJCRExplorer.class).getCurrentNode().getNode(nodeType) ;
618   }
619 
620   public Node getNodeByPath(String nodePath, String workspace) throws Exception {
621     ManageableRepository manageRepo = getApplicationComponent(RepositoryService.class).getCurrentRepository();
622     Session session = WCMCoreUtils.getUserSessionProvider().getSession(workspace, manageRepo) ;
623     return getAncestorOfType(UIJCRExplorer.class).getNodeByPath(nodePath, session) ;
624   }
625 
626   public String getActionsList(Node node) throws Exception {
627     return getAncestorOfType(UIWorkingArea.class).getActionsExtensionList(node) ;
628   }
629 
630   public List<Node> getCustomActions(Node node) throws Exception {
631     return getAncestorOfType(UIWorkingArea.class).getCustomActions(node) ;
632   }
633 
634   public boolean isPreferenceNode(Node node) throws Exception {
635     return getAncestorOfType(UIWorkingArea.class).isPreferenceNode(node) ;
636   }
637 
638   public boolean isReadAuthorized(ExtendedNode node) throws Exception {
639     return getAncestorOfType(UIJCRExplorer.class).isReadAuthorized(node) ;
640   }
641 
642   @SuppressWarnings("unchecked")
643   public Object getComponentInstanceOfType(String className) {
644     Object service = null;
645     try {
646       ClassLoader loader =  Thread.currentThread().getContextClassLoader();
647       Class clazz = loader.loadClass(className);
648       service = getApplicationComponent(clazz);
649     } catch (ClassNotFoundException ex) {
650       if (LOG.isErrorEnabled()) {
651         LOG.error("Unexpected error", ex);
652       }
653     }
654     return service;
655   }
656 
657   public String getNodeOwner(Node node) throws RepositoryException {
658     if(node.hasProperty(Utils.EXO_OWNER)) {
659       return node.getProperty(Utils.EXO_OWNER).getString();
660     }
661     return IdentityConstants.ANONIM ;
662   }
663 
664   public Date getDateCreated(Node node) throws Exception{
665     if(node.hasProperty(Utils.EXO_CREATED_DATE)) {
666       return node.getProperty(Utils.EXO_CREATED_DATE).getDate().getTime();
667     }
668     return new GregorianCalendar().getTime();
669   }
670 
671   public Date getDateModified(Node node) throws Exception {
672     if(node.hasProperty(Utils.EXO_MODIFIED_DATE)) {
673       return node.getProperty(Utils.EXO_MODIFIED_DATE).getDate().getTime();
674     }
675     return new GregorianCalendar().getTime();
676   }
677 
678   public List<Node> getRelations() throws Exception {
679     List<Node> relations = new ArrayList<Node>() ;
680     Node currentNode = getCurrentNode();
681     if (currentNode.hasProperty(Utils.EXO_RELATION)) {
682       Value[] vals = currentNode.getProperty(Utils.EXO_RELATION).getValues();
683       for (int i = 0; i < vals.length; i++) {
684         String uuid = vals[i].getString();
685         Node node = getNodeByUUID(uuid);
686         if (node != null)
687           relations.add(node);
688       }
689     }
690     return relations;
691   }
692 
693   public List<Node> getAttachments() throws Exception {
694     List<Node> attachments = new ArrayList<Node>() ;
695     Node currentNode = getCurrentNode();
696     NodeIterator childrenIterator = currentNode.getNodes();
697     int attachData =0 ;
698     while (childrenIterator.hasNext()) {
699       Node childNode = childrenIterator.nextNode();
700       String nodeType = childNode.getPrimaryNodeType().getName();
701       List<String> listCanCreateNodeType =
702         Utils.getListAllowedFileType(currentNode, templateService) ;
703       if(listCanCreateNodeType.contains(nodeType) ) {
704 
705         // Case of childNode has jcr:data property
706         if (childNode.hasProperty(Utils.JCR_DATA)) {
707           attachData = childNode.getProperty(Utils.JCR_DATA).getStream().available();
708 
709           // Case of jcr:data has content.
710           if (attachData > 0)
711             attachments.add(childNode);
712         } else {
713           attachments.add(childNode);
714         }
715       }
716     }
717     return attachments;
718   }
719 
720   public String getViewableLink(Node attNode, Parameter[] params) throws Exception {
721     return this.event("ChangeNode", Utils.formatNodeName(attNode.getPath()), params);
722   }
723 
724   public boolean isNodeTypeSupported(String nodeTypeName) {
725     try {
726       return templateService.isManagedNodeType(nodeTypeName);
727     } catch (Exception e) {
728       return false;
729     }
730   }
731 
732   public String getNodeType() throws Exception { return null; }
733 
734   public List<String> getSupportedLocalise() throws Exception {
735     MultiLanguageService multiLanguageService = getApplicationComponent(MultiLanguageService.class) ;
736     return multiLanguageService.getSupportedLanguages(getCurrentNode());
737   }
738 
739   public String getTemplatePath() throws Exception { return null; }
740 
741   public boolean isNodeTypeSupported() { return false; }
742 
743   public String getVersionName(Node node) throws Exception {
744     return node.getBaseVersion().getName() ;
745   }
746 
747   /**
748    * Method which returns true if the node has a history.
749    */
750   public boolean hasAuditHistory(Node node) throws Exception{
751     AuditService auServ = WCMCoreUtils.getService(AuditService.class);
752     node = node instanceof NodeLinkAware ? ((NodeLinkAware) node).getTargetNode().getRealNode() : node;
753     return auServ.hasHistory(node);
754   }
755 
756   /**
757    * Method which returns the number of histories.
758    */
759   public int getNumAuditHistory(Node node) throws Exception{
760     AuditService auServ = WCMCoreUtils.getService(AuditService.class);
761     node = node instanceof NodeLinkAware ? ((NodeLinkAware) node).getTargetNode().getRealNode() : node;
762     if (auServ.hasHistory(node)) {
763       AuditHistory auHistory = auServ.getHistory(node);
764       return (auHistory.getAuditRecords()).size();
765     }
766     return 0;
767   }
768 
769   public void setNode(Node node) {
770     currentNode_ = NodeLocation.getNodeLocationByNode(node);
771   }
772 
773   public boolean isRssLink() { return false ; }
774   public String getRssLink() { return null ; }
775   
776   /**
777    * Checks if allow render fast publish link for the inline editting
778    *
779    * @return true, if need to render fast publish link
780    */
781   public boolean isFastPublishLink() { return false ; }
782 
783   public String getPortalName() {
784     return WCMCoreUtils.getPortalName();
785   }
786 
787   public String getRepository() throws Exception {
788     return getAncestorOfType(UIJCRExplorer.class).getRepositoryName();
789   }
790 
791   public String getWorkspaceName() throws Exception {
792     if(currentNode_ == null) {
793       return getOriginalNode().getSession().getWorkspace().getName();
794     }
795     return getCurrentNode().getSession().getWorkspace().getName();
796   }
797 
798   public Node getDisplayNode() throws Exception {
799     Node currentNode = getAncestorOfType(UIJCRExplorer.class).getCurrentNode() ;
800     currentNode_ = NodeLocation.getNodeLocationByNode(currentNode);
801     if(currentNode.hasProperty(Utils.EXO_LANGUAGE)) {
802       String defaultLang = currentNode.getProperty(Utils.EXO_LANGUAGE).getString() ;
803       if(getLanguage() == null) setLanguage(defaultLang) ;
804       if(!getLanguage().equals(defaultLang)) {
805         MultiLanguageService multiServ = getApplicationComponent(MultiLanguageService.class);
806         Node curNode = multiServ.getLanguage(currentNode, getLanguage());
807         if (currentNode.isNodeType(Utils.NT_FOLDER) || currentNode.isNodeType(Utils.NT_UNSTRUCTURED)) {
808           try {
809             return curNode.getNode(currentNode.getName());
810           } catch (Exception e) {
811             return curNode;
812           }
813         }
814         return curNode ;
815       }
816     }
817     return currentNode;
818   }
819 
820   public Node getNode() throws Exception {
821     Node ret = getDisplayNode();
822     if (NodePresentation.MEDIA_STATE_DISPLAY.equals(getMediaState()) &&
823         ret.isNodeType(NodetypeConstant.EXO_ACCESSIBLE_MEDIA)) {
824       Node audioDescription = org.exoplatform.services.cms.impl.Utils.getChildOfType(ret, NodetypeConstant.EXO_AUDIO_DESCRIPTION);
825       if (audioDescription != null) {
826         return audioDescription;
827       }
828     }
829     return ret;
830   }
831 
832   public Node getCurrentNode() {
833     return NodeLocation.getNodeByLocation(currentNode_);
834   }
835 
836   public Node getOriginalNode() throws Exception {return getAncestorOfType(UIJCRExplorer.class).getCurrentNode() ;}
837 
838   public String getIcons(Node node, String size) throws Exception {
839     return Utils.getNodeTypeIcon(node, size) ;
840   }
841 
842   public List<Node> getComments() throws Exception {
843     return getApplicationComponent(CommentsService.class).getComments(getCurrentNode(), getLanguage()) ;
844   }
845 
846   public String getViewTemplate(String nodeTypeName, String templateName) throws Exception {
847     TemplateService tempServ = getApplicationComponent(TemplateService.class) ;
848     return tempServ.getTemplatePath(false, nodeTypeName, templateName) ;
849   }
850 
851   public String getTemplateSkin(String nodeTypeName, String skinName) throws Exception {
852     TemplateService tempServ = getApplicationComponent(TemplateService.class) ;
853     return tempServ.getSkinPath(nodeTypeName, skinName, getLanguage()) ;
854   }
855 
856   public String getLanguage() {
857     return getAncestorOfType(UIJCRExplorer.class).getLanguage() ;
858   }
859 
860   public void setLanguage(String language) {
861     getAncestorOfType(UIJCRExplorer.class).setLanguage(language) ;
862   }
863 
864   public boolean isCanPaste() {
865     ClipboardService clipboardService = WCMCoreUtils.getService(ClipboardService.class);
866     String userId = ConversationState.getCurrent().getIdentity().getUserId();
867     
868     UIJCRExplorer uiExplorer = getAncestorOfType(UIJCRExplorer.class) ;
869     if(!clipboardService.getClipboardList(userId, false).isEmpty()) return true;
870     return false;
871   }
872 
873   public void updatePageListData() throws Exception {
874     UIJCRExplorer uiExplorer = this.getAncestorOfType(UIJCRExplorer.class);
875     String currentPath = uiExplorer.getCurrentPath();
876 
877     PageList<Object> pageList = getPageList(currentPath);
878     pageIterator_.setPageList(pageList);
879     if (documentNodeList_ != null) {
880       documentNodeList_.removeChild(UIDocumentNodeList.class);
881       documentNodeList_.setPageList(pageList);
882     }
883     updateTimeLineData_ = true;
884   }
885 
886   @SuppressWarnings("unchecked")
887   public PageList<Object> getPageList(String path) throws Exception {
888     UIJCRExplorer uiExplorer = this.getAncestorOfType(UIJCRExplorer.class);
889     Preference pref = uiExplorer.getPreference();
890     DocumentProviderUtils docProviderUtil = DocumentProviderUtils.getInstance();
891     if (!uiExplorer.isViewTag() && docProviderUtil.canSortType(pref.getSortType()) && 
892         uiExplorer.getAllItemByTypeFilterMap().isEmpty()) {
893       return docProviderUtil.getPageList(
894                uiExplorer.getWorkspaceName(), 
895                uiExplorer.getCurrentPath(), 
896                pref, 
897                uiExplorer.getAllItemFilterMap(), 
898                uiExplorer.getAllItemByTypeFilterMap(),
899                (NodeLinkAware) ItemLinkAware.newInstance(uiExplorer.getWorkspaceName(), path, 
900                                                 uiExplorer.getNodeByPath(path, uiExplorer.getSession())));
901     }
902     
903     int nodesPerPage = pref.getNodesPerPage();
904     List<Node> nodeList = new ArrayList<Node>();
905 
906     if (uiExplorer.isViewTag() && uiExplorer.getTagPaths() != null && !uiExplorer.getTagPaths().isEmpty()) {
907       nodeList = uiExplorer.getDocumentByTag();
908     } else {
909       Set<String> allItemByTypeFilterMap = uiExplorer.getAllItemByTypeFilterMap();
910       if (allItemByTypeFilterMap.size() > 0)
911         nodeList = filterNodeList(uiExplorer.getChildrenList(path, !pref.isShowPreferenceDocuments()));
912       else
913         nodeList = filterNodeList(uiExplorer.getChildrenList(path, pref.isShowPreferenceDocuments()));
914     }
915 
916     ListAccess<Object> nodeAccList = new ListAccessImpl<Object>(Object.class,
917                                                                 NodeLocation.getLocationsByNodeList(nodeList));
918     return new LazyPageList<Object>(nodeAccList, nodesPerPage);
919   }
920 
921   @SuppressWarnings("unchecked")
922   public List<Node> getChildrenList() throws Exception {
923     return NodeLocation.getNodeListByLocationList(pageIterator_.getCurrentPageData());
924   }
925 
926   public String getTypeSort() { return typeSort_; }
927 
928   public void setTypeSort(String typeSort) {
929     typeSort_ = typeSort;
930   }
931 
932   public String getSortOrder() { return sortOrder_; }
933 
934   public void setSortOrder(String sortOrder) {
935     sortOrder_ = sortOrder;
936   }
937 
938   public String encodeHTML(String text) { return Utils.encodeHTML(text) ; }
939 
940 
941   public UIComponent getCommentComponent() {
942     UIJCRExplorer uiExplorer = getAncestorOfType(UIJCRExplorer.class);
943     UIActionBar uiActionBar = uiExplorer.findFirstComponentOfType(UIActionBar.class);
944     UIComponent uicomponent = uiActionBar.getUIAction(COMMENT_COMPONENT);
945     return (uicomponent != null ? uicomponent : this);
946   }
947 
948   public boolean isEnableThumbnail() {
949     ThumbnailService thumbnailService = getApplicationComponent(ThumbnailService.class);
950     return thumbnailService.isEnableThumbnail();
951   }
952 
953   public String getFlowImage(Node node) throws Exception {
954     node = node instanceof NodeLinkAware ? ((NodeLinkAware) node).getTargetNode().getRealNode() : node;
955     return Utils.getThumbnailImage(node, ThumbnailService.BIG_SIZE);
956   }
957 
958   public String getThumbnailSize(Node node) throws Exception {
959     node = node instanceof NodeLinkAware ? ((NodeLinkAware) node).getTargetNode().getRealNode() : node;
960     String imageSize = null;
961     if(node.hasProperty(ThumbnailService.BIG_SIZE)) {
962       Image image = ImageIO.read(node.getProperty(ThumbnailService.BIG_SIZE).getStream());
963       imageSize =
964         Integer.toString(image.getWidth(null)) + "x" + Integer.toString(image.getHeight(null));
965     }
966     return imageSize;
967   }
968 
969   public DateFormat getSimpleDateFormat() {
970     Locale locale = Util.getUIPortal().getAncestorOfType(UIPortalApplication.class).getLocale();
971     return SimpleDateFormat.getDateTimeInstance(SimpleDateFormat.SHORT, SimpleDateFormat.SHORT, locale);
972   }
973 
974   public boolean isSymLink(Node node) throws RepositoryException {
975     LinkManager linkManager = getApplicationComponent(LinkManager.class);
976     return linkManager.isLink(node);
977   }
978 
979   public UIComponent getRemoveAttach() throws Exception {
980     removeChild(RemoveAttachmentComponent.class);
981     UIComponent uicomponent = addChild(RemoveAttachmentComponent.class, null, "DocumentInfoRemoveAttach");
982     ((AbstractActionComponent)uicomponent).setLstComponentupdate(Arrays.asList(new Class[] {UIDocumentContainer.class}));
983     return uicomponent;
984   }
985 
986   public UIComponent getRemoveComment() throws Exception {
987     removeChild(RemoveCommentComponent.class);
988     UIComponent uicomponent = addChild(RemoveCommentComponent.class, null, "DocumentInfoRemoveComment");
989     ((AbstractActionComponent) uicomponent).setLstComponentupdate(Arrays.asList(new Class[] {
990         UIDocumentContainer.class, UIWorkingArea.class }));
991     return uicomponent;
992   }
993 
994   public boolean isFavouriter(Node data) throws Exception {
995     return isFavouriteNode(WCMCoreUtils.getRemoteUser(), data);
996   }
997 
998   public boolean isFavouriteNode(String userName, Node node) throws Exception {
999     return getApplicationComponent(FavoriteService.class).isFavoriter(userName, node);
1000   }
1001 
1002   public boolean isMediaType(Node data) throws Exception {
1003     if (!data.isNodeType(Utils.NT_FILE)) return false;
1004     String mimeType = data.getNode(Utils.JCR_CONTENT).getProperty(Utils.JCR_MIMETYPE).getString();
1005     UIExtensionManager manager = getApplicationComponent(UIExtensionManager.class);
1006     Map<String, Object> context = new HashMap<String, Object>();
1007     context.put(Utils.MIME_TYPE, mimeType);
1008     if (manager.accept(Utils.FILE_VIEWER_EXTENSION_TYPE, "VideoAudio", context)) {
1009         return true;
1010     }
1011     return false;
1012   }
1013 
1014   public String getPropertyNameWithoutNamespace(String propertyName) {
1015     if(propertyName.indexOf(":") > -1) {
1016       return propertyName.split(":")[1];
1017     }
1018     return propertyName;
1019   }
1020 
1021   public String getPropertyValue(Node node, String propertyName) throws Exception {
1022     try {
1023       Property property = node.getProperty(propertyName);
1024       if(property != null) {
1025         int requiredType = property.getDefinition().getRequiredType();
1026         switch (requiredType) {
1027         case PropertyType.STRING:
1028           return property.getString();
1029         case PropertyType.DATE:
1030           return getSimpleDateFormat().format(property.getDate().getTime());
1031         }
1032       }
1033     } catch(PathNotFoundException PNE) {
1034       return "";
1035     }
1036     return "";
1037   }
1038 
1039   public DriveData getDrive(List<DriveData> lstDrive, Node node) throws RepositoryException{
1040     DriveData driveData = null;
1041     for (DriveData drive : lstDrive) {
1042       if (node.getSession().getWorkspace().getName().equals(drive.getWorkspace())
1043           && node.getPath().contains(drive.getHomePath()) && drive.getHomePath().equals("/")) {
1044         driveData = drive;
1045         break;
1046       }
1047     }
1048     return driveData;
1049   }
1050 
1051   public List<Node> filterNodeList(List<Node> sourceNodeList) throws Exception {
1052     List<Node> ret = new ArrayList<Node>();
1053 
1054     if (!this.hasFilters()) {
1055       return sourceNodeList;
1056     }
1057 
1058     for (Node node : sourceNodeList) {
1059       try {
1060         if (filterOk(node))
1061           ret.add(node);
1062       } catch (Exception ex) {
1063         if (LOG.isWarnEnabled()) {
1064           LOG.warn(ex.getMessage());
1065         }
1066       }
1067     }
1068 
1069     return ret;
1070   }
1071 
1072   private boolean hasFilters() {
1073     UIJCRExplorer uiExplorer = this.getAncestorOfType(UIJCRExplorer.class);
1074     Set<String> allItemsFilterSet = uiExplorer.getAllItemFilterMap();
1075     Set<String> allItemsByTypeFilterSet = uiExplorer.getAllItemByTypeFilterMap();
1076     return (allItemsByTypeFilterSet.size() > 0 || allItemsFilterSet.size() > 0);
1077   }
1078 
1079   private boolean filterOk(Node node) throws Exception {
1080     UIJCRExplorer uiExplorer = this.getAncestorOfType(UIJCRExplorer.class);
1081 
1082     Set<String> allItemsFilterSet = uiExplorer.getAllItemFilterMap();
1083     Set<String> allItemsByTypeFilterSet = uiExplorer.getAllItemByTypeFilterMap();
1084 
1085     String userId = WCMCoreUtils.getRemoteUser();
1086 
1087     //Owned by me
1088     if (allItemsFilterSet.contains(NodetypeConstant.OWNED_BY_ME) &&
1089         !userId.equals(node.getProperty(NodetypeConstant.EXO_OWNER).getString()))
1090           return false;
1091     //Favorite
1092     if (allItemsFilterSet.contains(NodetypeConstant.FAVORITE) &&
1093         !favoriteService.isFavoriter(userId, node))
1094           return false;
1095     //Hidden
1096 /*
1097     Behaviour of this filter is different from the others, it shows up hidden nodes or not, not just filter them.
1098 */
1099 
1100     //By types
1101     if(allItemsByTypeFilterSet.isEmpty())
1102       return true;
1103     boolean found = false;
1104     try {
1105       for (String documentType : allItemsByTypeFilterSet) {
1106         for (String mimeType : documentTypeService.getMimeTypes(documentType)) {
1107           if(node.hasNode(Utils.JCR_CONTENT)){
1108             Node content = node.getNode(Utils.JCR_CONTENT);
1109             if (content.hasProperty(Utils.JCR_MIMETYPE)
1110                     && content.getProperty(Utils.JCR_MIMETYPE).getString().indexOf(mimeType) >= 0) {
1111               found = true;
1112               break;
1113             }
1114           }
1115         }
1116       }
1117     } catch (PathNotFoundException ep) {
1118       if (LOG.isErrorEnabled()) {
1119         LOG.error("Cannot found the node path in the repository. We will continue filter by content type in the next block code.");
1120       }
1121   }
1122 
1123     if(!found && allItemsByTypeFilterSet.contains(Contents_Document_Type)) {
1124       for(String contentType:templateService.getAllDocumentNodeTypes()){
1125         if (node.isNodeType(contentType)){
1126           found=true;
1127           break;
1128         }
1129       }
1130     }
1131     return found;
1132   }
1133 
1134   static public class ViewNodeActionListener extends EventListener<UIDocumentInfo> {
1135     public void execute(Event<UIDocumentInfo> event) throws Exception {
1136       UIDocumentInfo uicomp = event.getSource() ;
1137       UIApplication uiApp = uicomp.getAncestorOfType(UIApplication.class);
1138       UIJCRExplorer uiExplorer = uicomp.getAncestorOfType(UIJCRExplorer.class);
1139       try {
1140         String uri = event.getRequestContext().getRequestParameter(OBJECTID) ;
1141         String workspaceName = event.getRequestContext().getRequestParameter("workspaceName") ;
1142         uiExplorer.setSelectNode(workspaceName, uri) ;
1143         uiExplorer.updateAjax(event) ;
1144         event.broadcast();
1145       } catch(RepositoryException e) {
1146         if (LOG.isErrorEnabled()) {
1147           LOG.error("Repository cannot be found");
1148         }
1149         uiApp.addMessage(new ApplicationMessage("UIDocumentInfo.msg.repository-error", null,
1150             ApplicationMessage.WARNING)) ;
1151 
1152         return ;
1153       } catch (Exception e) {
1154         JCRExceptionManager.process(uiApp, e);
1155         return;
1156       }
1157     }
1158   }
1159 
1160   static public class ChangeNodeActionListener extends EventListener<UIDocumentInfo> {
1161     public void execute(Event<UIDocumentInfo> event) throws Exception {
1162       UIDocumentInfo uicomp =  event.getSource();
1163 
1164       NodeFinder nodeFinder = uicomp.getApplicationComponent(NodeFinder.class);
1165       UIJCRExplorer uiExplorer = uicomp.getAncestorOfType(UIJCRExplorer.class);
1166       UITreeExplorer uiTreeExplorer = uiExplorer.findFirstComponentOfType(UITreeExplorer.class);
1167       String uri = event.getRequestContext().getRequestParameter(OBJECTID);
1168       String workspaceName = event.getRequestContext().getRequestParameter("workspaceName");
1169       boolean findDrive = Boolean.getBoolean(event.getRequestContext().getRequestParameter("findDrive"));
1170       UIApplication uiApp = uicomp.getAncestorOfType(UIApplication.class);
1171       AutoVersionService autoVersionService = WCMCoreUtils.getService(AutoVersionService.class);
1172       try {
1173         // Manage ../ and ./
1174         uri = LinkUtils.evaluatePath(uri);
1175         // Just in order to check if the node exists
1176         Item item = nodeFinder.getItem(workspaceName, uri);
1177         if ((item instanceof Node) && Utils.isInTrash((Node) item)) {
1178           return;
1179         }
1180         uiExplorer.setSelectNode(workspaceName, uri);
1181         if (findDrive) {
1182           ManageDriveService manageDriveService = uicomp.getApplicationComponent(ManageDriveService.class);
1183           List<DriveData> driveList = manageDriveService.getDriveByUserRoles(Util.getPortalRequestContext()
1184                                                                                  .getRemoteUser(),
1185                                                                              Utils.getMemberships());
1186           DriveData drive = uicomp.getDrive(driveList, uiExplorer.getCurrentNode());
1187           String warningMSG = null;
1188           if (driveList.size() == 0) {
1189             warningMSG = "UIDocumentInfo.msg.access-denied";
1190           } else if (drive == null) {
1191             warningMSG = "UIPopupMenu.msg.path-not-found-exception";
1192           }
1193           if (warningMSG != null) {
1194             uiApp.addMessage(new ApplicationMessage(warningMSG, null, ApplicationMessage.WARNING)) ;
1195 
1196             return ;
1197           }
1198           uiExplorer.setDriveData(uicomp.getDrive(driveList, uiExplorer.getCurrentNode()));
1199         }
1200         uiExplorer.updateAjax(event);
1201         event.getRequestContext().getJavascriptManager().
1202         require("SHARED/multiUpload", "multiUpload").
1203         addScripts("multiUpload.setLocation('" +
1204                    uiExplorer.getWorkspaceName()  + "','" +
1205                    uiExplorer.getDriveData().getName()  + "','" +
1206                    uiTreeExplorer.getLabel()  + "','" +
1207                    uiExplorer.getCurrentPath() + "','" +
1208                    org.exoplatform.services.cms.impl.Utils.getPersonalDrivePath(uiExplorer.getDriveData().getHomePath(),
1209                    ConversationState.getCurrent().getIdentity().getUserId())+ "', '"+
1210                    autoVersionService.isVersionSupport(uiExplorer.getCurrentPath(), uiExplorer.getCurrentWorkspace())+"');");
1211       } catch(ItemNotFoundException nu) {
1212         uiApp.addMessage(new ApplicationMessage("UIDocumentInfo.msg.null-exception", null, ApplicationMessage.WARNING)) ;
1213 
1214         return ;
1215       } catch(PathNotFoundException pa) {
1216         uiApp.addMessage(new ApplicationMessage("UIDocumentInfo.msg.path-not-found", null, ApplicationMessage.WARNING)) ;
1217 
1218         return ;
1219       } catch(AccessDeniedException ace) {
1220         uiApp.addMessage(new ApplicationMessage("UIDocumentInfo.msg.access-denied", null, ApplicationMessage.WARNING)) ;
1221 
1222         return ;
1223       } catch(RepositoryException e) {
1224         if (LOG.isErrorEnabled()) {
1225           LOG.error("Repository cannot be found");
1226         }
1227         uiApp.addMessage(new ApplicationMessage("UIDocumentInfo.msg.repository-error", null,
1228             ApplicationMessage.WARNING)) ;
1229 
1230         return ;
1231       } catch (Exception e) {
1232         JCRExceptionManager.process(uiApp, e);
1233         return;
1234       }
1235     }
1236   }
1237 
1238   static public class SortActionListener extends EventListener<UIDocumentInfo> {
1239     public void execute(Event<UIDocumentInfo> event) throws Exception {
1240       UIDocumentInfo uicomp = event.getSource() ;
1241       UIJCRExplorer uiExplorer = uicomp.getAncestorOfType(UIJCRExplorer.class);
1242       UIApplication uiApp = uicomp.getAncestorOfType(UIApplication.class);
1243       try {
1244         String sortParam = event.getRequestContext().getRequestParameter(OBJECTID) ;
1245         String[] array = sortParam.split(";");
1246         String order = Preference.ASCENDING_ORDER.equals(array[0].trim()) || !array[1].trim().equals(uicomp.getTypeSort()) ?
1247                        Preference.BLUE_DOWN_ARROW : Preference.BLUE_UP_ARROW;
1248 
1249         String prefOrder = Preference.ASCENDING_ORDER.equals(array[0].trim()) || !array[1].trim().equals(uicomp.getTypeSort())?
1250                            Preference.ASCENDING_ORDER : Preference.DESCENDING_ORDER;
1251         if(!uicomp.getTypeSort().equals(array[1].trim()) && array[1].trim().equals("Date")){
1252           order = Preference.BLUE_UP_ARROW;
1253           prefOrder = Preference.DESCENDING_ORDER;  
1254         }
1255         uicomp.setSortOrder(order);
1256         uicomp.setTypeSort(array[1]);
1257         Preference pref = uiExplorer.getPreference();
1258         if (array.length == 2) {
1259           pref.setSortType(array[1].trim());
1260           pref.setOrder(prefOrder);
1261         } else {
1262           return ;
1263         }
1264         uiExplorer.updateAjax(event) ;
1265       } catch(RepositoryException e) {
1266         if (LOG.isErrorEnabled()) {
1267           LOG.error("Repository cannot be found");
1268         }
1269         uiApp.addMessage(new ApplicationMessage("UIDocumentInfo.msg.repository-error", null,
1270             ApplicationMessage.WARNING)) ;
1271 
1272         return ;
1273       } catch (Exception e) {
1274         JCRExceptionManager.process(uiApp, e);
1275         return;
1276       }
1277     }
1278   }
1279 
1280   static public class ChangeLanguageActionListener extends EventListener<UIDocumentInfo> {
1281     public void execute(Event<UIDocumentInfo> event) throws Exception {
1282       UIDocumentInfo uiDocumentInfo = event.getSource() ;
1283       UIJCRExplorer uiExplorer = uiDocumentInfo.getAncestorOfType(UIJCRExplorer.class) ;
1284       UIApplication uiApp = uiDocumentInfo.getAncestorOfType(UIApplication.class);
1285       try {
1286         String selectedLanguage = event.getRequestContext().getRequestParameter(OBJECTID) ;
1287         uiExplorer.setLanguage(selectedLanguage) ;
1288         uiExplorer.updateAjax(event) ;
1289       } catch(RepositoryException e) {
1290         if (LOG.isErrorEnabled()) {
1291           LOG.error("Repository cannot be found");
1292         }
1293         uiApp.addMessage(new ApplicationMessage("UIDocumentInfo.msg.repository-error", null,
1294             ApplicationMessage.WARNING)) ;
1295 
1296         return ;
1297       } catch (Exception e) {
1298         JCRExceptionManager.process(uiApp, e);
1299         return;
1300       }
1301     }
1302   }
1303 
1304   static public class VoteActionListener extends EventListener<UIDocumentInfo> {
1305     public void execute(Event<UIDocumentInfo> event) throws Exception {
1306       UIDocumentInfo uiComp = event.getSource();
1307       UIApplication uiApp = uiComp.getAncestorOfType(UIApplication.class);
1308       try {
1309         String userName = Util.getPortalRequestContext().getRemoteUser() ;
1310         double objId = Double.parseDouble(event.getRequestContext().getRequestParameter(OBJECTID)) ;
1311         VotingService votingService = uiComp.getApplicationComponent(VotingService.class) ;
1312         votingService.vote(uiComp.getCurrentNode(), objId, userName, uiComp.getLanguage()) ;
1313       } catch(RepositoryException e) {
1314         if (LOG.isErrorEnabled()) {
1315           LOG.error("Repository cannot be found");
1316         }
1317         uiApp.addMessage(new ApplicationMessage("UIDocumentInfo.msg.repository-error", null,
1318             ApplicationMessage.WARNING)) ;
1319 
1320         return ;
1321       } catch (Exception e) {
1322         JCRExceptionManager.process(uiApp, e);
1323         return;
1324       }
1325     }
1326   }
1327 
1328   static public class DownloadActionListener extends EventListener<UIDocumentInfo> {
1329     public void execute(Event<UIDocumentInfo> event) throws Exception {
1330       UIDocumentInfo uiComp = event.getSource();
1331       UIApplication uiApp = uiComp.getAncestorOfType(UIApplication.class);
1332       try {
1333         String downloadLink = uiComp.getDownloadLink(org.exoplatform.wcm.webui.Utils.getFileLangNode(uiComp.getNode()));
1334         RequireJS requireJS = event.getRequestContext().getJavascriptManager().getRequireJS();
1335         requireJS.require("SHARED/ecm-utils", "ecmutil").addScripts("ecmutil.ECMUtils.ajaxRedirect('" + downloadLink + "');");
1336       } catch(RepositoryException e) {
1337         if (LOG.isErrorEnabled()) {
1338           LOG.error("Repository cannot be found");
1339         }
1340         uiApp.addMessage(new ApplicationMessage("UIDocumentInfo.msg.repository-error", null,
1341             ApplicationMessage.WARNING)) ;
1342 
1343         return ;
1344       } catch (Exception e) {
1345         JCRExceptionManager.process(uiApp, e);
1346         return;
1347       }
1348     }
1349   }
1350 
1351   static public class StarClickActionListener extends EventListener<UIDocumentInfo> {
1352     public void execute(Event<UIDocumentInfo> event) throws Exception {
1353       String srcPath = event.getRequestContext().getRequestParameter(OBJECTID);
1354       UIDocumentInfo uiDocumentInfo = event.getSource();
1355       UIJCRExplorer uiExplorer = uiDocumentInfo.getAncestorOfType(UIJCRExplorer.class);
1356       UIApplication uiApp = uiDocumentInfo.getAncestorOfType(UIApplication.class);
1357       FavoriteService favoriteService =
1358         uiDocumentInfo.getApplicationComponent(FavoriteService.class);
1359       Matcher matcher = UIWorkingArea.FILE_EXPLORER_URL_SYNTAX.matcher(srcPath);
1360       String wsName = null;
1361       Node node = null;
1362       if (matcher.find()) {
1363         wsName = matcher.group(1);
1364         srcPath = matcher.group(2);
1365       } else {
1366         throw new IllegalArgumentException("The ObjectId is invalid '"+ srcPath + "'");
1367       }
1368 
1369       Session session = null;
1370       try {
1371         session = uiExplorer.getSessionByWorkspace(wsName);
1372         // Use the method getNodeByPath because it is link aware
1373         node = uiExplorer.getNodeByPath(srcPath, session, false);
1374         // Reset the path to manage the links that potentially create virtual path
1375         srcPath = node.getPath();
1376         // Reset the session to manage the links that potentially change of workspace
1377         session = node.getSession();
1378         // Reset the workspace name to manage the links that potentially change of workspace
1379         wsName = session.getWorkspace().getName();
1380       } catch(PathNotFoundException path) {
1381         uiApp.addMessage(new ApplicationMessage("UIPopupMenu.msg.path-not-found-exception",
1382             null,ApplicationMessage.WARNING));
1383 
1384         return;
1385       } catch(RepositoryException e) {
1386         if (LOG.isErrorEnabled()) {
1387           LOG.error("Repository cannot be found");
1388         }
1389         uiApp.addMessage(new ApplicationMessage("UIDocumentInfo.msg.repository-error", null,
1390             ApplicationMessage.WARNING)) ;
1391 
1392         return ;
1393       } catch (Exception e) {
1394         JCRExceptionManager.process(uiApp, e);
1395         return;
1396       }
1397 
1398       try {
1399           uiExplorer.addLockToken(node);
1400       } catch (Exception e) {
1401         JCRExceptionManager.process(uiApp, e);
1402         return;
1403       }
1404       try {
1405         if (favoriteService.isFavoriter(WCMCoreUtils.getRemoteUser(), node)) {
1406           if (PermissionUtil.canRemoveNode(node)) {
1407             favoriteService.removeFavorite(node, WCMCoreUtils.getRemoteUser());
1408           }
1409           else {
1410             throw new AccessDeniedException();
1411           }
1412         } else {
1413           if (PermissionUtil.canSetProperty(node)) {
1414             favoriteService.addFavorite(node, WCMCoreUtils.getRemoteUser());
1415           }
1416           else {
1417             throw new AccessDeniedException();
1418           }
1419         }
1420         //uiStar.changeFavourite();
1421         uiExplorer.updateAjax(event);
1422       } catch (AccessDeniedException e) {
1423         if (LOG.isErrorEnabled()) {
1424           LOG.error("Access denied! No permission for modifying property " +
1425                     Utils.EXO_FAVOURITER + " of node: " + node.getPath());
1426         }
1427         uiApp.addMessage(new ApplicationMessage("UIShowAllFavouriteResult.msg.accessDenied", null, ApplicationMessage.WARNING));
1428 
1429       } catch (VersionException ve) {
1430         uiApp.addMessage(new ApplicationMessage("UIPopupMenu.msg.remove-verion-exception", null,
1431             ApplicationMessage.WARNING));
1432 
1433         uiExplorer.updateAjax(event);
1434         return;
1435       } catch (ReferentialIntegrityException ref) {
1436         session.refresh(false);
1437         uiExplorer.refreshExplorer();
1438         uiApp
1439             .addMessage(new ApplicationMessage(
1440                 "UIPopupMenu.msg.remove-referentialIntegrityException", null,
1441                 ApplicationMessage.WARNING));
1442 
1443         uiExplorer.updateAjax(event);
1444         return;
1445       } catch (ConstraintViolationException cons) {
1446         session.refresh(false);
1447         uiExplorer.refreshExplorer();
1448         uiApp.addMessage(new ApplicationMessage("UIPopupMenu.msg.constraintviolation-exception",
1449             null, ApplicationMessage.WARNING));
1450 
1451         uiExplorer.updateAjax(event);
1452         return;
1453       } catch (LockException lockException) {
1454         uiApp.addMessage(new ApplicationMessage("UIPopupMenu.msg.node-locked-other-person", null,
1455             ApplicationMessage.WARNING));
1456 
1457         uiExplorer.updateAjax(event);
1458         return;
1459       } catch (Exception e) {
1460         if (LOG.isErrorEnabled()) {
1461           LOG.error("an unexpected error occurs while removing the node", e);
1462         }
1463         JCRExceptionManager.process(uiApp, e);
1464 
1465         return;
1466       }
1467     }
1468   }
1469 
1470   static public class SortTimelineASCActionListener extends EventListener<UIDocumentInfo> {
1471     public void execute(Event<UIDocumentInfo> event) throws Exception {
1472       UIDocumentInfo uiDocumentInfo = event.getSource();
1473       String objectID = event.getRequestContext().getRequestParameter(OBJECTID);
1474       if (objectID.equals("favourite")) {
1475         uiDocumentInfo.timeLineSortByFavourite = Preference.BLUE_DOWN_ARROW;
1476         uiDocumentInfo.timeLineSortByName = "";
1477         uiDocumentInfo.timeLineSortByDate = "";
1478       } else if (objectID.equals("name")) {
1479         uiDocumentInfo.timeLineSortByFavourite = "";
1480         uiDocumentInfo.timeLineSortByName = Preference.BLUE_DOWN_ARROW;
1481         uiDocumentInfo.timeLineSortByDate = "";
1482       } else if (objectID.equals("dateTime")) {
1483         uiDocumentInfo.timeLineSortByFavourite = "";
1484         uiDocumentInfo.timeLineSortByName = "";
1485         uiDocumentInfo.timeLineSortByDate = Preference.BLUE_DOWN_ARROW;
1486       }
1487       uiDocumentInfo.updateNodeLists();
1488       event.getRequestContext().addUIComponentToUpdateByAjax(uiDocumentInfo);
1489     }
1490   }
1491 
1492   static public class SortTimelineDESCActionListener extends EventListener<UIDocumentInfo> {
1493     public void execute(Event<UIDocumentInfo> event) throws Exception {
1494       UIDocumentInfo uiDocumentInfo = event.getSource();
1495       String objectID = event.getRequestContext().getRequestParameter(OBJECTID);
1496       if (objectID.equals("favourite")) {
1497         uiDocumentInfo.timeLineSortByFavourite = Preference.BLUE_UP_ARROW;
1498         uiDocumentInfo.timeLineSortByName = "";
1499         uiDocumentInfo.timeLineSortByDate = "";
1500       } else if (objectID.equals("name")) {
1501         uiDocumentInfo.timeLineSortByFavourite = "";
1502         uiDocumentInfo.timeLineSortByName = Preference.BLUE_UP_ARROW;
1503         uiDocumentInfo.timeLineSortByDate = "";
1504       } else if (objectID.equals("dateTime")) {
1505         uiDocumentInfo.timeLineSortByFavourite = "";
1506         uiDocumentInfo.timeLineSortByName = "";
1507         uiDocumentInfo.timeLineSortByDate = Preference.BLUE_UP_ARROW;
1508       }
1509       uiDocumentInfo.updateNodeLists();
1510       event.getRequestContext().addUIComponentToUpdateByAjax(uiDocumentInfo);
1511     }
1512   }
1513 
1514   static public class SwitchToAudioDescriptionActionListener extends EventListener<UIDocumentInfo> {
1515     public void execute(Event<UIDocumentInfo> event) throws Exception {
1516       UIDocumentInfo uiDocumentInfo = event.getSource();
1517       UIJCRExplorer uiExplorer = uiDocumentInfo.getAncestorOfType(UIJCRExplorer.class);
1518       uiDocumentInfo.switchMediaState();
1519       event.getRequestContext().addUIComponentToUpdateByAjax(uiExplorer);
1520     }
1521   }
1522 
1523   static public class SwitchToOriginalActionListener extends EventListener<UIDocumentInfo> {
1524     public void execute(Event<UIDocumentInfo> event) throws Exception {
1525       UIDocumentInfo uiDocumentInfo = event.getSource();
1526       UIJCRExplorer uiExplorer = uiDocumentInfo.getAncestorOfType(UIJCRExplorer.class);
1527       uiDocumentInfo.switchMediaState();
1528       event.getRequestContext().addUIComponentToUpdateByAjax(uiExplorer);
1529     }
1530   }
1531 
1532 //  public boolean isRenderAccessibleMedia() {
1533 //    Node originalNode = getOriginalNode();
1534 //    if (!originalNode.hasNode("audioDescription")) return false;
1535 //    Node audioDescription = originalNode.getNode("audioDescription");
1536 //    if (!audioDescription.isNodeType("exo:audioDescription")) return false;
1537 //    return true;
1538 //  }
1539 
1540   static public class ShowPageActionListener extends EventListener<UIPageIterator> {
1541     public void execute(Event<UIPageIterator> event) throws Exception {
1542       UIPageIterator uiPageIterator = event.getSource() ;
1543 
1544       // If in the timeline view, then does not have the equivalent paginator on the left tree view explorer
1545       if (!UIDocumentInfo.CONTENT_PAGE_ITERATOR_ID.equalsIgnoreCase(uiPageIterator.getId())) {
1546         return;
1547       }
1548       UIApplication uiApp = uiPageIterator.getAncestorOfType(UIApplication.class);
1549       UIJCRExplorer explorer = uiPageIterator.getAncestorOfType(UIJCRExplorer.class);
1550       UITreeExplorer treeExplorer = explorer.findFirstComponentOfType(UITreeExplorer.class);
1551       try {
1552         if(treeExplorer == null) return;
1553         String componentId = explorer.getCurrentNode().getPath();
1554         UITreeNodePageIterator extendedPageIterator = treeExplorer.getUIPageIterator(componentId);
1555         if(extendedPageIterator == null) return;
1556         int page = Integer.parseInt(event.getRequestContext().getRequestParameter(OBJECTID)) ;
1557         extendedPageIterator.setCurrentPage(page);
1558         event.getRequestContext().addUIComponentToUpdateByAjax(explorer);
1559       } catch(RepositoryException e) {
1560         if (LOG.isErrorEnabled()) {
1561           LOG.error("Repository cannot be found");
1562         }
1563         uiApp.addMessage(new ApplicationMessage("UIDocumentInfo.msg.repository-error", null,
1564             ApplicationMessage.WARNING)) ;
1565 
1566         return ;
1567       } catch (Exception e) {
1568         JCRExceptionManager.process(uiApp, e);
1569         return;
1570       }
1571     }
1572   }
1573 
1574   private class SearchComparator implements Comparator<NodeLocation> {
1575     public int compare(NodeLocation nodeA, NodeLocation nodeB) {
1576       try {
1577         Node node1 = NodeLocation.getNodeByLocation(nodeA);
1578         Node node2 = NodeLocation.getNodeByLocation(nodeB);
1579         if (timeLineSortByFavourite.length() != 0) {
1580           int factor = (timeLineSortByFavourite.equals(Preference.BLUE_DOWN_ARROW)) ? 1 : -1;
1581           if (isFavouriter(node1)) return -1 * factor;
1582           else if (isFavouriter(node2)) return 1 * factor;
1583           else return 0;
1584 
1585         } else if (timeLineSortByDate.length() != 0) {
1586           int factor = timeLineSortByDate.equals(Preference.BLUE_DOWN_ARROW) ? 1 : -1;
1587           Calendar c1 = node1.getProperty(Utils.EXO_MODIFIED_DATE).getValue().getDate();
1588           Calendar c2 = node2.getProperty(Utils.EXO_MODIFIED_DATE).getValue().getDate();
1589           return factor * c1.compareTo(c2);
1590 
1591         } else if (timeLineSortByName.length() != 0) {
1592           int factor = timeLineSortByName.equals(Preference.BLUE_DOWN_ARROW) ? 1 : -1;
1593           String s1 = Utils.getTitle(node1).toLowerCase();
1594           String s2 = Utils.getTitle(node2).toLowerCase();
1595           return factor * s1.compareTo(s2);
1596         }
1597       } catch (Exception e) {
1598         if (LOG.isErrorEnabled()) {
1599           LOG.error("Cannot compare nodes", e);
1600         }
1601       }
1602       return 0;
1603     }
1604   }
1605 
1606   static public class CollapseTimelineCatergoryActionListener extends EventListener<UIDocumentInfo> {
1607 
1608     @Override
1609     public void execute(Event<UIDocumentInfo> event) throws Exception {
1610       UIDocumentInfo uiDocumentInfo = event.getSource();
1611       UIJCRExplorer uiExplorer = uiDocumentInfo.getAncestorOfType(UIJCRExplorer.class);
1612       uiDocumentInfo.displayCategory_ = UIDocumentInfo.CATEGORY_ALL;
1613 
1614       uiExplorer.updateAjax(event);
1615     }
1616 
1617   }
1618 
1619   static public class ExpandTimelineCatergoryActionListener extends EventListener<UIDocumentInfo> {
1620 
1621     @Override
1622     public void execute(Event<UIDocumentInfo> event) throws Exception {
1623       UIDocumentInfo uiDocumentInfo = event.getSource();
1624       UIJCRExplorer uiExplorer = uiDocumentInfo.getAncestorOfType(UIJCRExplorer.class);
1625       String category = event.getRequestContext().getRequestParameter(OBJECTID);
1626       uiDocumentInfo.displayCategory_ = category;
1627 
1628       uiExplorer.updateAjax(event);
1629     }
1630 
1631   }
1632 
1633   public boolean isEnableComment() {
1634     return true;
1635   }
1636 
1637   public boolean isEnableVote() {
1638     return true;
1639   }
1640 
1641   public void setEnableComment(boolean value) {
1642   }
1643 
1644   public void setEnableVote(boolean value) {
1645   }
1646 
1647   public String getInlineEditingField(Node orgNode, String propertyName, String defaultValue,
1648       String inputType, String idGenerator, String cssClass,
1649       boolean isGenericProperty, String... arguments) throws Exception {
1650     return org.exoplatform.ecm.webui.utils.Utils.getInlineEditingField(orgNode, propertyName, defaultValue, inputType,
1651                                                                        idGenerator, cssClass, isGenericProperty, arguments);
1652   }
1653 
1654   public String getInlineEditingField(Node orgNode, String propertyName) throws Exception {
1655     return org.exoplatform.ecm.webui.utils.Utils.getInlineEditingField(orgNode, propertyName);
1656   }
1657 
1658   /**
1659    * @return the itemsPerTimeline
1660    */
1661   public int getItemsPerTimeline() {
1662     if (itemsPerTimeline <=0 ) {
1663       return 5;
1664     }
1665     return itemsPerTimeline;
1666   }
1667 
1668   /**
1669    *
1670    * @return
1671    */
1672   public HashMap<String, String> getIsExpanded() {
1673     return isExpanded_;
1674   }
1675 
1676   public Set<String> getExpandedFolders() {
1677     return this.expandedFolders_;
1678   }
1679 
1680   @Override
1681   public boolean isDisplayAlternativeText() {
1682     try {
1683       Node node = this.getNode();
1684       return node.isNodeType(NodetypeConstant.EXO_ACCESSIBLE_MEDIA) &&
1685              node.hasProperty(NodetypeConstant.EXO_ALTERNATIVE_TEXT) &&
1686              StringUtils.isNotEmpty(node.getProperty(NodetypeConstant.EXO_ALTERNATIVE_TEXT).getString());
1687     } catch (Exception e) { return false; }
1688   }
1689 
1690   @Override
1691   public boolean playAudioDescription() {
1692     try {
1693       Node node = this.getNode();
1694       return node.isNodeType(NodetypeConstant.EXO_ACCESSIBLE_MEDIA) &&
1695              org.exoplatform.services.cms.impl.Utils.hasChild(node, NodetypeConstant.EXO_AUDIO_DESCRIPTION);
1696     } catch (Exception e) { return false; }
1697   }
1698 
1699   @Override
1700   public boolean switchBackAudioDescription() {
1701     try {
1702       Node node = this.getNode();
1703       Node parent = node.getParent();
1704       return node.isNodeType(NodetypeConstant.EXO_AUDIO_DESCRIPTION) &&
1705              parent.isNodeType(NodetypeConstant.EXO_ACCESSIBLE_MEDIA);
1706     } catch (Exception e) { return false; }
1707   }
1708 
1709   /**
1710    * checks if user has permission to add nt:file to current node
1711    * @throws Exception
1712    */
1713   public boolean canAddNode() throws Exception {
1714     Node currentNode = getAncestorOfType(UIJCRExplorer.class).getCurrentNode();
1715     return canAddNode(currentNode);
1716   }
1717 
1718   /**
1719    * checks if user has permission to add nt:file to node
1720    * @throws Exception
1721    */
1722   public boolean canAddNode(Node node) throws Exception {
1723     if (node == null || !PermissionUtil.canAddNode(node) || !node.isCheckedOut()) {
1724       return false;
1725     }
1726     if (node.isLocked()) {
1727       //check for lock
1728       String lockToken = LockUtil.getLockTokenOfUser(node);
1729       if(lockToken == null) {
1730         return false;
1731       }
1732     }
1733     LinkManager linkManager = WCMCoreUtils.getService(LinkManager.class);
1734     if(linkManager.isLink(node)) {
1735       try {
1736         linkManager.getTarget(node);
1737       } catch(ItemNotFoundException ine) {
1738         return false;
1739       }
1740     }
1741     List<NodeDefinition> defs = new ArrayList<NodeDefinition>();
1742     if(node.getPrimaryNodeType().getChildNodeDefinitions() != null) {
1743       defs.addAll(Arrays.asList(node.getPrimaryNodeType().getChildNodeDefinitions()));
1744     }
1745     for (NodeType mix : node.getMixinNodeTypes()) {
1746       if(mix.getChildNodeDefinitions() != null) {
1747         defs.addAll(Arrays.asList(mix.getChildNodeDefinitions()));
1748       }
1749     }
1750     for (NodeDefinition def : defs) {
1751       for (NodeType type : def.getRequiredPrimaryTypes()) {
1752         if ((NodetypeConstant.NT_FILE.equals(type.getName()) ||
1753              NodetypeConstant.NT_BASE.equals(type.getName()) ||
1754              NodetypeConstant.NT_HIERARCHY_NODE.equals(type.getName())) &&
1755             "*".equals(def.getName())) {
1756           return true;
1757         }
1758       }
1759     }
1760     return false;
1761   }
1762 
1763   public String getDragAndDropEvents(Node node) throws Exception{
1764     //define events for drag&drop files into subfolders
1765 //    if (this.canAddNode(node)) {
1766     StringBuilder dragEvents = new StringBuilder().append("ondragover='eXo.ecm.MultiUpload.enableDragItemArea(event, this)' ").
1767                                                     append("ondragleave='eXo.ecm.MultiUpload.disableDragItemArea(this)' ").
1768                                                     append("ondragend='eXo.ecm.MultiUpload.disableDragItemArea(this)' ").
1769                                                     append("onmouseout='eXo.ecm.MultiUpload.disableDragItemArea(this)' ");
1770     //add ondrop event
1771       dragEvents.append("ondrop='eXo.ecm.MultiUpload.doDropItemArea(event, this,\"").
1772                  append(node.getPath()).append("\")' ");
1773       return dragEvents.toString();
1774 //    } else {
1775 //      return "";
1776 //    }
1777   }
1778 
1779   @Override
1780   public void processRender(WebuiRequestContext context) throws Exception {
1781     if(!context.useAjax()) updatePageListData();
1782     //check if current user can add node to current node
1783     //for MuiltUpload drag&drop feature
1784     if (canAddNode()) {
1785       context.getJavascriptManager().require("SHARED/multiUpload", "multiUpload").
1786               addScripts("multiUpload.registerEvents('" + this.getId() +"');");
1787     } else {
1788       context.getJavascriptManager().require("SHARED/multiUpload", "multiUpload").
1789               addScripts("multiUpload.unregisterEvents();");
1790     }
1791     super.processRender(context);
1792   }
1793 
1794   public boolean hasChildren(Node node) {
1795     return false;
1796   }
1797 
1798   public List<Node> getChildrenFromNode(Node node) {
1799     return null;
1800   }
1801   
1802   /** get node attribute in Icons View and Web View **/
1803   public String getNodeAttributeInView(Node node) throws Exception {
1804     String preferenceWS = node.getSession().getWorkspace().getName();
1805     String attr = getNodeAttributeInCommon(node);
1806     StringBuilder builder = new StringBuilder(attr);
1807     String rightClickMenu = "";
1808     // right click menu in Icon View
1809     if(!isSystemWorkspace()) 
1810         rightClickMenu = "" + getContextMenu().getJSOnclickShowPopup(preferenceWS + ":" + Utils.formatNodeName(node.getPath()), getActionsList(node));
1811     
1812     builder.append(rightClickMenu);
1813     return builder.toString();
1814   }
1815   
1816   /** get node attribute in Admin View **/
1817   public String getNodeAttribute(Node node) throws Exception {
1818     StringBuilder builder = new StringBuilder();
1819     String preferenceWS = node.getSession().getWorkspace().getName();
1820     
1821     builder.append(getNodeAttributeInCommon(node));
1822     
1823     // right click menu in Admin View
1824     if (!isSystemWorkspace()) {
1825       builder.append(" onmousedown=\"eXo.ecm.UIFileView.clickRightMouse(event, this, 'ECMContextMenu','");
1826       builder.append(preferenceWS + ":");
1827       builder.append(Utils.formatNodeName(node.getPath()) + "','" );
1828       builder.append(getActionsList(node) + "');\"");
1829     }
1830     return builder.toString();
1831   }
1832   
1833   /** get Attribute in common. */
1834   private String getNodeAttributeInCommon(Node node) throws Exception {
1835     StringBuilder builder = new StringBuilder();
1836     String preferenceWS = node.getSession().getWorkspace().getName();
1837     
1838     // drag and drop events
1839     builder.append(" " + getDragAndDropEvents(node));
1840     // in common
1841     builder.append(" trashHome='" + Utils.isTrashHomeNode(node) + "' "); 
1842     builder.append(" locked='" + node.isLocked() + "' ");
1843     builder.append(" mediaType='" + isMediaType(node) + "' ");
1844     builder.append(" removeFavourite='" + isFavouriter(node) + "' ");
1845     builder.append(" inTrash='" + node.isNodeType("exo:restoreLocation") + "' ");
1846     builder.append(" workspacename='" + preferenceWS + "' ");
1847     builder.append(" objectId='" + org.exoplatform.services.cms.impl.Utils.getObjectId(node.getPath()) + "' ");
1848     builder.append(" isFile='" + node.isNodeType("nt:file") + "' ");
1849     builder.append(" isLinkWithTarget='" + Utils.targetNodeAndLinkInTrash(node) + "' ");
1850     builder.append(" isAbleToRestore='" + Utils.isAbleToRestore(node) + "' ");
1851     builder.append(" isExoAction='" + (Utils.EXO_ACTIONS.equals(node.getName()) && Utils.isInTrash(node)) + "' ");
1852     builder.append(" isCheckedIn='" + !node.isCheckedOut() + "' ");
1853 
1854     return builder.toString();
1855   }
1856   
1857   public UIPopupContainer getPopupContainer() throws Exception {
1858     return this.getAncestorOfType(UIJCRExplorer.class).getChild(UIPopupContainer.class);
1859   }
1860 }