View Javadoc
1   /*
2    * Copyright (C) 2003-2007 eXo Platform SAS.
3    *
4    * This program is free software; you can redistribute it and/or
5    * modify it under the terms of the GNU Affero General Public License
6    * as published by the Free Software Foundation; either version 3
7    * of the License, or (at your option) any later version.
8    *
9    * This program is distributed in the hope that it will be useful,
10   * but WITHOUT ANY WARRANTY; without even the implied warranty of
11   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12   * GNU General Public License for more details.
13   *
14   * You should have received a copy of the GNU General Public License
15   * along with this program; if not, see<http://www.gnu.org/licenses/>.
16   */
17  package org.exoplatform.ecm.webui.component.admin.script;
18  
19  import org.exoplatform.ecm.jcr.model.VersionNode;
20  import org.exoplatform.ecm.webui.component.admin.script.UIScriptList.ScriptData;
21  import org.exoplatform.ecm.webui.form.validator.ECMNameValidator;
22  import org.exoplatform.ecm.webui.form.validator.XSSValidator;
23  import org.exoplatform.ecm.webui.utils.Utils;
24  import org.exoplatform.services.cms.scripts.ScriptService;
25  import org.exoplatform.services.log.ExoLogger;
26  import org.exoplatform.services.log.Log;
27  import org.exoplatform.services.wcm.core.NodetypeConstant;
28  import org.exoplatform.services.wcm.utils.WCMCoreUtils;
29  import org.exoplatform.web.application.ApplicationMessage;
30  import org.exoplatform.webui.config.annotation.ComponentConfig;
31  import org.exoplatform.webui.config.annotation.EventConfig;
32  import org.exoplatform.webui.core.UIApplication;
33  import org.exoplatform.webui.core.UIPopupComponent;
34  import org.exoplatform.webui.core.UIPopupWindow;
35  import org.exoplatform.webui.core.lifecycle.UIFormLifecycle;
36  import org.exoplatform.webui.core.model.SelectItemOption;
37  import org.exoplatform.webui.event.Event;
38  import org.exoplatform.webui.event.Event.Phase;
39  import org.exoplatform.webui.event.EventListener;
40  import org.exoplatform.webui.form.UIForm;
41  import org.exoplatform.webui.form.UIFormSelectBox;
42  import org.exoplatform.webui.form.UIFormStringInput;
43  import org.exoplatform.webui.form.UIFormTextAreaInput;
44  import org.exoplatform.webui.form.input.UICheckBoxInput;
45  import org.exoplatform.webui.form.validator.MandatoryValidator;
46  import javax.jcr.AccessDeniedException;
47  import javax.jcr.Node;
48  import javax.jcr.PathNotFoundException;
49  import javax.jcr.version.VersionHistory;
50  import java.util.ArrayList;
51  import java.util.List;
52  
53  /**
54   * Created by The eXo Platform SARL
55   * September 27, 2006 10:27:15 AM
56   */
57  
58  @ComponentConfig(
59      lifecycle = UIFormLifecycle.class,
60      template = "system:/groovy/webui/form/UIForm.gtmpl",
61      events = {
62        @EventConfig(listeners = UIScriptForm.SaveActionListener.class),
63        @EventConfig(phase=Phase.DECODE, listeners = UIScriptForm.RestoreActionListener.class),
64        @EventConfig(phase=Phase.DECODE, listeners = UIScriptForm.CancelActionListener.class),
65        @EventConfig(phase=Phase.DECODE, listeners = UIScriptForm.RefreshActionListener.class)
66      }
67  )
68  public class UIScriptForm extends UIForm implements UIPopupComponent {
69  
70    private static final Log LOG = ExoLogger.getLogger(UIScriptForm.class.getName());
71    
72    final static public String FIELD_SELECT_VERSION = "selectVersion" ;
73    final static public String FIELD_SCRIPT_CONTENT = "scriptContent" ;
74    final static public String FIELD_SCRIPT_NAME = "scriptName" ;
75    final static public String FIELD_SCRIPT_LABEL = "scriptLabel" ;
76    final static public String FIELD_ENABLE_VERSION = "enableVersion" ;
77    final static public String SCRIPT_FILE_TYPE = ".groovy" ;
78  
79    private List<String> listVersion = new ArrayList<String>() ;
80    private boolean isAddNew_ = true ;
81    private ScriptService scriptService;
82  
83    public UIScriptForm() throws Exception {
84      scriptService = WCMCoreUtils.getService(ScriptService.class);
85  
86      List<SelectItemOption<String>> options = new ArrayList<SelectItemOption<String>>() ;
87      UIFormSelectBox versions =
88        new UIFormSelectBox(FIELD_SELECT_VERSION , FIELD_SELECT_VERSION, options) ;
89      UIFormTextAreaInput contents =
90        new UIFormTextAreaInput(FIELD_SCRIPT_CONTENT , FIELD_SCRIPT_CONTENT, null) ;
91      contents.addValidator(MandatoryValidator.class) ;
92      UICheckBoxInput isVersion = new UICheckBoxInput(FIELD_ENABLE_VERSION , FIELD_ENABLE_VERSION, null) ;
93      UIFormStringInput scriptLabel = new UIFormStringInput(FIELD_SCRIPT_LABEL, FIELD_SCRIPT_LABEL, null) ;
94      UIFormStringInput scriptName = new UIFormStringInput(FIELD_SCRIPT_NAME, FIELD_SCRIPT_NAME, null) ;
95      scriptName.addValidator(MandatoryValidator.class).addValidator(ECMNameValidator.class).addValidator(XSSValidator.class);
96      versions.setOnChange("Change") ;
97      versions.setRendered(false) ;
98      isVersion.setRendered(false) ;
99      addUIFormInput(versions) ;
100     addUIFormInput(contents) ;
101     addUIFormInput(isVersion) ;
102     addUIFormInput(scriptLabel) ;
103     addUIFormInput(scriptName) ;
104   }
105 
106   private VersionNode getRootVersion(Node node) throws Exception{
107     VersionHistory vH = node.getVersionHistory() ;
108     return (vH == null) ? null : new VersionNode(vH.getRootVersion(), node.getSession()) ;
109   }
110 
111   private List<String> getNodeVersions(List<VersionNode> children) throws Exception {
112     List<VersionNode> child = new ArrayList<VersionNode>() ;
113     for(int i = 0; i < children.size(); i ++){
114       listVersion.add(children.get(i).getName());
115       child = children.get(i).getChildren() ;
116       if(!child.isEmpty()) getNodeVersions(child) ;
117     }
118     return listVersion ;
119   }
120 
121   private List<SelectItemOption<String>> getVersionValues(Node node) throws Exception {
122     List<SelectItemOption<String>> options = new ArrayList<SelectItemOption<String>>() ;
123     List<VersionNode> children = getRootVersion(node).getChildren() ;
124     listVersion.clear() ;
125     List<String> versionList = getNodeVersions(children) ;
126     for(int i = 0; i < versionList.size(); i++) {
127       for(int j = i + 1; j < versionList.size(); j ++) {
128         if(Integer.parseInt(versionList.get(j)) < Integer.parseInt(versionList.get(i))) {
129           String temp = versionList.get(i) ;
130           versionList.set(i, versionList.get(j))  ;
131           versionList.set(j, temp) ;
132         }
133       }
134       options.add(new SelectItemOption<String>(versionList.get(i), versionList.get(i))) ;
135     }
136     return options ;
137   }
138 
139   public void update(Node script, boolean isAddNew) throws Exception{
140     isAddNew_ = isAddNew ;
141     if(script != null) {
142       String scriptContent = scriptService.getScriptAsText(script);
143       getUICheckBoxInput(FIELD_ENABLE_VERSION).setRendered(true) ;
144       boolean isVersioned = script.isNodeType(Utils.MIX_VERSIONABLE) ;
145       if(isVersioned) {
146         getUIFormSelectBox(FIELD_SELECT_VERSION).setRendered(true) ;
147         getUIFormSelectBox(FIELD_SELECT_VERSION).setOptions(getVersionValues(script)) ;
148         getUIFormSelectBox(FIELD_SELECT_VERSION).setValue(script.getBaseVersion().getName()) ;
149         getUICheckBoxInput(FIELD_ENABLE_VERSION).setDisabled(true);
150         getUICheckBoxInput(FIELD_ENABLE_VERSION).setChecked(true) ;
151         setActions(new String[]{"Save", "Restore", "Refresh", "Cancel"})  ;
152       } else {
153         getUIFormSelectBox(FIELD_SELECT_VERSION).setRendered(false) ;
154         getUICheckBoxInput(FIELD_ENABLE_VERSION).setDisabled(false) ;
155         getUICheckBoxInput(FIELD_ENABLE_VERSION).setChecked(false) ;
156         setActions( new String[]{"Save", "Refresh", "Cancel"}) ;
157       }
158       getUIFormTextAreaInput(FIELD_SCRIPT_CONTENT).setValue(scriptContent) ;
159       Node content = script.getNode(NodetypeConstant.JCR_CONTENT);
160       String scriptLabel = content.getProperty(NodetypeConstant.DC_DESCRIPTION).getValues()[0].getString();
161       getUIStringInput(FIELD_SCRIPT_LABEL).setValue(scriptLabel) ;
162       getUIStringInput(FIELD_SCRIPT_NAME).setValue(script.getName()) ;
163       getUIStringInput(FIELD_SCRIPT_NAME).setDisabled(true) ;
164       return ;
165     }
166     if(!isAddNew_) {
167       getUIFormTextAreaInput(FIELD_SCRIPT_CONTENT).setValue(null) ;
168       return ;
169     }
170     getUIFormSelectBox(FIELD_SELECT_VERSION).setRendered(false) ;
171     getUICheckBoxInput(FIELD_ENABLE_VERSION).setRendered(false) ;
172     getUICheckBoxInput(FIELD_ENABLE_VERSION).setChecked(false) ;
173     getUIStringInput(FIELD_SCRIPT_LABEL).setValue(null) ;
174     getUIStringInput(FIELD_SCRIPT_NAME).setDisabled(false);
175     getUIStringInput(FIELD_SCRIPT_NAME).setValue(null) ;
176     getUIFormTextAreaInput(FIELD_SCRIPT_CONTENT).setValue(null) ;
177     setActions( new String[]{"Save", "Refresh", "Cancel"}) ;
178   }
179 
180   public void activate() { }
181   public void deActivate() { }
182 
183   static public class SaveActionListener extends EventListener<UIScriptForm> {
184     public void execute(Event<UIScriptForm> event) throws Exception {
185       UIScriptForm uiForm = event.getSource() ;
186       ScriptService scriptService = uiForm.getApplicationComponent(ScriptService.class) ;
187       UIApplication uiApp = uiForm.getAncestorOfType(UIApplication.class) ;
188       StringBuilder name = new StringBuilder();
189       name.append(uiForm.getUIStringInput(FIELD_SCRIPT_NAME).getValue().trim());
190       String content = uiForm.getUIFormTextAreaInput(FIELD_SCRIPT_CONTENT).getValue().trim();
191       String label = uiForm.getUIStringInput(FIELD_SCRIPT_LABEL).getValue();
192      
193       if (name.indexOf(SCRIPT_FILE_TYPE) < 0) {
194         name.append(SCRIPT_FILE_TYPE);
195       }
196       UIScriptList currentList = null ;
197       UIScriptManager uiManager = uiForm.getAncestorOfType(UIScriptManager.class) ;
198       List<String> listScript = new ArrayList<String>() ;
199       List<ScriptData> scriptData = new ArrayList<ScriptData>() ;
200       String namePrefix = null ;
201       
202       UIScriptContainer uiContainer = uiManager.getChildById(uiManager.getSelectedTabId());
203       currentList = uiContainer.getChild(UIScriptList.class);
204       namePrefix = currentList.getScriptCategory() ;
205       String subNamePrefix = namePrefix.substring(namePrefix.lastIndexOf("/") + 1, namePrefix.length()) ;
206       scriptData = currentList.getScript(subNamePrefix) ;
207         
208         
209       for(ScriptData data : scriptData) {
210         listScript.add(data.getName()) ;
211       }
212       if(listScript.contains(name.toString()) && uiForm.isAddNew_) {
213         Object[] args = { name } ;
214         ApplicationMessage appMessage = 
215           new ApplicationMessage("UIScriptForm.msg.name-exist", args, ApplicationMessage.WARNING);
216         appMessage.setArgsLocalized(false);
217         uiApp.addMessage(appMessage) ;        
218         return ;
219       }
220       boolean isEnableVersioning = uiForm.getUICheckBoxInput(FIELD_ENABLE_VERSION).isChecked() ;
221 	    if(label == null) label = name.toString();
222 	    else label = label.trim();
223       if(uiForm.isAddNew_ || !isEnableVersioning) {
224         try {
225           scriptService.addScript(namePrefix + "/" + name, label, content, WCMCoreUtils.getSystemSessionProvider());
226         } catch(AccessDeniedException ace) {
227           uiApp.addMessage(new ApplicationMessage("UIECMAdminControlPanel.msg.access-denied", null,
228                                                   ApplicationMessage.WARNING)) ;
229           
230           return ;
231         }
232       } else {
233         try {
234           Node node = currentList.getScriptNode(currentList.getTemplateFilter(), name.toString()) ;
235           if(!node.isNodeType(Utils.MIX_VERSIONABLE)) node.addMixin(Utils.MIX_VERSIONABLE) ;
236           else node.checkout() ;
237           scriptService.addScript(namePrefix + "/" + name, label, content, WCMCoreUtils.getSystemSessionProvider());
238           node.save() ;
239           node.checkin() ;
240         } catch (PathNotFoundException pathNotFoundException) {
241           Object[] args = { namePrefix };
242           uiApp.addMessage(new ApplicationMessage("UIScriptForm.msg.PathNotFoundException", args,
243               ApplicationMessage.WARNING));
244           
245           return;
246         }
247       }
248       uiForm.reset() ;      
249       UIPopupWindow uiPopup = uiManager.getChild(UIPopupWindow.class);
250       uiPopup.setRendered(false);
251       event.getRequestContext().addUIComponentToUpdateByAjax(currentList) ;
252       currentList.refresh(currentList.getTemplateFilter(),1) ;
253       event.getRequestContext().addUIComponentToUpdateByAjax(uiManager) ;
254     }
255   }
256 
257   static public class RestoreActionListener extends EventListener<UIScriptForm> {
258     public void execute(Event<UIScriptForm> event) throws Exception {    
259       UIScriptForm uiForm = event.getSource();
260       String name = uiForm.getUIStringInput(FIELD_SCRIPT_NAME).getValue() ;
261       UIScriptManager uiManager = uiForm.getAncestorOfType(UIScriptManager.class) ;
262       UIScriptContainer uiContainer = uiManager.getChildById(uiManager.getSelectedTabId());
263 	    UIScriptList uiScriptList = uiContainer.getChild(UIScriptList.class);
264           
265       try {
266         Node node = uiScriptList.getScriptNode(uiScriptList.getTemplateFilter(), name);
267         String version = uiForm.getUIFormSelectBox(FIELD_SELECT_VERSION).getValue();
268         String baseVersion = node.getBaseVersion().getName() ;
269         if(!version.equals(baseVersion)) {
270           node.checkout() ;
271           node.restore(version, true) ;
272           uiScriptList.refresh(uiScriptList.getTemplateFilter(), 1) ;
273         }  
274         UIPopupWindow uiPopup = uiManager.getChild(UIPopupWindow.class);
275         uiPopup.setRendered(false);
276         event.getRequestContext().addUIComponentToUpdateByAjax(uiManager) ;
277       } catch (PathNotFoundException pne) {
278         if (LOG.isWarnEnabled()) {
279           LOG.warn(pne.getMessage());
280         }
281       }
282     }
283   } 
284 
285   static public class RefreshActionListener extends EventListener<UIScriptForm> {
286     public void execute(Event<UIScriptForm> event) throws Exception {
287       UIScriptForm uiForm = event.getSource() ;
288       String scriptName = uiForm.getUIStringInput(UIScriptForm.FIELD_SCRIPT_NAME).getValue() ;
289       if(uiForm.isAddNew_) {
290         uiForm.update(null, true) ;
291       } else {
292         UIScriptManager uiScriptManager = uiForm.getAncestorOfType(UIScriptManager.class);
293         UIScriptContainer uiScriptContainer = uiScriptManager.getChildById(uiScriptManager.getSelectedTabId());
294         UIScriptList uiScriptList = uiScriptContainer.getChild(UIScriptList.class);        
295         try {
296           Node script = uiScriptList.getScriptNode(uiScriptList.getTemplateFilter(), scriptName) ;
297           uiForm.update(script, false) ;
298         } catch (PathNotFoundException pathNotFoundException) {
299           String namePrefix = uiScriptList.getScriptCategory();
300           Object[] args = { namePrefix };
301           UIApplication uiApp = uiForm.getAncestorOfType(UIApplication.class);
302           uiApp.addMessage(new ApplicationMessage("UIScriptForm.msg.PathNotFoundException", args,
303               ApplicationMessage.WARNING));          
304           return;
305         }
306       }
307       event.getRequestContext().addUIComponentToUpdateByAjax(uiForm.getAncestorOfType(UIScriptManager.class)) ;
308     }
309   }
310 
311   static public class CancelActionListener extends EventListener<UIScriptForm> {
312     public void execute(Event<UIScriptForm> event) throws Exception {
313       UIScriptForm uiForm = event.getSource();      
314       uiForm.reset() ;     
315       UIScriptManager uiManager = uiForm.getAncestorOfType(UIScriptManager.class) ;
316       UIPopupWindow uiPopup = uiManager.getChildById(UIScriptManager.POPUP_TEMPLATE_ID);
317       uiPopup.setRendered(false);
318       event.getRequestContext().addUIComponentToUpdateByAjax(uiManager) ;
319     }
320   }
321 }