1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.exoplatform.ecm.webui.component.explorer;
18
19 import org.apache.commons.lang.StringUtils;
20 import org.exoplatform.commons.utils.*;
21 import org.exoplatform.ecm.jcr.model.Preference;
22 import org.exoplatform.ecm.webui.component.explorer.control.action.ManageVersionsActionComponent;
23 import org.exoplatform.ecm.webui.component.explorer.versions.UIActivateVersion;
24 import org.exoplatform.ecm.webui.component.explorer.versions.UIVersionInfo;
25 import org.exoplatform.ecm.webui.utils.JCRExceptionManager;
26 import org.exoplatform.ecm.webui.utils.Utils;
27 import org.exoplatform.portal.webui.util.Util;
28 import org.exoplatform.portal.webui.workspace.UIPortalApplication;
29 import org.exoplatform.services.cms.documents.VersionHistoryUtils;
30 import org.exoplatform.services.cms.link.*;
31 import org.exoplatform.services.log.ExoLogger;
32 import org.exoplatform.services.log.Log;
33 import org.exoplatform.services.security.ConversationState;
34 import org.exoplatform.services.security.IdentityConstants;
35 import org.exoplatform.services.wcm.core.NodeLocation;
36 import org.exoplatform.services.wcm.core.NodetypeConstant;
37 import org.exoplatform.services.wcm.utils.WCMCoreUtils;
38 import org.exoplatform.web.application.ApplicationMessage;
39 import org.exoplatform.web.application.RequestContext;
40 import org.exoplatform.webui.config.annotation.ComponentConfig;
41 import org.exoplatform.webui.config.annotation.EventConfig;
42 import org.exoplatform.webui.core.*;
43 import org.exoplatform.webui.event.Event;
44 import org.exoplatform.webui.event.EventListener;
45
46 import javax.jcr.*;
47 import java.text.DateFormat;
48 import java.text.SimpleDateFormat;
49 import java.util.*;
50
51
52
53
54
55
56
57 @ComponentConfig (
58 template = "app:/groovy/webui/component/explorer/UIDocumentNodeList.gtmpl",
59 events = {
60 @EventConfig(listeners = UIDocumentNodeList.ExpandNodeActionListener.class),
61 @EventConfig(listeners = UIDocumentNodeList.CollapseNodeActionListener.class),
62 @EventConfig(listeners = UIDocumentNodeList.ManageVersionsActionListener.class),
63 @EventConfig(listeners = UIDocumentNodeList.MoreActionListener.class)
64 }
65 )
66 public class UIDocumentNodeList extends UIContainer {
67
68 private static final Log LOG = ExoLogger.getLogger(UIDocumentNodeList.class.getName());
69
70 private UIPageIterator pageIterator_;
71
72 private LinkManager linkManager_;
73
74 private List dataList_;
75
76 private int padding_;
77
78 private boolean showMoreButton_ = true;
79
80 public UIDocumentNodeList() throws Exception {
81 linkManager_ = WCMCoreUtils.getService(LinkManager.class);
82 addChild(ManageVersionsActionComponent.class, null, null);
83 pageIterator_ = addChild(UIPageIterator.class, null, "UIDocumentNodeListPageIterator");
84 padding_ = 0;
85 }
86
87 @SuppressWarnings("unchecked")
88 public List<Node> getNodeChildrenList() throws Exception {
89 return NodeLocation.getNodeListByLocationList(showMoreButton_ ? dataList_ : pageIterator_.getCurrentPageData());
90 }
91
92 public void setPageList(PageList p) throws Exception {
93 pageIterator_.setPageList(p);
94 dataList_ = new ArrayList();
95 if (p != null && p.getAvailable() > 0) {
96 dataList_.addAll(p.getPage(1));
97 }
98 updateUIDocumentNodeListChildren();
99 }
100
101 public int getPadding() { return padding_; }
102 public void setPadding(int value) { padding_ = value; }
103
104 public boolean isShowMoreButton() {
105 return showMoreButton_ && (pageIterator_ != null) &&
106 (pageIterator_.getPageList() != null) &&
107 (dataList_ != null) && (dataList_.size() < pageIterator_.getPageList().getAvailable());
108 }
109 public void setShowMoreButton(boolean value) { showMoreButton_ = value; }
110
111 public void setCurrentNode(Node node) throws Exception {
112 setPageList(this.getPageList(node.getPath()));
113 }
114
115 public void updateUIDocumentNodeListChildren() throws Exception {
116 Set<String> ids = new HashSet<String>();
117
118 for (UIComponent component : getChildren()) {
119 if (component instanceof UIDocumentNodeList) {
120 ids.add(component.getId());
121 }
122 }
123
124 for (String id : ids) {
125 this.removeChildById(id);
126 }
127
128 for (Node node : getNodeChildrenList()) {
129 if (node instanceof NodeLinkAware) {
130 node = ((NodeLinkAware)node).getRealNode();
131 }
132 try {
133 Node targetNode = linkManager_.isLink(node) ? linkManager_.getTarget(node) : node;
134 if (targetNode.isNodeType(NodetypeConstant.NT_FOLDER) || targetNode.isNodeType(NodetypeConstant.NT_UNSTRUCTURED)) {
135 addUIDocList(getID(node));
136 }
137 } catch(ItemNotFoundException ine) {
138 continue;
139 }
140 }
141 }
142
143 public UIPageIterator getContentPageIterator() {
144 return pageIterator_;
145 }
146
147 public String getID(Node node) throws Exception {
148 return this.getAncestorOfType(UIDocumentInfo.class).getClass().getSimpleName() +
149 this.getClass().getSimpleName() + String.valueOf(Math.abs(node.getPath().hashCode()));
150 }
151
152 public UIComponent addUIDocList(String id) throws Exception {
153 UIDocumentNodeList child = addChild(UIDocumentNodeList.class, null, id);
154 child.setPadding(padding_ + 1);
155 child.getContentPageIterator().setId(child.getId() + "PageIterator");
156 return child;
157 }
158
159
160
161
162
163
164
165
166 public String getFileName(Node file, String title) throws Exception {
167 if (!file.isNodeType(NodetypeConstant.NT_FILE) || title == null) {
168 return title;
169 } else {
170 int index = title.lastIndexOf('.');
171 if (index != -1) {
172 return title.substring(0, index);
173 } else {
174 return title;
175 }
176 }
177 }
178
179
180
181
182
183
184
185
186 public String getFileExtension(Node file, String title) throws Exception {
187 if (!file.isNodeType(NodetypeConstant.NT_FILE) || title == null) {
188 return "";
189 } else {
190 int index = title.lastIndexOf('.');
191 if (index != -1) {
192 return title.substring(index);
193 } else {
194 return "";
195 }
196 }
197 }
198
199
200
201
202
203
204
205 public String getFileDate(Node file) throws Exception {
206 String createdDate = this.getDatePropertyValue(file, NodetypeConstant.EXO_DATE_CREATED);
207 String modifiedDate = this.getDatePropertyValue(file, NodetypeConstant.EXO_LAST_MODIFIED_DATE);
208 return StringUtils.isEmpty(modifiedDate) ||
209 equalDates(file, NodetypeConstant.EXO_DATE_CREATED, NodetypeConstant.EXO_LAST_MODIFIED_DATE)?
210 getLabel("CreatedOn") + " " + createdDate : getLabel("Updated") + " " + modifiedDate;
211 }
212
213 private boolean equalDates(Node node, String p1, String p2) {
214 Calendar pr1 = null;
215 Calendar pr2 = null;
216 try {
217 pr1 = node.getProperty(p1).getDate();
218 } catch (PathNotFoundException e) {
219 pr1 = null;
220 } catch (ValueFormatException e) {
221 pr1 = null;
222 } catch (RepositoryException e) {
223 pr1 = null;
224 }
225 try {
226 pr2 = node.getProperty(p2).getDate();
227 } catch (PathNotFoundException e) {
228 pr2 = null;
229 } catch (ValueFormatException e) {
230 pr2 = null;
231 } catch (RepositoryException e) {
232 pr2 = null;
233 }
234 if ((pr1 == null) && (pr2 == null)) return true;
235 if ((pr1 == null) || (pr2 == null)) return false;
236 return Math.abs(pr1.getTimeInMillis() - pr2.getTimeInMillis()) < 3000;
237 }
238
239 public String getDatePropertyValue(Node node, String propertyName) throws Exception {
240 try {
241 Property property = node.getProperty(propertyName);
242 if(property != null) {
243 Locale locale = Util.getUIPortal().getAncestorOfType(UIPortalApplication.class).getLocale();
244 DateFormat dateFormat = SimpleDateFormat.getDateInstance(SimpleDateFormat.SHORT, locale);
245 return dateFormat.format(property.getDate().getTime());
246 }
247 } catch(PathNotFoundException PNE) {
248 return "";
249 }
250 return "";
251 }
252
253
254
255
256
257
258 public String getLabel(String id) {
259 RequestContext context = RequestContext.getCurrentInstance();
260 ResourceBundle res = context.getApplicationResourceBundle();
261 try {
262 return res.getString("UIDocumentNodeList.label." + id);
263 } catch (MissingResourceException ex) {
264 return id;
265 }
266 }
267
268
269
270
271
272
273 protected String getVersionNumber(Node file) throws Exception {
274 String currentVersion = null;
275 if (file.isNodeType(NodetypeConstant.MIX_VERSIONABLE)){
276 try {
277 if (file.isNodeType(VersionHistoryUtils.MIX_DISPLAY_VERSION_NAME) &&
278 file.hasProperty(VersionHistoryUtils.MAX_VERSION_PROPERTY)) {
279
280 int max = (int) file.getProperty(VersionHistoryUtils.MAX_VERSION_PROPERTY).getLong();
281 currentVersion = String.valueOf(max-1);
282 }else {
283 currentVersion = file.getBaseVersion().getName();
284 if (currentVersion.contains("jcr:rootVersion")) currentVersion = "0";
285 }
286 }catch (Exception e) {
287 currentVersion ="0";
288 }
289 return "V"+currentVersion;
290 }
291 return "";
292 }
293
294
295 public String getAuthorName(Node file) throws Exception {
296 String userName = getAncestorOfType(UIDocumentInfo.class).getPropertyValue(file, NodetypeConstant.EXO_LAST_MODIFIER);
297 if (StringUtils.isEmpty(userName) || IdentityConstants.SYSTEM.equals(userName)) {
298 return StringUtils.EMPTY;
299 }
300 return String.format("%s %s",
301 getLabel("by"),
302 userName.equals(ConversationState.getCurrent().getIdentity().getUserId()) ? getLabel("you") : userName);
303 }
304 public String getFileSize(Node file) throws Exception {
305 return org.exoplatform.services.cms.impl.Utils.fileSize(file);
306 }
307
308 @SuppressWarnings("unchecked")
309 private PageList<Object> getPageList(String path) throws Exception {
310 UIJCRExplorer uiExplorer = this.getAncestorOfType(UIJCRExplorer.class);
311 Preference pref = uiExplorer.getPreference();
312
313 DocumentProviderUtils docProviderUtil = DocumentProviderUtils.getInstance();
314 if (docProviderUtil.canSortType(pref.getSortType()) && uiExplorer.getAllItemByTypeFilterMap().isEmpty()) {
315 return docProviderUtil.getPageList(
316 uiExplorer.getWorkspaceName(),
317 path,
318 pref,
319 uiExplorer.getAllItemFilterMap(),
320 uiExplorer.getAllItemByTypeFilterMap(),
321 (NodeLinkAware) ItemLinkAware.newInstance(uiExplorer.getWorkspaceName(), path,
322 uiExplorer.getNodeByPath(path, uiExplorer.getSystemSession())));
323
324 }
325
326 List<Node> nodeList = null;
327
328 UIDocumentInfo uiDocInfo = this.getAncestorOfType(UIDocumentInfo.class);
329 int nodesPerPage = pref.getNodesPerPage();
330
331 Set<String> allItemByTypeFilterMap = uiExplorer.getAllItemByTypeFilterMap();
332 if (allItemByTypeFilterMap.size() > 0)
333 nodeList = uiDocInfo.filterNodeList(uiExplorer.getChildrenList(path, !pref.isShowPreferenceDocuments()));
334 else
335 nodeList = uiDocInfo.filterNodeList(uiExplorer.getChildrenList(path, pref.isShowPreferenceDocuments()));
336
337 ListAccess<Object> nodeAccList =
338 new ListAccessImpl<Object>(Object.class, NodeLocation.getLocationsByNodeList(nodeList));
339 return new LazyPageList<Object>(nodeAccList, nodesPerPage);
340 }
341
342 static public class ExpandNodeActionListener extends EventListener<UIDocumentNodeList> {
343 public void execute(Event<UIDocumentNodeList> event) throws Exception {
344 UIDocumentNodeList uicomp = event.getSource();
345
346 NodeFinder nodeFinder = uicomp.getApplicationComponent(NodeFinder.class);
347 String uri = event.getRequestContext().getRequestParameter(OBJECTID);
348 String workspaceName = event.getRequestContext().getRequestParameter("workspaceName");
349 UIApplication uiApp = uicomp.getAncestorOfType(UIApplication.class);
350 try {
351
352 uri = LinkUtils.evaluatePath(uri);
353
354 Item item = nodeFinder.getItem(workspaceName, uri);
355 if ((item instanceof Node) && Utils.isInTrash((Node) item)) {
356 return;
357 }
358
359 Node clickedNode = (Node)item;
360
361
362 UIDocumentNodeList uiDocNodeListChild = uicomp.getChildById(uicomp.getID(clickedNode));
363 uiDocNodeListChild.setCurrentNode(clickedNode);
364 uicomp.getAncestorOfType(UIDocumentInfo.class).getExpandedFolders().add(uri);
365 event.getRequestContext().addUIComponentToUpdateByAjax(uiDocNodeListChild);
366 } catch(ItemNotFoundException nu) {
367 uiApp.addMessage(new ApplicationMessage("UIDocumentInfo.msg.null-exception", null, ApplicationMessage.WARNING)) ;
368
369 return ;
370 } catch(PathNotFoundException pa) {
371 uiApp.addMessage(new ApplicationMessage("UIDocumentInfo.msg.path-not-found", null, ApplicationMessage.WARNING)) ;
372
373 return ;
374 } catch(AccessDeniedException ace) {
375 uiApp.addMessage(new ApplicationMessage("UIDocumentInfo.msg.access-denied", null, ApplicationMessage.WARNING)) ;
376
377 return ;
378 } catch(RepositoryException e) {
379 if (LOG.isErrorEnabled()) {
380 LOG.error("Repository cannot be found");
381 }
382 uiApp.addMessage(new ApplicationMessage("UIDocumentInfo.msg.repository-error", null,
383 ApplicationMessage.WARNING)) ;
384
385 return ;
386 } catch (Exception e) {
387 JCRExceptionManager.process(uiApp, e);
388 return;
389 }
390 }
391 }
392
393 static public class CollapseNodeActionListener extends EventListener<UIDocumentNodeList> {
394 public void execute(Event<UIDocumentNodeList> event) throws Exception {
395 UIDocumentNodeList uicomp = event.getSource();
396
397 NodeFinder nodeFinder = uicomp.getApplicationComponent(NodeFinder.class);
398 String uri = event.getRequestContext().getRequestParameter(OBJECTID);
399 String workspaceName = event.getRequestContext().getRequestParameter("workspaceName");
400 UIApplication uiApp = uicomp.getAncestorOfType(UIApplication.class);
401 try {
402
403 uri = LinkUtils.evaluatePath(uri);
404
405 Item item = nodeFinder.getItem(workspaceName, uri);
406 if ((item instanceof Node) && Utils.isInTrash((Node) item)) {
407 return;
408 }
409 Node clickedNode = (Node)item;
410 UIDocumentNodeList uiDocNodeListChild = uicomp.getChildById(uicomp.getID(clickedNode));
411 uiDocNodeListChild.setPageList(EmptySerializablePageList.get());
412 uicomp.getAncestorOfType(UIDocumentInfo.class).getExpandedFolders().remove(uri);
413 event.getRequestContext().addUIComponentToUpdateByAjax(uiDocNodeListChild);
414 } catch(ItemNotFoundException nu) {
415 uiApp.addMessage(new ApplicationMessage("UIDocumentInfo.msg.null-exception", null, ApplicationMessage.WARNING)) ;
416 return ;
417 } catch(PathNotFoundException pa) {
418 uiApp.addMessage(new ApplicationMessage("UIDocumentInfo.msg.path-not-found", null, ApplicationMessage.WARNING)) ;
419 return ;
420 } catch(AccessDeniedException ace) {
421 uiApp.addMessage(new ApplicationMessage("UIDocumentInfo.msg.access-denied", null, ApplicationMessage.WARNING)) ;
422 return ;
423 } catch(RepositoryException e) {
424 if (LOG.isErrorEnabled()) {
425 LOG.error("Repository cannot be found");
426 }
427 uiApp.addMessage(new ApplicationMessage("UIDocumentInfo.msg.repository-error", null,
428 ApplicationMessage.WARNING)) ;
429 return ;
430 } catch (Exception e) {
431 JCRExceptionManager.process(uiApp, e);
432 return;
433 }
434 }
435 }
436
437
438 public static class ManageVersionsActionListener extends EventListener<UIDocumentNodeList> {
439 public void execute(Event<UIDocumentNodeList> event) throws Exception {
440 NodeFinder nodeFinder = event.getSource().getApplicationComponent(NodeFinder.class);
441 UIJCRExplorer uiExplorer = event.getSource().getAncestorOfType(UIJCRExplorer.class);
442 UIPopupContainer UIPopupContainer = uiExplorer.getChild(UIPopupContainer.class);
443 String uri = event.getRequestContext().getRequestParameter(OBJECTID);
444 String workspaceName = event.getRequestContext().getRequestParameter("workspaceName");
445
446 uri = LinkUtils.evaluatePath(uri);
447
448 Node currentNode = (Node)nodeFinder.getItem(workspaceName, uri);
449 uiExplorer.setIsHidePopup(false);
450 if (currentNode.canAddMixin(Utils.MIX_VERSIONABLE)) {
451 UIPopupContainer.activate(UIActivateVersion.class, 400);
452 event.getRequestContext().addUIComponentToUpdateByAjax(UIPopupContainer);
453 } else if (currentNode.isNodeType(Utils.MIX_VERSIONABLE)) {
454 UIWorkingArea uiWorkingArea = uiExplorer.getChild(UIWorkingArea.class);
455 UIDocumentWorkspace uiDocumentWorkspace = uiWorkingArea.getChild(UIDocumentWorkspace.class);
456 UIVersionInfo uiVersionInfo = uiDocumentWorkspace.getChild(UIVersionInfo.class);
457 uiVersionInfo.setCurrentNode(currentNode);
458 uiVersionInfo.setRootOwner(currentNode.getProperty("exo:lastModifier").getString());
459 uiVersionInfo.activate();
460 uiDocumentWorkspace.setRenderedChild(UIVersionInfo.class);
461 event.getRequestContext().addUIComponentToUpdateByAjax(uiDocumentWorkspace);
462 }
463 }
464 }
465
466 public static class MoreActionListener extends EventListener<UIDocumentNodeList> {
467 public void execute(Event<UIDocumentNodeList> event) throws Exception {
468 UIDocumentNodeList uicomp = event.getSource();
469
470 UIApplication uiApp = uicomp.getAncestorOfType(UIApplication.class);
471 try {
472 int currentPage = uicomp.dataList_.size() / uicomp.pageIterator_.getPageList().getPageSize();
473 uicomp.dataList_.addAll(uicomp.pageIterator_.getPageList().getPage(currentPage + 1));
474 event.getRequestContext().addUIComponentToUpdateByAjax(uicomp);
475 } catch(AccessDeniedException ace) {
476 uiApp.addMessage(new ApplicationMessage("UIDocumentInfo.msg.access-denied", null, ApplicationMessage.WARNING)) ;
477 return ;
478 } catch(RepositoryException e) {
479 if (LOG.isErrorEnabled()) {
480 LOG.error("Repository cannot be found");
481 }
482 uiApp.addMessage(new ApplicationMessage("UIDocumentInfo.msg.repository-error", null,
483 ApplicationMessage.WARNING)) ;
484 return ;
485 } catch (Exception e) {
486 JCRExceptionManager.process(uiApp, e);
487 return;
488 }
489 }
490 }
491
492 }