/* * Copyright (C) 2003-2007 eXo Platform SAS. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU Affero General Public License * as published by the Free Software Foundation; either version 3 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, see<http://www.gnu.org/licenses/>. */ package org.exoplatform.ecm.webui.component.explorer; import java.util.ArrayList; import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.regex.Pattern; import javax.jcr.ItemNotFoundException; import javax.jcr.Node; import javax.jcr.PathNotFoundException; import javax.jcr.RepositoryException; import javax.jcr.Session; import javax.jcr.Value; import org.apache.commons.lang.StringUtils; import org.exoplatform.ecm.webui.component.explorer.control.UIActionBar; import org.exoplatform.ecm.webui.component.explorer.popup.actions.UIDocumentFormController; import org.exoplatform.ecm.webui.component.explorer.popup.actions.UISelectDocumentForm; import org.exoplatform.ecm.webui.component.explorer.rightclick.manager.RestoreFromTrashManageComponent; import org.exoplatform.ecm.webui.component.explorer.sidebar.UISideBar; import org.exoplatform.ecm.webui.component.explorer.sidebar.UITreeExplorer; import org.exoplatform.ecm.webui.utils.Utils; import org.exoplatform.services.cms.actions.ActionServiceContainer; import org.exoplatform.services.cms.link.NodeFinder; import org.exoplatform.services.cms.link.NodeLinkAware; import org.exoplatform.services.jcr.RepositoryService; import org.exoplatform.services.jcr.core.ManageableRepository; import org.exoplatform.services.log.ExoLogger; import org.exoplatform.services.log.Log; import org.exoplatform.services.security.Identity; import org.exoplatform.services.security.IdentityConstants; import org.exoplatform.services.security.IdentityRegistry; import org.exoplatform.services.security.MembershipEntry; import org.exoplatform.services.wcm.utils.WCMCoreUtils; import org.exoplatform.webui.application.WebuiRequestContext; import org.exoplatform.webui.config.annotation.ComponentConfig; import org.exoplatform.webui.config.annotation.ComponentConfigs; import org.exoplatform.webui.config.annotation.EventConfig; import org.exoplatform.webui.core.UIApplication; import org.exoplatform.webui.core.UIComponent; import org.exoplatform.webui.core.UIContainer; import org.exoplatform.webui.core.UIRightClickPopupMenu; import org.exoplatform.webui.event.Event; import org.exoplatform.webui.event.EventListener; import org.exoplatform.webui.ext.UIExtension; import org.exoplatform.webui.ext.UIExtensionManager; import org.exoplatform.webui.ext.manager.UIAbstractManagerComponent; /** * Created by The eXo Platform SARL Author : Tran The Trong trongtt@gmail.com * July 3, 2006 10:07:15 AM */ @ComponentConfigs( { @ComponentConfig(template = "app:/groovy/webui/component/explorer/UIWorkingArea.gtmpl", events = {@EventConfig(listeners = UIWorkingArea.RefreshActionListener.class)}), @ComponentConfig( type = UIRightClickPopupMenu.class, id = "ECMContextMenu", template = "app:/groovy/webui/component/explorer/UIRightClickPopupMenu.gtmpl" ) }) public class UIWorkingArea extends UIContainer { /** * Logger. */ private static final Log LOG = ExoLogger.getLogger(UIWorkingArea.class.getName()); public static final Pattern FILE_EXPLORER_URL_SYNTAX = Pattern.compile("([^:/]+):(/.*)"); public static final String WS_NAME = "workspaceName"; public static final String EXTENSION_TYPE = "org.exoplatform.ecm.dms.UIWorkingArea"; public static final String ITEM_CONTEXT_MENU = "ItemContextMenu"; public static final String MULTI_ITEM_CONTEXT_MENU = "MultiItemContextMenu"; public static final String GROUND_CONTEXT_MENU = "GroundContextMenu"; public static final String ITEM_GROUND_CONTEXT_MENU = "ItemGroundContextMenu"; public static final String MOVE_NODE = "MoveNode"; public static final String CREATE_LINK = "CreateLink"; public static final String CUSTOM_ACTIONS = "CustomActions"; public static final String PERMLINK = "PermlinkContextMenu"; public static final String PERM_LINK_ACTION = "Permlink"; private String nodePathDelete = ""; private String deleteNotice = ""; private String wcmNotice = ""; public void setNodePathDelete(String nodePathDelete) { this.nodePathDelete = nodePathDelete; } public String getNodePathDelete() { return nodePathDelete; } public String getWCMNotice() { return wcmNotice; } public void setWCMNotice(String wcmNotice) { this.wcmNotice = wcmNotice; } public void setDeleteNotice(String deleteNotice) { this.deleteNotice = deleteNotice; } public String getDeleteNotice() { return this.deleteNotice; } public static final String REFRESH_ACTION = "Refresh"; public static final String RENAME_ACTION = "Rename"; private List<UIAbstractManagerComponent> managers = Collections.synchronizedList(new ArrayList<UIAbstractManagerComponent>()); public UIWorkingArea() throws Exception { addChild(UIRightClickPopupMenu.class, "ECMContextMenu", null); addChild(UISideBar.class, null, null); addChild(UIActionBar.class, null, null) ; addChild(UISelectDocumentTemplateTitle.class, null, null); addChild(UIDocumentWorkspace.class, null, null); addChild(UIDrivesArea.class, null, null).setRendered(false); } private List<UIExtension> getUIExtensionList() { UIExtensionManager manager = getApplicationComponent(UIExtensionManager.class); return manager.getUIExtensions(EXTENSION_TYPE); } public synchronized UITreeExplorer getTreeExplorer() { UISideBar uiSideBar = getChild(UISideBar.class); return uiSideBar.getChild(UITreeExplorer.class); } public void initialize() throws Exception { List<UIExtension> extensions = getUIExtensionList(); if (extensions == null) { return; } managers.clear(); for (UIExtension extension : extensions) { UIComponent component = addUIExtension(extension, null); if (component !=null && !managers.contains(component)) managers.add((UIAbstractManagerComponent)component); } } private UIComponent addUIExtension(UIExtension extension, Map<String, Object> context) throws Exception { UIExtensionManager manager = getApplicationComponent(UIExtensionManager.class); UIComponent component = manager.addUIExtension(extension, context, this); if(component == null) return null; synchronized(component) { if (component instanceof UIAbstractManagerComponent) { // You can access to the given extension and the extension is valid UIAbstractManagerComponent uiAbstractManagerComponent = (UIAbstractManagerComponent) component; uiAbstractManagerComponent.setUIExtensionName(extension.getName()); uiAbstractManagerComponent.setUIExtensionCategory(extension.getCategory()); return component; } else if (component != null) { // You can access to the given extension but the extension is not valid if (LOG.isWarnEnabled()) { LOG.warn("All the extension '" + extension.getName() + "' of type '" + EXTENSION_TYPE + "' must be associated to a component of type " + UIAbstractManagerComponent.class); } removeChild(component.getClass()); } } return null; } public RestoreFromTrashManageComponent getThrashManageComponent(){ for(UIAbstractManagerComponent c : getManagers()){ if(c instanceof RestoreFromTrashManageComponent){ return (RestoreFromTrashManageComponent)c; } } return null; } public List<UIAbstractManagerComponent> getManagers() { List<UIAbstractManagerComponent> managers = new ArrayList<UIAbstractManagerComponent>(); managers.addAll(this.managers); return managers; } public void unregister(UIAbstractManagerComponent component) { managers.remove(component); } //Should use this method to check for when execute Actions in Working Area instead in UIEditingTagsForm (line 120) public boolean isShowSideBar() throws Exception { UIJCRExplorer jcrExplorer = getParent(); return jcrExplorer.getPreference().isShowSideBar() && getAncestorOfType(UIJCRExplorerPortlet.class).isShowSideBar(); } public void setShowSideBar(boolean b) throws Exception { UIJCRExplorer jcrExplorer = getParent(); jcrExplorer.getPreference().setShowSideBar(b); } public Node getNodeByUUID(String uuid) throws Exception { ManageableRepository repo = getApplicationComponent(RepositoryService.class).getCurrentRepository(); String workspace = repo.getConfiguration().getDefaultWorkspaceName(); return getNodeByUUID(uuid, workspace); } public Node getNodeByUUID(String uuid, String workspaceName) throws Exception { ManageableRepository repo = getApplicationComponent(RepositoryService.class).getCurrentRepository(); Session session = WCMCoreUtils.getSystemSessionProvider().getSession(workspaceName, repo); return session.getNodeByUUID(uuid); } public boolean isPreferenceNode(Node node) { return getAncestorOfType(UIJCRExplorer.class).isPreferenceNode(node); } public String getVersionNumber(Node node) throws RepositoryException { if (!Utils.isVersionable(node)) return "-"; return node.getBaseVersion().getName(); } public boolean isJcrViewEnable() throws Exception { UIJCRExplorer uiExplorer = getAncestorOfType(UIJCRExplorer.class); return uiExplorer.getPreference().isJcrEnable(); } private Map<String, Object> createContext(Node currentNode) throws Exception { Map<String, Object> context = new HashMap<String, Object>(); WebuiRequestContext requestContext = WebuiRequestContext.getCurrentInstance() ; UIJCRExplorer uiExplorer = getAncestorOfType(UIJCRExplorer.class); UIApplication uiApp = getAncestorOfType(UIApplication.class); context.put(Node.class.getName(), currentNode); context.put(UIWorkingArea.class.getName(), this); context.put(UIApplication.class.getName(), uiApp); context.put(UIJCRExplorer.class.getName(), uiExplorer); context.put(WebuiRequestContext.class.getName(), requestContext); return context; } List<UIComponent> getGroundActionsExtensionList() throws Exception { List<UIComponent> uiGroundActionList = new ArrayList<UIComponent>(); List<UIExtension> uiExtensionList = getUIExtensionList(); UIJCRExplorer uiExplorer = getAncestorOfType(UIJCRExplorer.class); Node currentNode = uiExplorer.getCurrentNode(); UIComponent uiAddedActionManage; for (UIExtension uiextension : uiExtensionList) { if (GROUND_CONTEXT_MENU.equals(uiextension.getCategory()) || ITEM_GROUND_CONTEXT_MENU.equals(uiextension.getCategory())) { uiAddedActionManage = addUIExtension(uiextension, createContext(currentNode)); if (uiAddedActionManage != null) { if (!uiGroundActionList.contains(uiAddedActionManage)) uiGroundActionList.add(uiAddedActionManage); } } } return uiGroundActionList; } List<UIComponent> getMultiActionsExtensionList() throws Exception { List<UIComponent> uiActionList = new ArrayList<UIComponent>(); List<UIExtension> uiExtensionList = getUIExtensionList(); UIComponent uiAddedActionManage; for (UIExtension uiextension : uiExtensionList) { if (ITEM_CONTEXT_MENU.equals(uiextension.getCategory()) || ITEM_GROUND_CONTEXT_MENU.equals(uiextension.getCategory()) || MULTI_ITEM_CONTEXT_MENU.equals(uiextension.getCategory())) { uiAddedActionManage = addUIExtension(uiextension, null); if (uiAddedActionManage != null) { if (!uiActionList.contains(uiAddedActionManage)) uiActionList.add(uiAddedActionManage); } } } return uiActionList; } public String getActionsExtensionList(Node node) throws Exception { StringBuffer actionsList = new StringBuffer(1024); List<UIExtension> uiExtensionList = getUIExtensionList(); UIComponent uiAddedActionManage; try { NodeFinder nodeFinder = getApplicationComponent(NodeFinder.class); nodeFinder.getItem(getAncestorOfType(UIJCRExplorer.class).getSession(), node.getPath()); } catch(PathNotFoundException pne) { return ""; } for (UIExtension uiextension : uiExtensionList) { if (uiextension.getCategory().startsWith(ITEM_CONTEXT_MENU) || ITEM_GROUND_CONTEXT_MENU.equals(uiextension.getCategory())) { uiAddedActionManage = addUIExtension(uiextension, createContext(node)); if (uiAddedActionManage != null) { actionsList.append(uiextension.getName()).append(","); } } } if (actionsList.length() > 0) { return actionsList.substring(0, actionsList.length() - 1); } return actionsList.toString(); } public UIComponent getJCRMoveAction() throws Exception { UIExtensionManager manager = getApplicationComponent(UIExtensionManager.class); UIExtension extension = manager.getUIExtension(EXTENSION_TYPE, MOVE_NODE); return addUIExtension(extension, null); } public UIComponent getCreateLinkAction() throws Exception { UIExtensionManager manager = getApplicationComponent(UIExtensionManager.class); UIExtension extension = manager.getUIExtension(EXTENSION_TYPE, CREATE_LINK); return addUIExtension(extension, null); } public UIComponent getPermlink(Node node) throws Exception { UIComponent uicomponent = null; List<UIExtension> uiExtensionList = getUIExtensionList(); for (UIExtension uiextension : uiExtensionList) { if (PERMLINK.equals(uiextension.getCategory())) { uicomponent = addUIExtension(uiextension, createContext(node)); } } return uicomponent; } public UIComponent getCustomAction() throws Exception { UIComponent uicomponent = null; List<UIExtension> uiExtensionList = getUIExtensionList(); for (UIExtension uiextension : uiExtensionList) { if (CUSTOM_ACTIONS.equals(uiextension.getCategory())) { uicomponent = addUIExtension(uiextension, null); } } return uicomponent; } private boolean hasPermission(String userName, Value[] roles) throws Exception { IdentityRegistry identityRegistry = getApplicationComponent(IdentityRegistry.class); if (IdentityConstants.SYSTEM.equalsIgnoreCase(userName)) { return true; } Identity identity = identityRegistry.getIdentity(userName); if (identity == null) { return false; } for (int i = 0; i < roles.length; i++) { String role = roles[i].getString(); if ("*".equalsIgnoreCase(role)) return true; MembershipEntry membershipEntry = MembershipEntry.parse(role); if (membershipEntry == null) return false; if (identity.isMemberOf(membershipEntry)) { return true; } } return false; } public List<Node> getCustomActions(Node node) throws Exception { if (node instanceof NodeLinkAware) { NodeLinkAware nodeLA = (NodeLinkAware) node; try { node = nodeLA.getTargetNode().getRealNode(); } catch (Exception e) { // The target of the link is not reachable } } List<Node> safeActions = new ArrayList<Node>(); WebuiRequestContext context = WebuiRequestContext.getCurrentInstance(); String userName = context.getRemoteUser(); ActionServiceContainer actionContainer = getApplicationComponent(ActionServiceContainer.class); List<Node> unsafeActions = actionContainer.getCustomActionsNode(node, "read"); if (unsafeActions == null) return new ArrayList<Node>(); for (Node actionNode : unsafeActions) { Value[] roles = actionNode.getProperty(Utils.EXO_ROLES).getValues(); if (hasPermission(userName, roles)) safeActions.add(actionNode); } return safeActions; } /** * Gets the title. * * @param node the node * * @return the title * * @throws Exception the exception */ public String getTitle(Node node) throws Exception { return Utils.getTitle(node); } public void processRender(WebuiRequestContext context) throws Exception { UIJCRExplorerPortlet uiPortlet = getAncestorOfType(UIJCRExplorerPortlet.class); UIActionBar uiActionBar = findFirstComponentOfType(UIActionBar.class); uiActionBar.setRendered(uiPortlet.isShowActionBar()); UISelectDocumentTemplateTitle uiTemplateTitle = findFirstComponentOfType(UISelectDocumentTemplateTitle.class); boolean isUITemplateTitleRendered = isUISelectDocumentTemplateTitleRendered(); uiTemplateTitle.setRendered(isUITemplateTitleRendered); if(!context.useAjax()) { UITreeExplorer uiTreeExplorer = this.findFirstComponentOfType(UITreeExplorer.class); if (uiTreeExplorer != null) uiTreeExplorer.buildTree(); } super.processRender(context); } public boolean isUISelectDocumentTemplateTitleRendered() { UIDocumentFormController uiDocumentController = findFirstComponentOfType(UIDocumentFormController.class); boolean isUITemplateTitleRendered = (uiDocumentController != null && uiDocumentController.isRendered() && uiDocumentController.getChild(UISelectDocumentForm.class).isRendered()); return isUITemplateTitleRendered; } /** * Refresh UIWorkingArea after renaming.UIPresentationContainer */ public static class RefreshActionListener extends EventListener<UIWorkingArea> { public void execute(Event<UIWorkingArea> event) throws Exception { UIJCRExplorer uiExplorer = event.getSource().getAncestorOfType(UIJCRExplorer.class); // Get path before renaming String pathBeforeRename = event.getRequestContext().getRequestParameter("oldPath"); // Get path after renaming String renamedNodeUUID = event.getRequestContext().getRequestParameter("uuid"); String pathAfterRename = null; Node renamedNode = null; try { renamedNode = uiExplorer.getSession().getNodeByUUID(renamedNodeUUID); } catch (ItemNotFoundException e) { // Try to find node in other workspaces String[] workspaceNames = uiExplorer.getRepository().getWorkspaceNames(); String currentWorkSpaceName = uiExplorer.getWorkspaceName(); for (String workspaceName : workspaceNames) { if (!workspaceName.equals(currentWorkSpaceName)) { try { renamedNode = uiExplorer.getSessionByWorkspace(workspaceName).getNodeByUUID(renamedNodeUUID); break; } catch (ItemNotFoundException infE) { renamedNode = null; } } } } if (renamedNode != null) { pathAfterRename = renamedNode.getPath(); } else { LOG.warn("Can not find renamed node with old path: [%s]", pathBeforeRename); return; } // Update content explorer String currentPath = uiExplorer.getCurrentPath(); if (currentPath.equals(pathBeforeRename)) { uiExplorer.setCurrentPath(pathAfterRename) ; } else if(currentPath.startsWith(pathBeforeRename)) { uiExplorer.setCurrentPath(pathAfterRename + currentPath.replace(pathBeforeRename, StringUtils.EMPTY)); } uiExplorer.updateAjax(event); } } }