UIActionBar.java
/*
* 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.control;
import org.apache.commons.lang.StringUtils;
import org.exoplatform.commons.utils.CommonsUtils;
import org.exoplatform.ecm.jcr.SearchValidator;
import org.exoplatform.ecm.webui.component.explorer.*;
import org.exoplatform.ecm.webui.component.explorer.popup.actions.UIDocumentForm;
import org.exoplatform.ecm.webui.component.explorer.popup.actions.UIDocumentFormController;
import org.exoplatform.ecm.webui.component.explorer.search.*;
import org.exoplatform.portal.webui.util.Util;
import org.exoplatform.services.cms.BasePath;
import org.exoplatform.services.cms.drives.DriveData;
import org.exoplatform.services.cms.drives.impl.ManageDriveServiceImpl;
import org.exoplatform.services.cms.queries.QueryService;
import org.exoplatform.services.cms.views.ManageViewService;
import org.exoplatform.services.jcr.RepositoryService;
import org.exoplatform.services.jcr.ext.hierarchy.NodeHierarchyCreator;
import org.exoplatform.services.log.ExoLogger;
import org.exoplatform.services.log.Log;
import org.exoplatform.services.organization.OrganizationService;
import org.exoplatform.services.organization.User;
import org.exoplatform.services.security.IdentityConstants;
import org.exoplatform.services.wcm.core.NodeLocation;
import org.exoplatform.services.wcm.core.NodetypeConstant;
import org.exoplatform.services.wcm.utils.WCMCoreUtils;
import org.exoplatform.web.application.RequestContext;
import org.exoplatform.web.application.RequireJS;
import org.exoplatform.webui.config.annotation.ComponentConfig;
import org.exoplatform.webui.config.annotation.EventConfig;
import org.exoplatform.webui.core.UIComponent;
import org.exoplatform.webui.core.UIPopupContainer;
import org.exoplatform.webui.core.lifecycle.UIFormLifecycle;
import org.exoplatform.webui.core.model.SelectItemOption;
import org.exoplatform.webui.event.Event;
import org.exoplatform.webui.event.Event.Phase;
import org.exoplatform.webui.event.EventListener;
import org.exoplatform.webui.ext.UIExtension;
import org.exoplatform.webui.ext.UIExtensionManager;
import org.exoplatform.webui.form.UIForm;
import org.exoplatform.webui.form.UIFormSelectBox;
import org.exoplatform.webui.form.UIFormStringInput;
import javax.jcr.Node;
import javax.jcr.NodeIterator;
import javax.jcr.PathNotFoundException;
import javax.jcr.RepositoryException;
import javax.jcr.query.Query;
import javax.portlet.PortletPreferences;
import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.util.*;
/**
* Created by The eXo Platform SARL
* Author : Tran The Trong
* trongtt@gmail.com
* Aug 2, 2006
*/
@ComponentConfig(
lifecycle = UIFormLifecycle.class,
template = "app:/groovy/webui/component/explorer/control/UIActionBar.gtmpl",
events = {
@EventConfig(listeners = UIActionBar.SearchActionListener.class, phase = Phase.DECODE),
@EventConfig(listeners = UIActionBar.SimpleSearchActionListener.class),
@EventConfig(listeners = UIActionBar.AdvanceSearchActionListener.class, phase = Phase.DECODE),
@EventConfig(listeners = UIActionBar.SavedQueriesActionListener.class, phase = Phase.DECODE),
@EventConfig(listeners = UIActionBar.ChangeTabActionListener.class, phase = Phase.DECODE),
@EventConfig(listeners = UIActionBar.PreferencesActionListener.class, phase = Phase.DECODE),
@EventConfig(listeners = UIActionBar.BackToActionListener.class, phase=Phase.DECODE),
@EventConfig(listeners = UIActionBar.ShowDrivesActionListener.class, phase=Phase.DECODE)
}
)
public class UIActionBar extends UIForm {
/**
* Logger.
*/
private static final Log LOG = ExoLogger.getLogger(UIActionBar.class.getName());
private OrganizationService organizationService;
private NodeLocation view_ ;
private String templateName_ ;
//private List<SelectItemOption<String>> tabOptions = new ArrayList<SelectItemOption<String>>() ;
private List<String> tabList_ = new ArrayList<String>();
private List<String[]> tabs_ = new ArrayList<String[]>();
private Map<String, String[]> actionInTabs_ = new HashMap<String, String[]>();
private String selectedTabName_;
final static private String FIELD_SIMPLE_SEARCH = "simpleSearch";
final static private String FIELD_ADVANCE_SEARCH = "advanceSearch";
final static private String FIELD_SEARCH_TYPE = "searchType";
final static private String FIELD_SQL = "SQL";
final static private String FIELD_XPATH = "xPath";
final static private String ROOT_SQL_QUERY = "select * from nt:base where contains(*, '$1') "
+ "order by exo:dateCreated DESC, jcr:primaryType DESC";
final static private String SQL_QUERY = "select * from nt:base where jcr:path like '$0/%' and contains(*, '$1') "
+ "order by jcr:path DESC, jcr:primaryType DESC";
private String backLink;
public UIActionBar() throws Exception {
organizationService = CommonsUtils.getService(OrganizationService.class);
addChild(new UIFormStringInput(FIELD_SIMPLE_SEARCH, FIELD_SIMPLE_SEARCH, null).addValidator(SearchValidator.class));
List<SelectItemOption<String>> typeOptions = new ArrayList<SelectItemOption<String>>();
typeOptions.add(new SelectItemOption<String>(FIELD_SQL, Query.SQL));
typeOptions.add(new SelectItemOption<String>(FIELD_XPATH, Query.XPATH));
addChild(new UIFormSelectBox(FIELD_SEARCH_TYPE, FIELD_SEARCH_TYPE, typeOptions));
addChild(new UIFormStringInput(FIELD_ADVANCE_SEARCH, FIELD_ADVANCE_SEARCH, null));
}
public void setTabOptions(String viewName) throws Exception {
tabList_ = new ArrayList<String>();
Node viewNode = getApplicationComponent(ManageViewService.class).getViewByName(viewName,
WCMCoreUtils.getSystemSessionProvider());
view_ = NodeLocation.getNodeLocationByNode(viewNode);
NodeIterator tabs = viewNode.getNodes();
while (tabs.hasNext()) {
Node tab = tabs.nextNode();
if(!tabList_.contains(tab.getName())) tabList_.add(tab.getName());
setListButton(tab.getName());
}
setSelectedTab(tabList_.get(0));
String template = viewNode.getProperty("exo:template").getString();
templateName_ = template.substring(template.lastIndexOf("/") + 1);
UIJCRExplorer uiExplorer = getAncestorOfType(UIJCRExplorer.class);
uiExplorer.setRenderTemplate(template);
}
public boolean hasBackButton() {
String newLink = getAncestorOfType(UIJCRExplorerPortlet.class).getBacktoValue();
if (newLink != null && newLink.length()>0)
backLink = newLink;
return backLink != null;
}
public String getBackLink() {
return getAncestorOfType(UIJCRExplorerPortlet.class).getBacktoValue();
}
public String getTemplateName() { return templateName_; }
private void setListButton(String tabName) throws PathNotFoundException, RepositoryException {
Node tabNode = NodeLocation.getNodeByLocation(view_).getNode(tabName);
if(tabNode.hasProperty("exo:buttons")) {
String buttons = tabNode.getProperty("exo:buttons").getString();
String[] buttonsInTab = StringUtils.split(buttons, ";");
Set<String> bt = new HashSet<String>();
//get all buttons in tab
for (String b : buttonsInTab) {
b = b.trim();
b = b.substring(0, 1).toUpperCase() + b.substring(1);
bt.add(b);
}
//sort the buttons by UIExtension sorting order
List<String> sortedButtons = new ArrayList<String>();
UIExtensionManager manager = getApplicationComponent(UIExtensionManager.class);
List<UIExtension> extensions = manager.getUIExtensions(ManageViewService.EXTENSION_TYPE);
for(UIExtension e : extensions) {
if (bt.contains(e.getName())) {
sortedButtons.add(e.getName().trim());
}
}
buttonsInTab = sortedButtons.toArray(new String[]{});
actionInTabs_.put(tabName, buttonsInTab);
tabs_.add(buttonsInTab);
}
}
public String[] getActionInTab(String tabName) { return actionInTabs_.get(tabName); }
public void setSelectedTab(String tabName) {
selectedTabName_ = tabName;
}
public boolean isDirectlyDrive() {
PortletPreferences portletPref =
getAncestorOfType(UIJCRExplorerPortlet.class).getPortletPreferences();
String usecase = portletPref.getValue("usecase", "").trim();
if ("selection".equals(usecase)) {
return false;
}
return true;
}
public String getSelectedTab() throws Exception {
if(selectedTabName_ == null || selectedTabName_.length() == 0) {
setTabOptions(tabList_.get(0));
return tabList_.get(0);
}
return selectedTabName_;
}
public List<String> getTabList() { return tabList_; }
public List<Query> getSavedQueries() throws Exception {
String userName = Util.getPortalRequestContext().getRemoteUser();
return getApplicationComponent(QueryService.class).getQueries(userName, WCMCoreUtils.getSystemSessionProvider());
}
public synchronized UIComponent getUIAction(String action) {
try {
UIExtensionManager manager = getApplicationComponent(UIExtensionManager.class);
Map<String, Object> context = new HashMap<String, Object>();
UIJCRExplorer uiExplorer = getAncestorOfType(UIJCRExplorer.class);
Node currentNode = uiExplorer.getCurrentNode();
context.put(UIJCRExplorer.class.getName(), uiExplorer);
context.put(Node.class.getName(), currentNode);
return manager.addUIExtension(ManageViewService.EXTENSION_TYPE, action, context, this);
} catch (Exception e) {
if (LOG.isErrorEnabled()) {
LOG.error("An error occurs while checking the action", e);
}
}
return null;
}
public boolean isActionAvailable(String tabName) {
List<UIComponent> listActions = new ArrayList<UIComponent>();
for(String action : getActionInTab(tabName)) {
UIComponent uicomp = getUIAction(action);
if(uicomp != null) listActions.add(uicomp);
}
if(listActions.size() > 0) return true;
return false;
}
static public class SearchActionListener extends EventListener<UIActionBar> {
public void execute(Event<UIActionBar> event) throws Exception {
UIJCRExplorer uiJCRExplorer = event.getSource().getAncestorOfType(UIJCRExplorer.class);
UIPopupContainer UIPopupContainer = uiJCRExplorer.getChild(UIPopupContainer.class);
UIPopupContainer.activate(UIECMSearch.class, 700);
event.getRequestContext().addUIComponentToUpdateByAjax(UIPopupContainer);
}
}
static public class SimpleSearchActionListener extends EventListener<UIActionBar> {
public void execute(Event<UIActionBar> event) throws Exception {
UIActionBar uiForm = event.getSource();
UIJCRExplorer uiExplorer = uiForm.getAncestorOfType(UIJCRExplorer.class);
String text = uiForm.getUIStringInput(FIELD_SIMPLE_SEARCH).getValue();
Node currentNode = uiExplorer.getCurrentNode();
String queryStatement = null;
if("/".equals(currentNode.getPath())) {
queryStatement = ROOT_SQL_QUERY;
}else {
queryStatement = StringUtils.replace(SQL_QUERY,"$0",currentNode.getPath());
}
queryStatement = StringUtils.replace(queryStatement,"$1", text.replaceAll("'", "''"));
uiExplorer.removeChildById("ViewSearch");
UIWorkingArea uiWorkingArea = uiExplorer.getChild(UIWorkingArea.class);
UIDocumentWorkspace uiDocumentWorkspace = uiWorkingArea.getChild(UIDocumentWorkspace.class);
if(!uiDocumentWorkspace.isRendered()) {
uiWorkingArea.getChild(UIDrivesArea.class).setRendered(false);
uiWorkingArea.getChild(UIDocumentWorkspace.class).setRendered(true);
uiDocumentWorkspace.setRenderedChild(UIDocumentContainer.class) ;
}
UISearchResult uiSearchResult =
uiDocumentWorkspace.getChildById(UIDocumentWorkspace.SIMPLE_SEARCH_RESULT);
long startTime = System.currentTimeMillis();
uiSearchResult.setQuery(queryStatement, currentNode.getSession().getWorkspace().getName(), Query.SQL,
IdentityConstants.SYSTEM.equals(WCMCoreUtils.getRemoteUser()), null);
uiSearchResult.updateGrid();
long time = System.currentTimeMillis() - startTime;
uiSearchResult.setSearchTime(time);
uiDocumentWorkspace.setRenderedChild(UISearchResult.class);
}
}
static public class AdvanceSearchActionListener extends EventListener<UIActionBar> {
public void execute(Event<UIActionBar> event) throws Exception {
UIJCRExplorer uiJCRExplorer = event.getSource().getAncestorOfType(UIJCRExplorer.class);
UIPopupContainer UIPopupContainer = uiJCRExplorer.getChild(UIPopupContainer.class);
UIECMSearch uiECMSearch = event.getSource().createUIComponent(UIECMSearch.class, null, null);
UIContentNameSearch contentNameSearch = uiECMSearch.findFirstComponentOfType(UIContentNameSearch.class);
String currentNodePath = uiJCRExplorer.getCurrentNode().getPath();
contentNameSearch.setLocation(currentNodePath);
UISimpleSearch uiSimpleSearch = uiECMSearch.findFirstComponentOfType(UISimpleSearch.class);
uiSimpleSearch.getUIFormInputInfo(UISimpleSearch.NODE_PATH).setValue(currentNodePath);
UIPopupContainer.activate(uiECMSearch, 700, 500);
event.getRequestContext().addUIComponentToUpdateByAjax(UIPopupContainer);
}
}
static public class BackToActionListener extends EventListener<UIActionBar> {
public void execute(Event<UIActionBar> event) throws Exception {
UIJCRExplorer uiExplorer = event.getSource().getAncestorOfType(UIJCRExplorer.class);
UIWorkingArea uiWorkingArea = uiExplorer.getChild(UIWorkingArea.class);
UIDocumentWorkspace uiDocumentWorkspace = uiWorkingArea.getChild(UIDocumentWorkspace.class);
UIDocumentFormController uiDocumentFormController = uiDocumentWorkspace.getChild(UIDocumentFormController.class);
String backLink = event.getSource().getBackLink();
if (uiDocumentFormController != null) {
UIDocumentForm uiDocument = uiDocumentFormController.getChild(UIDocumentForm.class);
if (uiDocument!=null) {
uiDocument.releaseLock();
}
uiDocumentWorkspace.removeChild(UIDocumentFormController.class);
} else
uiExplorer.cancelAction();
RequireJS requireJS = event.getRequestContext().getJavascriptManager().getRequireJS();
requireJS.require("SHARED/ecm-utils", "ecmutil").addScripts("ecmutil.ECMUtils.ajaxRedirect('" + backLink + "');");
}
}
static public class SavedQueriesActionListener extends EventListener<UIActionBar> {
public void execute(Event<UIActionBar> event) throws Exception {
UIJCRExplorer uiJCRExplorer = event.getSource().getAncestorOfType(UIJCRExplorer.class);
UIPopupContainer UIPopupContainer = uiJCRExplorer.getChild(UIPopupContainer.class);
UISavedQuery uiSavedQuery = event.getSource().createUIComponent(UISavedQuery.class, null, null);
uiSavedQuery.setIsQuickSearch(true);
uiSavedQuery.updateGrid(1);
UIPopupContainer.activate(uiSavedQuery, 700, 400);
event.getRequestContext().addUIComponentToUpdateByAjax(UIPopupContainer);
}
}
static public class ChangeTabActionListener extends EventListener<UIActionBar> {
public void execute(Event<UIActionBar> event) throws Exception {
UIActionBar uiActionBar = event.getSource();
String selectedTabName = event.getRequestContext().getRequestParameter(OBJECTID);
uiActionBar.setSelectedTab(selectedTabName);
event.getRequestContext().addUIComponentToUpdateByAjax(uiActionBar.getAncestorOfType(UIJCRExplorer.class));
}
}
static public class PreferencesActionListener extends EventListener<UIActionBar> {
public void execute(Event<UIActionBar> event) throws Exception {
UIActionBar uiActionBar = event.getSource();
UIJCRExplorer uiJCRExplorer = uiActionBar.getAncestorOfType(UIJCRExplorer.class);
UIPopupContainer popupAction = uiJCRExplorer.getChild(UIPopupContainer.class);
UIPreferencesForm uiPrefForm = popupAction.activate(UIPreferencesForm.class,600) ;
uiPrefForm.update(uiJCRExplorer.getPreference()) ;
event.getRequestContext().addUIComponentToUpdateByAjax(popupAction) ;
}
}
static public class ShowDrivesActionListener extends EventListener<UIActionBar> {
public void execute(Event<UIActionBar> event) throws Exception {
UIJCRExplorer uiExplorer = event.getSource().getAncestorOfType(UIJCRExplorer.class);
UIWorkingArea uiWorkingArea = uiExplorer.getChild(UIWorkingArea.class);
UIDrivesArea uiDriveArea = uiWorkingArea.getChild(UIDrivesArea.class);
if (uiDriveArea.isRendered()) {
uiDriveArea.setRendered(false);
uiWorkingArea.getChild(UIDocumentWorkspace.class).setRendered(true);
} else {
uiDriveArea.setRendered(true);
uiWorkingArea.getChild(UIDocumentWorkspace.class).setRendered(false);
}
event.getRequestContext().addUIComponentToUpdateByAjax(uiWorkingArea) ;
}
}
public String getDriveLabel() {
RequestContext context = RequestContext.getCurrentInstance();
ResourceBundle res = context.getApplicationResourceBundle();
DriveData drive = getAncestorOfType(UIJCRExplorer.class).getDriveData();
String driveName = drive.getName();
String driveLabel = "";
try {
if(ManageDriveServiceImpl.GROUPS_DRIVE_NAME.equals(driveName) || driveName.startsWith(".")) {
// Groups drive
RepositoryService repoService = WCMCoreUtils.getService(RepositoryService.class);
NodeHierarchyCreator nodeHierarchyCreator = WCMCoreUtils.getService(NodeHierarchyCreator.class);
String groupPath = nodeHierarchyCreator.getJcrPath(BasePath.CMS_GROUPS_PATH);
Node groupNode = (Node)WCMCoreUtils.getSystemSessionProvider().getSession(
repoService.getCurrentRepository().getConfiguration().getDefaultWorkspaceName(),
repoService.getCurrentRepository()).getItem(
groupPath + drive.getName().replace(".", "/"));
driveLabel = groupNode.getProperty(NodetypeConstant.EXO_LABEL).getString();
} else if(ManageDriveServiceImpl.USER_DRIVE_NAME.equals(driveName)) {
// User Documents drive
String userDisplayName = "";
String driveLabelKey = "Drives.label.UserDocuments";
String userIdPath = drive.getParameters().get(ManageDriveServiceImpl.DRIVE_PARAMATER_USER_ID);
String userId = userIdPath != null ? userIdPath.substring(userIdPath.lastIndexOf("/") + 1) : null;
if(StringUtils.isNotEmpty(userId)) {
userDisplayName = userId;
User user = organizationService.getUserHandler().findUserByName(userId);
if(user != null) {
userDisplayName = user.getDisplayName();
}
}
try {
driveLabel = res.getString(driveLabelKey).replace("{0}", userDisplayName);
} catch(MissingResourceException mre) {
LOG.error("Cannot get resource string " + driveLabel + " : " + mre.getMessage(), mre);
driveLabel = userDisplayName;
}
} else {
// Others drives
String driveLabelKey = "Drives.label." + driveName.replace(".", "").replace(" ", "");
try {
driveLabel = res.getString(driveLabelKey);
} catch (MissingResourceException ex) {
//
driveLabel = driveName.replace(".", "/");
}
}
} catch(Exception e) {
driveLabel = driveName.replace(".", " / ");
}
return driveLabel;
}
}