/*
* 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.popup.admin;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import javax.jcr.Node;
import javax.jcr.RepositoryException;
import javax.jcr.Session;
import javax.jcr.nodetype.ConstraintViolationException;
import org.exoplatform.ecm.webui.component.explorer.UIJCRExplorer;
import org.exoplatform.ecm.webui.component.explorer.sidebar.UITreeExplorer;
import org.exoplatform.ecm.webui.form.UIDialogForm;
import org.exoplatform.ecm.webui.nodetype.selector.UINodeTypeSelector;
import org.exoplatform.ecm.webui.selector.ComponentSelector;
import org.exoplatform.ecm.webui.selector.UISelectable;
import org.exoplatform.ecm.webui.tree.selectone.UIOneNodePathSelector;
import org.exoplatform.ecm.webui.utils.DialogFormUtil;
import org.exoplatform.ecm.webui.utils.PermissionUtil;
import org.exoplatform.ecm.webui.utils.Utils;
import org.exoplatform.portal.application.PortalRequestContext;
import org.exoplatform.portal.webui.util.Util;
import org.exoplatform.resolver.ResourceResolver;
import org.exoplatform.services.cms.CmsService;
import org.exoplatform.services.cms.JcrInputProperty;
import org.exoplatform.services.cms.actions.ActionServiceContainer;
import org.exoplatform.services.cms.templates.TemplateService;
import org.exoplatform.services.jcr.ext.common.SessionProvider;
import org.exoplatform.services.log.ExoLogger;
import org.exoplatform.services.log.Log;
import org.exoplatform.web.application.ApplicationMessage;
import org.exoplatform.web.url.navigation.NavigationResource;
import org.exoplatform.web.url.navigation.NodeURL;
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.UIPageIterator;
import org.exoplatform.webui.core.UIPopupWindow;
import org.exoplatform.webui.core.lifecycle.UIFormLifecycle;
import org.exoplatform.webui.event.Event;
import org.exoplatform.webui.event.Event.Phase;
import org.exoplatform.webui.event.EventListener;
import org.exoplatform.webui.form.UIFormInputBase;
import org.exoplatform.webui.form.UIFormMultiValueInputSet;
import org.exoplatform.webui.form.UIFormStringInput;
/**
* Created by The eXo Platform SARL
* Author : Dang Van Minh
* minh.dang@exoplatform.com
* Nov 8, 2006
* 11:23:50 AM
*/
@ComponentConfigs( {
@ComponentConfig(type = UIFormMultiValueInputSet.class, id = "WYSIWYGRichTextMultipleInputset", events = {
@EventConfig(listeners = UIDialogForm.AddActionListener.class, phase = Phase.DECODE),
@EventConfig(listeners = UIFormMultiValueInputSet.RemoveActionListener.class, phase = Phase.DECODE) }),
@ComponentConfig(lifecycle = UIFormLifecycle.class, events = {
@EventConfig(listeners = UIActionForm.SaveActionListener.class),
@EventConfig(listeners = UIDialogForm.OnchangeActionListener.class, phase = Phase.DECODE),
@EventConfig(listeners = UIActionForm.BackActionListener.class, phase = Phase.DECODE),
@EventConfig(listeners = UIActionForm.ShowComponentActionListener.class, phase = Phase.DECODE),
@EventConfig(listeners = UIActionForm.AddActionListener.class, phase = Phase.DECODE),
@EventConfig(listeners = UIActionForm.RemoveActionListener.class, phase = Phase.DECODE),
@EventConfig(listeners = UIActionForm.RemoveReferenceActionListener.class,
confirm = "DialogFormField.msg.confirm-delete", phase = Phase.DECODE) }) })
public class UIActionForm extends UIDialogForm implements UISelectable {
private String parentPath_;
private String nodeTypeName_ = null;
private boolean isAddNew_;
private String scriptPath_ = null;
private boolean isEditInList_ = false;
private String rootPath_ = null;
private String currentAction = null;
private static final String EXO_ACTIONS = "exo:actions";
private static final Log LOG = ExoLogger.getLogger(UIActionForm.class.getName());
public String getDriverName() {
UIJCRExplorer uiExplorer = getAncestorOfType(UIJCRExplorer.class);
return uiExplorer.getRepositoryName() + "/" + uiExplorer.getDriveData().getName();
}
public UIActionForm() throws Exception {
setActions(new String[]{"Save","Back"});
}
public void createNewAction(Node parentNode, String actionType, boolean isAddNew) throws Exception {
reset();
parentPath_ = parentNode.getPath();
nodeTypeName_ = actionType;
isAddNew_ = isAddNew;
componentSelectors.clear();
properties.clear();
getChildren().clear();
}
private Node getParentNode() throws Exception{ return (Node) getSession().getItem(parentPath_); }
/**
* @param currentAction the currentAction to set
*/
public void setCurrentAction(String currentAction) {
this.currentAction = currentAction;
}
/**
* @return the currentAction
*/
public String getCurrentAction() {
return currentAction;
}
public void doSelect(String selectField, Object value) throws Exception {
isUpdateSelect = true;
UIComponent uicomponent = getChildById(selectField);
if (UIFormStringInput.class.isInstance(uicomponent))
((UIFormStringInput)uicomponent).setValue(value.toString());
else if (UIFormMultiValueInputSet.class.isInstance(uicomponent)) {
((UIFormMultiValueInputSet)uicomponent).setValue((ArrayList<String>)value);
}
if(isEditInList_) {
UIActionManager uiManager = getAncestorOfType(UIActionManager.class);
UIActionListContainer uiActionListContainer = uiManager.getChild(UIActionListContainer.class);
uiActionListContainer.removeChildById("PopupComponent");
} else {
UIActionContainer uiActionContainer = getParent();
uiActionContainer.removeChildById("PopupComponent");
}
}
public String getCurrentPath() throws Exception {
return getAncestorOfType(UIJCRExplorer.class).getCurrentNode().getPath();
}
public ResourceResolver getTemplateResourceResolver(WebuiRequestContext context, String template) {
return getAncestorOfType(UIJCRExplorer.class).getJCRTemplateResourceResolver();
}
public String getTemplate() { return getDialogPath(); }
public String getDialogPath() {
repositoryName = getAncestorOfType(UIJCRExplorer.class).getRepositoryName();
TemplateService templateService = getApplicationComponent(TemplateService.class);
String userName = Util.getPortalRequestContext().getRemoteUser();
String dialogPath = null;
if (nodeTypeName_ != null) {
try {
dialogPath = templateService.getTemplatePathByUser(true, nodeTypeName_, userName);
} catch (Exception e){
if (LOG.isWarnEnabled()) {
LOG.warn(e.getMessage());
}
}
}
return dialogPath;
}
public String getRepositoryName() { return repositoryName; }
public String getTemplateNodeType() { return nodeTypeName_; }
private void setPath(String scriptPath) {
UIJCRExplorer uiExplorer = getAncestorOfType(UIJCRExplorer.class);
if(scriptPath.indexOf(":") < 0) {
scriptPath = uiExplorer.getCurrentWorkspace() + ":" + scriptPath;
}
scriptPath_ = scriptPath;
}
public String getPath() { return scriptPath_; }
public void setRootPath(String rootPath){
rootPath_ = rootPath;
}
public String getRootPath(){return rootPath_;}
public void setIsEditInList(boolean isEditInList) { isEditInList_ = isEditInList; }
public void onchange(Event<?> event) throws Exception {
if(isEditInList_ || !isAddNew_) {
event.getRequestContext().addUIComponentToUpdateByAjax(getParent());
return;
}
UIActionManager uiManager = getAncestorOfType(UIActionManager.class);
uiManager.setRenderedChild(UIActionContainer.class);
event.getRequestContext().addUIComponentToUpdateByAjax(uiManager);
}
public void renderField(String name) throws Exception {
UIComponent uiInput = findComponentById(name);
if ("homePath".equals(name)) {
UIJCRExplorer uiExplorer = getAncestorOfType(UIJCRExplorer.class) ;
Node currentNode = uiExplorer.getCurrentNode() ;
String homPath = uiExplorer.getCurrentWorkspace() + ":" + currentNode.getPath();
((UIFormStringInput) uiInput).setValue(homPath);
}
super.renderField(name);
}
static public class SaveActionListener extends EventListener<UIActionForm> {
private void addInputInfo(Map<String, JcrInputProperty> input, UIActionForm actionForm) throws Exception {
String rssUrlKey = "/node/exo:url";
if (input.get(rssUrlKey) == null) return;
UIJCRExplorer uiExplorer = actionForm.getAncestorOfType(UIJCRExplorer.class);
//drive name
UITreeExplorer treeExplorer = uiExplorer.findFirstComponentOfType(UITreeExplorer.class);
String driveName = treeExplorer.getDriveName();
//requestUri
PortalRequestContext pContext = Util.getPortalRequestContext();
NodeURL nodeURL = pContext.createURL(NodeURL.TYPE);
NavigationResource resource = new NavigationResource(Util.getUIPortal().getSelectedUserNode());
nodeURL.setResource(resource);
nodeURL.setQueryParameterValue("path", driveName);
nodeURL.setSchemeUse(true);
input.get(rssUrlKey).setValue(nodeURL.toString());
}
public void execute(Event<UIActionForm> event) throws Exception {
UIActionForm actionForm = event.getSource();
UIApplication uiApp = actionForm.getAncestorOfType(UIApplication.class);
ActionServiceContainer actionServiceContainer = actionForm.getApplicationComponent(ActionServiceContainer.class);
UIJCRExplorer uiExplorer = actionForm.getAncestorOfType(UIJCRExplorer.class);
String repository = actionForm.getAncestorOfType(UIJCRExplorer.class).getRepositoryName();
Map<String, JcrInputProperty> sortedInputs = DialogFormUtil.prepareMap(actionForm.getChildren(),
actionForm.getInputProperties(),
actionForm.getInputOptions());
addInputInfo(sortedInputs, actionForm);
Node currentNode = uiExplorer.getCurrentNode();
if(!PermissionUtil.canAddNode(currentNode) || !PermissionUtil.canSetProperty(currentNode)) {
uiApp.addMessage(new ApplicationMessage("UIActionForm.msg.no-permission-add", null));
return;
}
UIFormStringInput homePathInput = actionForm.getUIStringInput("homePath");
if (homePathInput != null) {
String targetPath = homePathInput.getValue();
if ((targetPath == null) || (targetPath.length() == 0)) {
uiApp.addMessage(new ApplicationMessage("UIActionForm.msg.homePath-emty", null,
ApplicationMessage.WARNING));
return;
}
}
UIFormStringInput targetPathInput = actionForm.getUIStringInput("targetPath");
if (targetPathInput != null) {
String targetPath = targetPathInput.getValue();
if ((targetPath == null) || (targetPath.length() == 0)) {
uiApp.addMessage(new ApplicationMessage("UIActionForm.msg.targetPath-emty", null,
ApplicationMessage.WARNING));
return;
}
}
String actionName = (String)(sortedInputs.get("/node/exo:name")).getValue();
if (!Utils.isNameValid(actionName, Utils.SPECIALCHARACTER)) {
uiApp.addMessage(new ApplicationMessage("UIActionForm.msg.name-not-allowed", null, ApplicationMessage.WARNING));
return;
}
Node parentNode = actionForm.getParentNode();
if (actionForm.isAddNew_) {
if (parentNode.hasNode(EXO_ACTIONS)) {
if (parentNode.getNode(EXO_ACTIONS).hasNode(actionName)) {
Object[] args = { actionName };
uiApp.addMessage(new ApplicationMessage("UIActionForm.msg.existed-action",
args,
ApplicationMessage.WARNING));
return;
}
}
} else if (actionForm.isEditInList_) {
if (parentNode.hasNode(EXO_ACTIONS)) {
if (parentNode.getNode(EXO_ACTIONS).hasNode(actionName)
&& !actionName.equals(actionForm.currentAction)) {
Object[] args = { actionName };
uiApp.addMessage(new ApplicationMessage("UIActionForm.msg.existed-action",
args,
ApplicationMessage.WARNING));
return;
}
}
}
try{
if (uiExplorer.nodeIsLocked(currentNode)) return;
if (!actionForm.isAddNew_) {
CmsService cmsService = actionForm.getApplicationComponent(CmsService.class);
Node storedHomeNode = actionForm.getNode().getParent();
Node currentActionNode = storedHomeNode.getNode(sortedInputs.get("/node").getValue().toString());
if (uiExplorer.nodeIsLocked(currentActionNode)) return;
cmsService.storeNode(actionForm.nodeTypeName_, storedHomeNode, sortedInputs, false);
Session session = currentActionNode.getSession();
if (uiExplorer.nodeIsLocked(currentActionNode))
return; // We add LockToken again because CMSService did logout
// session cause lost lock information
session.move(currentActionNode.getPath(), storedHomeNode.getPath() + "/"
+ sortedInputs.get("/node/exo:name").getValue().toString());
session.save();
currentNode.getSession().save();
if (actionForm.isEditInList_) {
UIActionManager uiManager = actionForm.getAncestorOfType(UIActionManager.class);
UIPopupWindow uiPopup = uiManager.findComponentById("editActionPopup");
uiPopup.setShow(false);
uiPopup.setRendered(false);
uiManager.setDefaultConfig();
actionForm.isEditInList_ = false;
//actionForm.isAddNew_ = true;
actionForm.setIsOnchange(false);
event.getRequestContext().addUIComponentToUpdateByAjax(uiManager);
uiExplorer.setIsHidePopup(true);
uiExplorer.updateAjax(event);
} else {
uiExplorer.setIsHidePopup(false);
uiExplorer.updateAjax(event);
}
actionForm.setPath(storedHomeNode.getPath());
actionServiceContainer.removeAction(currentNode, currentActionNode.getName(), repository);
//return;
}
JcrInputProperty rootProp = sortedInputs.get("/node");
if(rootProp == null) {
rootProp = new JcrInputProperty();
rootProp.setJcrPath("/node");
rootProp.setValue((sortedInputs.get("/node/exo:name")).getValue());
sortedInputs.put("/node", rootProp);
} else {
rootProp.setValue((sortedInputs.get("/node/exo:name")).getValue());
}
if (parentNode.isNew()) {
String[] args = { parentNode.getPath() };
uiApp.addMessage(new ApplicationMessage("UIActionForm.msg.unable-add-action", args));
return;
}
actionServiceContainer.addAction(parentNode, actionForm.nodeTypeName_, sortedInputs);
actionForm.setIsOnchange(false);
parentNode.getSession().save();
UIActionManager uiActionManager = actionForm.getAncestorOfType(UIActionManager.class);
actionForm.createNewAction(uiExplorer.getCurrentNode(), actionForm.nodeTypeName_, true);
UIActionList uiActionList = uiActionManager.findFirstComponentOfType(UIActionList.class);
uiActionList.updateGrid(parentNode, uiActionList.getChild(UIPageIterator.class).getCurrentPage());
uiActionManager.setRenderedChild(UIActionListContainer.class);
actionForm.reset();
} catch(ConstraintViolationException cex) {
uiApp.addMessage(new ApplicationMessage("UIActionForm.msg.constraintviolation-exception",
null,
ApplicationMessage.WARNING));
return;
} catch(RepositoryException repo) {
String key = "UIActionForm.msg.repository-exception";
uiApp.addMessage(new ApplicationMessage(key, null, ApplicationMessage.WARNING));
return;
} catch(NumberFormatException nume) {
String key = "UIActionForm.msg.numberformat-exception";
uiApp.addMessage(new ApplicationMessage(key, null, ApplicationMessage.WARNING));
return;
} catch (NullPointerException nullPointerException) {
uiApp.addMessage(new ApplicationMessage("UIActionForm.msg.unable-add", null, ApplicationMessage.WARNING));
return;
} catch (NoSuchFieldException ns) {
uiApp.addMessage(new ApplicationMessage("UIActionForm.msg.lifecycle-invalid", null, ApplicationMessage.WARNING));
return;
} catch (Exception e) {
uiApp.addMessage(new ApplicationMessage("UIActionForm.msg.unable-add", null, ApplicationMessage.WARNING));
return;
} finally {
if (actionForm.isEditInList_) {
actionForm.releaseLock();
actionForm.isEditInList_ = false;
}
}
}
}
@SuppressWarnings("unchecked")
static public class ShowComponentActionListener extends EventListener<UIActionForm> {
public void execute(Event<UIActionForm> event) throws Exception {
UIActionForm uiForm = event.getSource();
UIContainer uiContainer = null;
uiForm.isShowingComponent = true;
if(uiForm.isEditInList_) {
uiContainer = uiForm.getAncestorOfType(UIActionListContainer.class);
} else {
uiContainer = uiForm.getParent();
}
String fieldName = event.getRequestContext().getRequestParameter(OBJECTID);
Map fieldPropertiesMap = uiForm.componentSelectors.get(fieldName);
String classPath = (String)fieldPropertiesMap.get("selectorClass");
String rootPath = (String)fieldPropertiesMap.get("rootPath");
ClassLoader cl = Thread.currentThread().getContextClassLoader();
Class clazz = Class.forName(classPath, true, cl);
UIComponent uiComp = uiContainer.createUIComponent(clazz, null, null);
String selectorParams = (String)fieldPropertiesMap.get("selectorParams");
if(uiComp instanceof UIOneNodePathSelector) {
UIJCRExplorer explorer = uiForm.getAncestorOfType(UIJCRExplorer.class);
String repositoryName = explorer.getRepositoryName();
SessionProvider provider = explorer.getSessionProvider();
String wsFieldName = (String)fieldPropertiesMap.get("workspaceField");
String wsName = explorer.getCurrentWorkspace();
if(wsFieldName != null && wsFieldName.length() > 0) {
wsName = (String)uiForm.<UIFormInputBase>getUIInput(wsFieldName).getValue();
((UIOneNodePathSelector)uiComp).setIsDisable(wsName, true);
}
if(selectorParams != null) {
String[] arrParams = selectorParams.split(",");
if(arrParams.length == 4) {
((UIOneNodePathSelector)uiComp).setAcceptedNodeTypesInPathPanel(new String[] {Utils.NT_FILE});
wsName = arrParams[1];
rootPath = arrParams[2];
((UIOneNodePathSelector)uiComp).setIsDisable(wsName, true);
if(arrParams[3].indexOf(";") > -1) {
((UIOneNodePathSelector)uiComp).setAcceptedMimeTypes(arrParams[3].split(";"));
} else {
((UIOneNodePathSelector)uiComp).setAcceptedMimeTypes(new String[] {arrParams[3]});
}
}
}
if(rootPath == null) rootPath = "/";
((UIOneNodePathSelector)uiComp).setRootNodeLocation(repositoryName, wsName, rootPath);
((UIOneNodePathSelector)uiComp).setShowRootPathSelect(true);
((UIOneNodePathSelector)uiComp).init(provider);
} else if (uiComp instanceof UINodeTypeSelector) {
UIJCRExplorer explorer = uiForm.getAncestorOfType(UIJCRExplorer.class);
((UINodeTypeSelector)uiComp).setRepositoryName(explorer.getRepositoryName());
UIFormMultiValueInputSet uiFormMultiValueInputSet = uiForm.getChildById(fieldName);
List values = uiFormMultiValueInputSet.getValue();
((UINodeTypeSelector)uiComp).init(1, values);
}
if(uiForm.isEditInList_) ((UIActionListContainer) uiContainer).initPopup(uiComp);
else ((UIActionContainer)uiContainer).initPopup(uiComp);
String param = "returnField=" + fieldName;
String[] params = selectorParams == null ? new String[] { param } : new String[] { param,
"selectorParams=" + selectorParams };
((ComponentSelector)uiComp).setSourceComponent(uiForm, params);
if(uiForm.isAddNew_) {
UIContainer uiParent = uiContainer.getParent();
uiParent.setRenderedChild(uiContainer.getId());
}
event.getRequestContext().addUIComponentToUpdateByAjax(uiContainer);
}
}
static public class RemoveReferenceActionListener extends EventListener<UIActionForm> {
public void execute(Event<UIActionForm> event) throws Exception {
UIActionForm uiForm = event.getSource();
uiForm.isRemovePreference = true;
String fieldName = event.getRequestContext().getRequestParameter(OBJECTID);
UIComponent uicomponent = uiForm.getChildById(fieldName);
if (UIFormStringInput.class.isInstance(uicomponent))
((UIFormStringInput)uicomponent).setValue(null);
else if (UIFormMultiValueInputSet.class.isInstance(uicomponent)) {
((UIFormMultiValueInputSet)uicomponent).setValue(new ArrayList<String>());
}
event.getRequestContext().addUIComponentToUpdateByAjax(uiForm.getParent());
}
}
public static class AddActionListener extends EventListener<UIActionForm> {
public void execute(Event<UIActionForm> event) throws Exception {
UIActionForm uiForm = event.getSource();
event.getRequestContext().addUIComponentToUpdateByAjax(uiForm.getParent());
}
}
public static class RemoveActionListener extends EventListener<UIActionForm> {
public void execute(Event<UIActionForm> event) throws Exception {
UIActionForm uiForm = event.getSource();
uiForm.isRemoveActionField = true;
event.getRequestContext().addUIComponentToUpdateByAjax(uiForm.getParent());
}
}
static public class BackActionListener extends EventListener<UIActionForm> {
public void execute(Event<UIActionForm> event) throws Exception {
UIActionForm uiForm = event.getSource();
UIActionManager uiManager = uiForm.getAncestorOfType(UIActionManager.class);
if(uiForm.isAddNew_) {
uiManager.setRenderedChild(UIActionListContainer.class);
event.getRequestContext().addUIComponentToUpdateByAjax(uiManager);
} else {
if(uiForm.isEditInList_) {
uiForm.releaseLock();
uiManager.setRenderedChild(UIActionListContainer.class);
uiManager.setDefaultConfig();
UIActionListContainer uiActionListContainer = uiManager.getChild(UIActionListContainer.class);
UIPopupWindow uiPopup = uiActionListContainer.findComponentById("editActionPopup");
uiPopup.setShow(false);
uiPopup.setRendered(false);
uiForm.isEditInList_ = false;
event.getRequestContext().addUIComponentToUpdateByAjax(uiManager);
} else {
UIJCRExplorer uiExplorer = uiForm.getAncestorOfType(UIJCRExplorer.class);
uiExplorer.cancelAction();
}
}
}
}
}