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 java.util.ArrayList;
20 import java.util.Collections;
21 import java.util.HashMap;
22 import java.util.List;
23 import java.util.Map;
24 import java.util.regex.Pattern;
25
26 import javax.jcr.ItemNotFoundException;
27 import javax.jcr.Node;
28 import javax.jcr.PathNotFoundException;
29 import javax.jcr.RepositoryException;
30 import javax.jcr.Session;
31 import javax.jcr.Value;
32
33 import org.apache.commons.lang.StringUtils;
34 import org.exoplatform.ecm.webui.component.explorer.control.UIActionBar;
35 import org.exoplatform.ecm.webui.component.explorer.popup.actions.UIDocumentFormController;
36 import org.exoplatform.ecm.webui.component.explorer.popup.actions.UISelectDocumentForm;
37 import org.exoplatform.ecm.webui.component.explorer.rightclick.manager.RestoreFromTrashManageComponent;
38 import org.exoplatform.ecm.webui.component.explorer.sidebar.UISideBar;
39 import org.exoplatform.ecm.webui.component.explorer.sidebar.UITreeExplorer;
40 import org.exoplatform.ecm.webui.utils.Utils;
41 import org.exoplatform.services.cms.actions.ActionServiceContainer;
42 import org.exoplatform.services.cms.link.NodeFinder;
43 import org.exoplatform.services.cms.link.NodeLinkAware;
44 import org.exoplatform.services.jcr.RepositoryService;
45 import org.exoplatform.services.jcr.core.ManageableRepository;
46 import org.exoplatform.services.log.ExoLogger;
47 import org.exoplatform.services.log.Log;
48 import org.exoplatform.services.security.Identity;
49 import org.exoplatform.services.security.IdentityConstants;
50 import org.exoplatform.services.security.IdentityRegistry;
51 import org.exoplatform.services.security.MembershipEntry;
52 import org.exoplatform.services.wcm.utils.WCMCoreUtils;
53 import org.exoplatform.webui.application.WebuiRequestContext;
54 import org.exoplatform.webui.config.annotation.ComponentConfig;
55 import org.exoplatform.webui.config.annotation.ComponentConfigs;
56 import org.exoplatform.webui.config.annotation.EventConfig;
57 import org.exoplatform.webui.core.UIApplication;
58 import org.exoplatform.webui.core.UIComponent;
59 import org.exoplatform.webui.core.UIContainer;
60 import org.exoplatform.webui.core.UIRightClickPopupMenu;
61 import org.exoplatform.webui.event.Event;
62 import org.exoplatform.webui.event.EventListener;
63 import org.exoplatform.webui.ext.UIExtension;
64 import org.exoplatform.webui.ext.UIExtensionManager;
65 import org.exoplatform.webui.ext.manager.UIAbstractManagerComponent;
66
67
68
69
70
71
72 @ComponentConfigs( {
73 @ComponentConfig(template = "app:/groovy/webui/component/explorer/UIWorkingArea.gtmpl",
74 events = {@EventConfig(listeners = UIWorkingArea.RefreshActionListener.class)}),
75 @ComponentConfig(
76 type = UIRightClickPopupMenu.class,
77 id = "ECMContextMenu",
78 template = "app:/groovy/webui/component/explorer/UIRightClickPopupMenu.gtmpl"
79 )
80 })
81 public class UIWorkingArea extends UIContainer {
82
83
84
85
86 private static final Log LOG = ExoLogger.getLogger(UIWorkingArea.class.getName());
87
88 public static final Pattern FILE_EXPLORER_URL_SYNTAX = Pattern.compile("([^:/]+):(/.*)");
89
90 public static final String WS_NAME = "workspaceName";
91
92 public static final String EXTENSION_TYPE = "org.exoplatform.ecm.dms.UIWorkingArea";
93
94 public static final String ITEM_CONTEXT_MENU = "ItemContextMenu";
95
96 public static final String MULTI_ITEM_CONTEXT_MENU = "MultiItemContextMenu";
97
98 public static final String GROUND_CONTEXT_MENU = "GroundContextMenu";
99
100 public static final String ITEM_GROUND_CONTEXT_MENU = "ItemGroundContextMenu";
101
102 public static final String MOVE_NODE = "MoveNode";
103
104 public static final String CREATE_LINK = "CreateLink";
105
106 public static final String CUSTOM_ACTIONS = "CustomActions";
107
108 public static final String PERMLINK = "PermlinkContextMenu";
109 public static final String PERM_LINK_ACTION = "Permlink";
110
111 private String nodePathDelete = "";
112 private String deleteNotice = "";
113 private String wcmNotice = "";
114
115 public void setNodePathDelete(String nodePathDelete) {
116 this.nodePathDelete = nodePathDelete;
117 }
118
119 public String getNodePathDelete() {
120 return nodePathDelete;
121 }
122
123 public String getWCMNotice() {
124 return wcmNotice;
125 }
126
127 public void setWCMNotice(String wcmNotice) {
128 this.wcmNotice = wcmNotice;
129 }
130
131 public void setDeleteNotice(String deleteNotice) {
132 this.deleteNotice = deleteNotice;
133 }
134
135 public String getDeleteNotice() {
136 return this.deleteNotice;
137 }
138
139 public static final String REFRESH_ACTION = "Refresh";
140
141 public static final String RENAME_ACTION = "Rename";
142
143
144 private List<UIAbstractManagerComponent> managers =
145 Collections.synchronizedList(new ArrayList<UIAbstractManagerComponent>());
146
147 public UIWorkingArea() throws Exception {
148 addChild(UIRightClickPopupMenu.class, "ECMContextMenu", null);
149 addChild(UISideBar.class, null, null);
150 addChild(UIActionBar.class, null, null) ;
151 addChild(UISelectDocumentTemplateTitle.class, null, null);
152 addChild(UIDocumentWorkspace.class, null, null);
153 addChild(UIDrivesArea.class, null, null).setRendered(false);
154 }
155
156 private List<UIExtension> getUIExtensionList() {
157 UIExtensionManager manager = getApplicationComponent(UIExtensionManager.class);
158 return manager.getUIExtensions(EXTENSION_TYPE);
159 }
160
161 public synchronized UITreeExplorer getTreeExplorer() {
162 UISideBar uiSideBar = getChild(UISideBar.class);
163 return uiSideBar.getChild(UITreeExplorer.class);
164 }
165
166 public void initialize() throws Exception {
167 List<UIExtension> extensions = getUIExtensionList();
168 if (extensions == null) {
169 return;
170 }
171 managers.clear();
172 for (UIExtension extension : extensions) {
173 UIComponent component = addUIExtension(extension, null);
174 if (component !=null && !managers.contains(component))
175 managers.add((UIAbstractManagerComponent)component);
176 }
177 }
178
179 private UIComponent addUIExtension(UIExtension extension, Map<String, Object> context) throws Exception {
180 UIExtensionManager manager = getApplicationComponent(UIExtensionManager.class);
181 UIComponent component = manager.addUIExtension(extension, context, this);
182 if(component == null) return null;
183 synchronized(component) {
184 if (component instanceof UIAbstractManagerComponent) {
185
186 UIAbstractManagerComponent uiAbstractManagerComponent = (UIAbstractManagerComponent) component;
187 uiAbstractManagerComponent.setUIExtensionName(extension.getName());
188 uiAbstractManagerComponent.setUIExtensionCategory(extension.getCategory());
189 return component;
190 } else if (component != null) {
191
192 if (LOG.isWarnEnabled()) {
193 LOG.warn("All the extension '" + extension.getName() + "' of type '" + EXTENSION_TYPE
194 + "' must be associated to a component of type " + UIAbstractManagerComponent.class);
195 }
196 removeChild(component.getClass());
197 }
198 }
199 return null;
200 }
201
202 public RestoreFromTrashManageComponent getThrashManageComponent(){
203 for(UIAbstractManagerComponent c : getManagers()){
204 if(c instanceof RestoreFromTrashManageComponent){
205 return (RestoreFromTrashManageComponent)c;
206 }
207 }
208 return null;
209 }
210 public List<UIAbstractManagerComponent> getManagers() {
211 List<UIAbstractManagerComponent> managers = new ArrayList<UIAbstractManagerComponent>();
212 managers.addAll(this.managers);
213 return managers;
214 }
215
216 public void unregister(UIAbstractManagerComponent component) {
217 managers.remove(component);
218 }
219
220
221 public boolean isShowSideBar() throws Exception {
222 UIJCRExplorer jcrExplorer = getParent();
223 return jcrExplorer.getPreference().isShowSideBar() && getAncestorOfType(UIJCRExplorerPortlet.class).isShowSideBar();
224 }
225
226 public void setShowSideBar(boolean b) throws Exception {
227 UIJCRExplorer jcrExplorer = getParent();
228 jcrExplorer.getPreference().setShowSideBar(b);
229 }
230
231 public Node getNodeByUUID(String uuid) throws Exception {
232 ManageableRepository repo = getApplicationComponent(RepositoryService.class).getCurrentRepository();
233 String workspace = repo.getConfiguration().getDefaultWorkspaceName();
234 return getNodeByUUID(uuid, workspace);
235 }
236
237 public Node getNodeByUUID(String uuid, String workspaceName) throws Exception {
238 ManageableRepository repo = getApplicationComponent(RepositoryService.class).getCurrentRepository();
239 Session session = WCMCoreUtils.getSystemSessionProvider().getSession(workspaceName, repo);
240 return session.getNodeByUUID(uuid);
241 }
242
243 public boolean isPreferenceNode(Node node) {
244 return getAncestorOfType(UIJCRExplorer.class).isPreferenceNode(node);
245 }
246
247 public String getVersionNumber(Node node) throws RepositoryException {
248 if (!Utils.isVersionable(node))
249 return "-";
250 return node.getBaseVersion().getName();
251 }
252
253 public boolean isJcrViewEnable() throws Exception {
254 UIJCRExplorer uiExplorer = getAncestorOfType(UIJCRExplorer.class);
255 return uiExplorer.getPreference().isJcrEnable();
256 }
257
258 private Map<String, Object> createContext(Node currentNode) throws Exception {
259 Map<String, Object> context = new HashMap<String, Object>();
260 WebuiRequestContext requestContext = WebuiRequestContext.getCurrentInstance() ;
261 UIJCRExplorer uiExplorer = getAncestorOfType(UIJCRExplorer.class);
262 UIApplication uiApp = getAncestorOfType(UIApplication.class);
263 context.put(Node.class.getName(), currentNode);
264 context.put(UIWorkingArea.class.getName(), this);
265 context.put(UIApplication.class.getName(), uiApp);
266 context.put(UIJCRExplorer.class.getName(), uiExplorer);
267 context.put(WebuiRequestContext.class.getName(), requestContext);
268 return context;
269 }
270
271 List<UIComponent> getGroundActionsExtensionList() throws Exception {
272 List<UIComponent> uiGroundActionList = new ArrayList<UIComponent>();
273 List<UIExtension> uiExtensionList = getUIExtensionList();
274 UIJCRExplorer uiExplorer = getAncestorOfType(UIJCRExplorer.class);
275 Node currentNode = uiExplorer.getCurrentNode();
276 UIComponent uiAddedActionManage;
277 for (UIExtension uiextension : uiExtensionList) {
278 if (GROUND_CONTEXT_MENU.equals(uiextension.getCategory())
279 || ITEM_GROUND_CONTEXT_MENU.equals(uiextension.getCategory())) {
280 uiAddedActionManage = addUIExtension(uiextension, createContext(currentNode));
281 if (uiAddedActionManage != null) {
282 if (!uiGroundActionList.contains(uiAddedActionManage))
283 uiGroundActionList.add(uiAddedActionManage);
284 }
285 }
286 }
287 return uiGroundActionList;
288 }
289
290 List<UIComponent> getMultiActionsExtensionList() throws Exception {
291 List<UIComponent> uiActionList = new ArrayList<UIComponent>();
292 List<UIExtension> uiExtensionList = getUIExtensionList();
293 UIComponent uiAddedActionManage;
294 for (UIExtension uiextension : uiExtensionList) {
295 if (ITEM_CONTEXT_MENU.equals(uiextension.getCategory())
296 || ITEM_GROUND_CONTEXT_MENU.equals(uiextension.getCategory())
297 || MULTI_ITEM_CONTEXT_MENU.equals(uiextension.getCategory())) {
298 uiAddedActionManage = addUIExtension(uiextension, null);
299 if (uiAddedActionManage != null) {
300 if (!uiActionList.contains(uiAddedActionManage))
301 uiActionList.add(uiAddedActionManage);
302 }
303 }
304 }
305 return uiActionList;
306 }
307
308 public String getActionsExtensionList(Node node) throws Exception {
309 StringBuffer actionsList = new StringBuffer(1024);
310 List<UIExtension> uiExtensionList = getUIExtensionList();
311 UIComponent uiAddedActionManage;
312 try {
313 NodeFinder nodeFinder = getApplicationComponent(NodeFinder.class);
314 nodeFinder.getItem(getAncestorOfType(UIJCRExplorer.class).getSession(), node.getPath());
315 } catch(PathNotFoundException pne) {
316 return "";
317 }
318 for (UIExtension uiextension : uiExtensionList) {
319 if (uiextension.getCategory().startsWith(ITEM_CONTEXT_MENU)
320 || ITEM_GROUND_CONTEXT_MENU.equals(uiextension.getCategory())) {
321 uiAddedActionManage = addUIExtension(uiextension, createContext(node));
322 if (uiAddedActionManage != null) {
323 actionsList.append(uiextension.getName()).append(",");
324 }
325 }
326 }
327 if (actionsList.length() > 0) {
328 return actionsList.substring(0, actionsList.length() - 1);
329 }
330 return actionsList.toString();
331 }
332
333 public UIComponent getJCRMoveAction() throws Exception {
334 UIExtensionManager manager = getApplicationComponent(UIExtensionManager.class);
335 UIExtension extension = manager.getUIExtension(EXTENSION_TYPE, MOVE_NODE);
336 return addUIExtension(extension, null);
337 }
338
339 public UIComponent getCreateLinkAction() throws Exception {
340 UIExtensionManager manager = getApplicationComponent(UIExtensionManager.class);
341 UIExtension extension = manager.getUIExtension(EXTENSION_TYPE, CREATE_LINK);
342 return addUIExtension(extension, null);
343 }
344
345 public UIComponent getPermlink(Node node) throws Exception {
346 UIComponent uicomponent = null;
347 List<UIExtension> uiExtensionList = getUIExtensionList();
348 for (UIExtension uiextension : uiExtensionList) {
349 if (PERMLINK.equals(uiextension.getCategory())) {
350 uicomponent = addUIExtension(uiextension, createContext(node));
351 }
352 }
353 return uicomponent;
354 }
355
356 public UIComponent getCustomAction() throws Exception {
357 UIComponent uicomponent = null;
358 List<UIExtension> uiExtensionList = getUIExtensionList();
359 for (UIExtension uiextension : uiExtensionList) {
360 if (CUSTOM_ACTIONS.equals(uiextension.getCategory())) {
361 uicomponent = addUIExtension(uiextension, null);
362 }
363 }
364 return uicomponent;
365 }
366
367 private boolean hasPermission(String userName, Value[] roles) throws Exception {
368 IdentityRegistry identityRegistry = getApplicationComponent(IdentityRegistry.class);
369 if (IdentityConstants.SYSTEM.equalsIgnoreCase(userName)) {
370 return true;
371 }
372 Identity identity = identityRegistry.getIdentity(userName);
373 if (identity == null) {
374 return false;
375 }
376 for (int i = 0; i < roles.length; i++) {
377 String role = roles[i].getString();
378 if ("*".equalsIgnoreCase(role))
379 return true;
380 MembershipEntry membershipEntry = MembershipEntry.parse(role);
381 if (membershipEntry == null)
382 return false;
383 if (identity.isMemberOf(membershipEntry)) {
384 return true;
385 }
386 }
387 return false;
388 }
389
390 public List<Node> getCustomActions(Node node) throws Exception {
391 if (node instanceof NodeLinkAware) {
392 NodeLinkAware nodeLA = (NodeLinkAware) node;
393 try {
394 node = nodeLA.getTargetNode().getRealNode();
395 } catch (Exception e) {
396
397 }
398 }
399 List<Node> safeActions = new ArrayList<Node>();
400 WebuiRequestContext context = WebuiRequestContext.getCurrentInstance();
401 String userName = context.getRemoteUser();
402 ActionServiceContainer actionContainer = getApplicationComponent(ActionServiceContainer.class);
403 List<Node> unsafeActions = actionContainer.getCustomActionsNode(node, "read");
404 if (unsafeActions == null)
405 return new ArrayList<Node>();
406 for (Node actionNode : unsafeActions) {
407 Value[] roles = actionNode.getProperty(Utils.EXO_ROLES).getValues();
408 if (hasPermission(userName, roles))
409 safeActions.add(actionNode);
410 }
411 return safeActions;
412 }
413
414
415
416
417
418
419
420
421
422
423 public String getTitle(Node node) throws Exception {
424 return Utils.getTitle(node);
425 }
426
427 public void processRender(WebuiRequestContext context) throws Exception {
428 UIJCRExplorerPortlet uiPortlet = getAncestorOfType(UIJCRExplorerPortlet.class);
429 UIActionBar uiActionBar = findFirstComponentOfType(UIActionBar.class);
430 uiActionBar.setRendered(uiPortlet.isShowActionBar());
431 UISelectDocumentTemplateTitle uiTemplateTitle = findFirstComponentOfType(UISelectDocumentTemplateTitle.class);
432 boolean isUITemplateTitleRendered = isUISelectDocumentTemplateTitleRendered();
433 uiTemplateTitle.setRendered(isUITemplateTitleRendered);
434 if(!context.useAjax()) {
435 if (isShowSideBar()) {
436 UITreeExplorer uiTreeExplorer = this.findFirstComponentOfType(UITreeExplorer.class);
437 if (uiTreeExplorer != null) uiTreeExplorer.buildTree();
438 }
439 }
440 super.processRender(context);
441 }
442
443 public boolean isUISelectDocumentTemplateTitleRendered() {
444 UIDocumentFormController uiDocumentController = findFirstComponentOfType(UIDocumentFormController.class);
445 boolean isUITemplateTitleRendered =
446 (uiDocumentController != null
447 && uiDocumentController.isRendered()
448 && uiDocumentController.getChild(UISelectDocumentForm.class).isRendered());
449 return isUITemplateTitleRendered;
450 }
451
452
453
454
455 public static class RefreshActionListener extends EventListener<UIWorkingArea> {
456 public void execute(Event<UIWorkingArea> event) throws Exception {
457 UIJCRExplorer uiExplorer = event.getSource().getAncestorOfType(UIJCRExplorer.class);
458
459
460 String pathBeforeRename = event.getRequestContext().getRequestParameter("oldPath");
461
462
463 String renamedNodeUUID = event.getRequestContext().getRequestParameter("uuid");
464 String pathAfterRename = null;
465 Node renamedNode = null;
466 try {
467 renamedNode = uiExplorer.getSession().getNodeByUUID(renamedNodeUUID);
468 } catch (ItemNotFoundException e) {
469
470 String[] workspaceNames = uiExplorer.getRepository().getWorkspaceNames();
471 String currentWorkSpaceName = uiExplorer.getWorkspaceName();
472 for (String workspaceName : workspaceNames) {
473 if (!workspaceName.equals(currentWorkSpaceName)) {
474 try {
475 renamedNode = uiExplorer.getSessionByWorkspace(workspaceName).getNodeByUUID(renamedNodeUUID);
476 break;
477 } catch (ItemNotFoundException infE) {
478 renamedNode = null;
479 }
480 }
481 }
482 }
483 if (renamedNode != null) {
484 pathAfterRename = renamedNode.getPath();
485 } else {
486 LOG.warn("Can not find renamed node with old path: [%s]", pathBeforeRename);
487 return;
488 }
489
490
491 String currentPath = uiExplorer.getCurrentPath();
492 if (currentPath.equals(pathBeforeRename)) {
493 uiExplorer.setCurrentPath(pathAfterRename) ;
494 } else if(currentPath.startsWith(pathBeforeRename)) {
495 uiExplorer.setCurrentPath(pathAfterRename + currentPath.replace(pathBeforeRename, StringUtils.EMPTY));
496 }
497 uiExplorer.updateAjax(event);
498 }
499 }
500 }