View Javadoc
1   /*
2    * Copyright (C) 2003-2009 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.wcm.webui.fastcontentcreator.config.action;
18  
19  import org.exoplatform.ecm.resolver.JCRResourceResolver;
20  import org.exoplatform.ecm.utils.lock.LockUtil;
21  import org.exoplatform.ecm.webui.form.UIDialogForm;
22  import org.exoplatform.ecm.webui.nodetype.selector.UINodeTypeSelector;
23  import org.exoplatform.ecm.webui.selector.ComponentSelector;
24  import org.exoplatform.ecm.webui.selector.UISelectable;
25  import org.exoplatform.ecm.webui.tree.selectone.UIOneNodePathSelector;
26  import org.exoplatform.ecm.webui.utils.DialogFormUtil;
27  import org.exoplatform.ecm.webui.utils.PermissionUtil;
28  import org.exoplatform.portal.webui.util.Util;
29  import org.exoplatform.resolver.ResourceResolver;
30  import org.exoplatform.services.cms.CmsService;
31  import org.exoplatform.services.cms.JcrInputProperty;
32  import org.exoplatform.services.cms.actions.ActionServiceContainer;
33  import org.exoplatform.services.cms.impl.DMSConfiguration;
34  import org.exoplatform.services.cms.impl.DMSRepositoryConfiguration;
35  import org.exoplatform.services.cms.templates.TemplateService;
36  import org.exoplatform.services.wcm.utils.WCMCoreUtils;
37  import org.exoplatform.wcm.webui.Utils;
38  import org.exoplatform.wcm.webui.fastcontentcreator.UIFCCConstant;
39  import org.exoplatform.wcm.webui.fastcontentcreator.UIFCCPortlet;
40  import org.exoplatform.wcm.webui.fastcontentcreator.UIFCCUtils;
41  import org.exoplatform.wcm.webui.fastcontentcreator.config.UIFCCConfig;
42  import org.exoplatform.web.application.ApplicationMessage;
43  import org.exoplatform.webui.application.WebuiRequestContext;
44  import org.exoplatform.webui.config.annotation.ComponentConfig;
45  import org.exoplatform.webui.config.annotation.EventConfig;
46  import org.exoplatform.webui.core.UIApplication;
47  import org.exoplatform.webui.core.UIComponent;
48  import org.exoplatform.webui.core.UIContainer;
49  import org.exoplatform.webui.core.UIGrid;
50  import org.exoplatform.webui.core.lifecycle.UIFormLifecycle;
51  import org.exoplatform.webui.event.Event;
52  import org.exoplatform.webui.event.Event.Phase;
53  import org.exoplatform.webui.event.EventListener;
54  import org.exoplatform.webui.form.UIFormInputBase;
55  import org.exoplatform.webui.form.UIFormMultiValueInputSet;
56  import org.exoplatform.webui.form.UIFormStringInput;
57  
58  import javax.jcr.Node;
59  import javax.jcr.RepositoryException;
60  import java.util.ArrayList;
61  import java.util.List;
62  import java.util.Map;
63  
64  /**
65   * Created by The eXo Platform SAS
66   * Author : eXoPlatform
67   * chuong.phan@exoplatform.com, phan.le.thanh.chuong@gmail.com
68   * Jun 25, 2009
69   */
70  @ComponentConfig(lifecycle = UIFormLifecycle.class, events = {
71      @EventConfig(listeners = UIFCCActionForm.SaveActionListener.class),
72      @EventConfig(listeners = UIDialogForm.OnchangeActionListener.class, phase = Phase.DECODE),
73      @EventConfig(listeners = UIFCCActionForm.CloseActionListener.class, phase = Phase.DECODE),
74      @EventConfig(listeners = UIFCCActionForm.ShowComponentActionListener.class, phase = Phase.DECODE),
75      @EventConfig(listeners = UIFCCActionForm.RemoveReferenceActionListener.class,
76                   confirm = "DialogFormField.msg.confirm-delete", phase = Phase.DECODE) })
77  public class UIFCCActionForm extends UIDialogForm implements UISelectable {
78  
79    /** The parent path_. */
80    private String parentPath_ ;
81  
82    /** The node type name_. */
83    private String nodeTypeName_ = null ;
84  
85    /** The script path_. */
86    private String scriptPath_ = null ;
87  
88    /** The root path_. */
89    private String rootPath_ = null;
90  
91    /** The is add new. */
92    private boolean isAddNew = false;
93  
94    /** The Constant EXO_ACTIONS. */
95    private static final String EXO_ACTIONS = "exo:actions";
96  
97    /**
98     * Instantiates a new uIFCC action form.
99     *
100    * @throws Exception the exception
101    */
102   public UIFCCActionForm() throws Exception {setActions(new String[]{"Save","Close"}) ;}
103 
104   /**
105    * Creates the new action.
106    *
107    * @param parentNode the parent node
108    * @param actionType the action type
109    * @param isAddNew the is add new
110    *
111    * @throws Exception the exception
112    */
113   public void createNewAction(Node parentNode, String actionType, boolean isAddNew) throws Exception {
114     reset() ;
115     parentPath_ = parentNode.getPath() ;
116     nodeTypeName_ = actionType;
117     componentSelectors.clear() ;
118     properties.clear() ;
119     this.isAddNew = isAddNew;
120     getChildren().clear() ;
121   }
122 
123   /**
124    * Gets the parent node.
125    *
126    * @return the parent node
127    *
128    * @throws Exception the exception
129    */
130   private Node getParentNode(Node node) throws Exception{
131     return (Node) node.getSession().getItem(parentPath_) ;
132   }
133 
134   /* (non-Javadoc)
135    * @see org.exoplatform.ecm.webui.form.UIDialogForm#renderField(java.lang.String)
136    */
137   public void renderField(String name) throws Exception {
138     UIComponent uiInput = findComponentById(name);
139     if ("homePath".equals(name)) {
140       String homPath = UIFCCUtils.getPreferenceWorkspace() + ":" + parentPath_;
141       if (homPath.endsWith("/"))
142         homPath = homPath.substring(0, homPath.length() - 1);
143       ((UIFormStringInput) uiInput).setValue(homPath);
144     }
145     if ("targetPath".equals(name) && (isOnchange()) && !isUpdateSelect) {
146       ((UIFormStringInput) uiInput).reset();
147     }
148     super.renderField(name);
149   }
150 
151   /* (non-Javadoc)
152    * @see org.exoplatform.ecm.webui.selector.UISelectable#doSelect(java.lang.String, java.lang.Object)
153    */
154   public void doSelect(String selectField, Object value) throws Exception {
155     isUpdateSelect = true ;
156     //getUIStringInput(selectField).setValue(value.toString()) ;
157     UIComponent uicomponent = getChildById(selectField);
158     if (UIFormStringInput.class.isInstance(uicomponent))
159       ((UIFormStringInput)uicomponent).setValue(value.toString());
160     else if (UIFormMultiValueInputSet.class.isInstance(uicomponent)) {
161       ((UIFormMultiValueInputSet)uicomponent).setValue((ArrayList<String>)value);
162     }
163   }
164 
165   /**
166    * Gets the current path.
167    *
168    * @return the current path
169    *
170    * @throws Exception the exception
171    */
172   public String getCurrentPath() throws Exception {
173     UIFCCPortlet fastContentCreatorPortlet = getAncestorOfType(UIFCCPortlet.class);
174     UIFCCConfig fastContentCreatorConfig = fastContentCreatorPortlet.getChild(UIFCCConfig.class);
175     return fastContentCreatorConfig.getSavedLocationNode().getPath();
176   }
177 
178   /*
179    * (non-Javadoc)
180    * @see
181    * org.exoplatform.webui.core.UIComponent#getTemplateResourceResolver(org.
182    * exoplatform.webui.application.WebuiRequestContext, java.lang.String)
183    */
184   public ResourceResolver getTemplateResourceResolver(WebuiRequestContext context, String template) {
185     DMSConfiguration dmsConfiguration = getApplicationComponent(DMSConfiguration.class);
186     DMSRepositoryConfiguration repositoryConfiguration = dmsConfiguration.getConfig();
187     return new JCRResourceResolver(repositoryConfiguration.getSystemWorkspace());
188   }
189 
190   /* (non-Javadoc)
191    * @see org.exoplatform.ecm.webui.form.UIDialogForm#getTemplate()
192    */
193   public String getTemplate() { return getDialogPath() ; }
194 
195   /**
196    * Gets the dialog path.
197    *
198    * @return the dialog path
199    */
200   public String getDialogPath() {
201     repositoryName = UIFCCUtils.getPreferenceRepository() ;
202     TemplateService templateService = getApplicationComponent(TemplateService.class) ;
203     String userName = Util.getPortalRequestContext().getRemoteUser() ;
204     String dialogPath = null ;
205     if (nodeTypeName_ != null) {
206       try {
207         dialogPath = templateService.getTemplatePathByUser(true, nodeTypeName_, userName);
208       } catch (Exception e){
209         Utils.createPopupMessage(this, "UIFCCForm.msg.get-dialog-path", null, ApplicationMessage.ERROR);
210       }
211     }
212     return dialogPath ;
213   }
214 
215   /**
216    * Gets the repository name.
217    *
218    * @return the repository name
219    */
220   public String getRepositoryName() { return repositoryName; }
221 
222   /**
223    * Gets the template node type.
224    *
225    * @return the template node type
226    */
227   public String getTemplateNodeType() { return nodeTypeName_ ; }
228 
229   /**
230    * Gets the path.
231    *
232    * @return the path
233    */
234   public String getPath() { return scriptPath_ ; }
235 
236   /**
237    * Sets the root path.
238    *
239    * @param rootPath the new root path
240    */
241   public void setRootPath(String rootPath){
242    rootPath_ = rootPath;
243   }
244 
245   /**
246    * Gets the root path.
247    *
248    * @return the root path
249    */
250   public String getRootPath(){return rootPath_;}
251 
252   /* (non-Javadoc)
253    * @see org.exoplatform.ecm.webui.form.UIDialogForm#onchange(org.exoplatform.webui.event.Event)
254    */
255   public void onchange(Event<?> event) throws Exception {
256     if(!isAddNew){
257       event.getRequestContext().addUIComponentToUpdateByAjax(getParent()) ;
258       return;
259     }
260   }
261 
262   /**
263    * The listener interface for receiving saveAction events.
264    * The class that is interested in processing a saveAction
265    * event implements this interface, and the object created
266    * with that class is registered with a component using the
267    * component's <code>addSaveActionListener</code> method. When
268    * the saveAction event occurs, that object's appropriate
269    * method is invoked.
270    */
271   static public class SaveActionListener extends EventListener<UIFCCActionForm> {
272 
273     /* (non-Javadoc)
274      * @see org.exoplatform.webui.event.EventListener#execute(org.exoplatform.webui.event.Event)
275      */
276     public void execute(Event<UIFCCActionForm> event) throws Exception {
277       UIFCCActionForm fccActionForm = event.getSource();
278       UIApplication uiApp = fccActionForm.getAncestorOfType(UIApplication.class) ;
279 
280       // Get current node
281       UIFCCPortlet fastContentCreatorPortlet = fccActionForm.getAncestorOfType(UIFCCPortlet.class);
282       UIFCCConfig fastContentCreatorConfig = fastContentCreatorPortlet.getChild(UIFCCConfig.class) ;
283       Node currentNode = fastContentCreatorConfig.getSavedLocationNode();
284 
285       // Check permission for current node
286       if (!PermissionUtil.canAddNode(currentNode) || !PermissionUtil.canSetProperty(currentNode)) {
287         uiApp.addMessage(new ApplicationMessage("UIFastContentCreatorActionForm.msg.no-permission-add",
288                                                 null));
289         
290         return;
291       }
292       UIFCCActionList fastContentCreatorActionList = null;
293       Map<String, JcrInputProperty> sortedInputs = DialogFormUtil.prepareMap(fccActionForm.getChildren(),
294                                                                              fccActionForm.getInputProperties(),
295                                                                              fccActionForm.getInputOptions());
296       // Update action node:
297       if(!fccActionForm.isAddNew) {
298         CmsService cmsService = fccActionForm.getApplicationComponent(CmsService.class) ;
299         Node storedHomeNode = fccActionForm.getParentNode(currentNode).getNode("exo:actions");
300         cmsService.storeNode(fccActionForm.nodeTypeName_, storedHomeNode, sortedInputs, false) ;
301         storedHomeNode.getSession().save();
302       } else {
303 
304         // Add lock token if node is locked
305         if (currentNode.isLocked()) {
306           String lockToken = LockUtil.getLockToken(currentNode);
307           if(lockToken != null) {
308             currentNode.getSession().addLockToken(lockToken);
309           }
310         }
311 
312         try{
313           JcrInputProperty rootProp = sortedInputs.get("/node");
314           if(rootProp == null) {
315             rootProp = new JcrInputProperty();
316             rootProp.setJcrPath("/node");
317             rootProp.setValue((sortedInputs.get("/node/exo:name")).getValue()) ;
318             sortedInputs.put("/node", rootProp) ;
319           } else {
320             rootProp.setValue((sortedInputs.get("/node/exo:name")).getValue());
321           }
322           String actionName = (String)(sortedInputs.get("/node/exo:name")).getValue() ;
323           Node parentNode = fccActionForm.getParentNode(currentNode);
324 
325           // Check if action existed
326           if (parentNode.hasNode(EXO_ACTIONS)) {
327             if (parentNode.getNode(EXO_ACTIONS).hasNode(actionName)) {
328               Object[] args = { actionName };
329               uiApp.addMessage(new ApplicationMessage("UIFastContentCreatorActionForm.msg.existed-action",
330                                                       args,
331                                                       ApplicationMessage.WARNING));
332               
333               return;
334             }
335           }
336 
337           // Check parent node
338           if(parentNode.isNew()) {
339             String[] args = {parentNode.getPath()} ;
340             uiApp.addMessage(new ApplicationMessage("UIFastContentCreatorActionForm.msg.unable-add-action",args)) ;
341             
342             return;
343           }
344 
345           // Save to database
346           ActionServiceContainer actionServiceContainer = fccActionForm.getApplicationComponent(ActionServiceContainer.class);
347           actionServiceContainer.addAction(parentNode, fccActionForm.nodeTypeName_, sortedInputs);
348           fccActionForm.setIsOnchange(false) ;
349           parentNode.getSession().save() ;
350 
351           // Create action
352           fccActionForm.createNewAction(fastContentCreatorConfig.getSavedLocationNode(),
353                                         fccActionForm.nodeTypeName_,
354                                         true);
355           fastContentCreatorActionList = fastContentCreatorConfig.findFirstComponentOfType(UIFCCActionList.class);
356           fastContentCreatorActionList.updateGrid(parentNode,
357                                                   fastContentCreatorActionList.getChild(UIGrid.class)
358                                                                               .getUIPageIterator()
359                                                                               .getCurrentPage());
360           fccActionForm.reset() ;
361         } catch(RepositoryException repo) {
362           String key = "UIFastContentCreatorActionForm.msg.repository-exception" ;
363           uiApp.addMessage(new ApplicationMessage(key, null, ApplicationMessage.WARNING)) ;
364           
365           return;
366         } catch(NumberFormatException nume) {
367           String key = "UIFastContentCreatorActionForm.msg.numberformat-exception" ;
368           uiApp.addMessage(new ApplicationMessage(key, null, ApplicationMessage.WARNING)) ;
369           
370           return;
371         } catch (NullPointerException nullPointerException) {
372           uiApp.addMessage(new ApplicationMessage("UIFastContentCreatorActionForm.msg.unable-add",
373                                                   null,
374                                                   ApplicationMessage.WARNING));
375           
376           return;
377         } catch (Exception e) {
378           uiApp.addMessage(new ApplicationMessage("UIFastContentCreatorActionForm.msg.unable-add",
379                                                   null,
380                                                   ApplicationMessage.WARNING));
381           
382           return;
383         }
384       }
385       Utils.closePopupWindow(fccActionForm, UIFCCConstant.ACTION_POPUP_WINDOW);
386     }
387   }
388 
389   /**
390    * The listener interface for receiving closeAction events.
391    * The class that is interested in processing a closeAction
392    * event implements this interface, and the object created
393    * with that class is registered with a component using the
394    * component's <code>addCloseActionListener</code> method. When
395    * the closeAction event occurs, that object's appropriate
396    * method is invoked.
397    */
398   static public class CloseActionListener extends EventListener<UIFCCActionForm> {
399 
400     /* (non-Javadoc)
401      * @see org.exoplatform.webui.event.EventListener#execute(org.exoplatform.webui.event.Event)
402      */
403     public void execute(Event<UIFCCActionForm> event) throws Exception {
404       UIFCCActionForm fastContentCreatorActionForm = event.getSource();
405       Utils.closePopupWindow(fastContentCreatorActionForm, UIFCCConstant.ACTION_POPUP_WINDOW);
406     }
407   }
408 
409   /**
410    * The listener interface for receiving removeReferenceAction events.
411    * The class that is interested in processing a removeReferenceAction
412    * event implements this interface, and the object created
413    * with that class is registered with a component using the
414    * component's <code>addRemoveReferenceActionListener</code> method. When
415    * the removeReferenceAction event occurs, that object's appropriate
416    * method is invoked.
417    */
418   static public class RemoveReferenceActionListener extends EventListener<UIFCCActionForm> {
419 
420     /* (non-Javadoc)
421      * @see org.exoplatform.webui.event.EventListener#execute(org.exoplatform.webui.event.Event)
422      */
423     public void execute(Event<UIFCCActionForm> event) throws Exception {
424       UIFCCActionForm fastContentCreatorActionForm = event.getSource();
425       fastContentCreatorActionForm.isRemovePreference = true;
426       String fieldName = event.getRequestContext().getRequestParameter(OBJECTID);
427       fastContentCreatorActionForm.getUIStringInput(fieldName).setValue(null);
428       event.getRequestContext()
429            .addUIComponentToUpdateByAjax(fastContentCreatorActionForm.getParent());
430     }
431   }
432 
433   /**
434    * The listener interface for receiving showComponentAction events.
435    * The class that is interested in processing a showComponentAction
436    * event implements this interface, and the object created
437    * with that class is registered with a component using the
438    * component's <code>addShowComponentActionListener</code> method. When
439    * the showComponentAction event occurs, that object's appropriate
440    * method is invoked.
441    */
442   @SuppressWarnings("unchecked")
443   static public class ShowComponentActionListener extends EventListener<UIFCCActionForm> {
444 
445     /* (non-Javadoc)
446      * @see org.exoplatform.webui.event.EventListener#execute(org.exoplatform.webui.event.Event)
447      */
448     public void execute(Event<UIFCCActionForm> event) throws Exception {
449       UIFCCActionForm fastContentCreatorActionForm = event.getSource() ;
450       UIContainer uiContainer = fastContentCreatorActionForm.getParent() ;
451       fastContentCreatorActionForm.isShowingComponent = true;
452       String fieldName = event.getRequestContext().getRequestParameter(OBJECTID) ;
453       Map fieldPropertiesMap = fastContentCreatorActionForm.componentSelectors.get(fieldName) ;
454       String classPath = (String)fieldPropertiesMap.get("selectorClass") ;
455       String rootPath = (String)fieldPropertiesMap.get("rootPath") ;
456       ClassLoader cl = Thread.currentThread().getContextClassLoader() ;
457       Class clazz = Class.forName(classPath, true, cl) ;
458       UIComponent uiComp = uiContainer.createUIComponent(clazz, null, null);
459       String repositoryName = fastContentCreatorActionForm.getRepositoryName();
460       String selectorParams = (String) fieldPropertiesMap.get("selectorParams");
461       if (uiComp instanceof UIOneNodePathSelector) {
462         String wsFieldName = (String) fieldPropertiesMap.get("workspaceField");
463         String wsName = "";
464         if (wsFieldName != null && wsFieldName.length() > 0) {
465           wsName = (String) fastContentCreatorActionForm.<UIFormInputBase> getUIInput(wsFieldName)
466                                                         .getValue();
467           ((UIOneNodePathSelector) uiComp).setIsDisable(wsName, true);
468         }
469         if(selectorParams != null) {
470           String[] arrParams = selectorParams.split(",") ;
471           if(arrParams.length == 4) {
472             ((UIOneNodePathSelector)uiComp).setAcceptedNodeTypesInPathPanel(new String[] {"nt:file"}) ;
473             wsName = arrParams[1];
474             rootPath = arrParams[2];
475             ((UIOneNodePathSelector)uiComp).setIsDisable(wsName, true) ;
476             if(arrParams[3].indexOf(";") > -1) {
477               ((UIOneNodePathSelector)uiComp).setAcceptedMimeTypes(arrParams[3].split(";")) ;
478             } else {
479               ((UIOneNodePathSelector)uiComp).setAcceptedMimeTypes(new String[] {arrParams[3]}) ;
480             }
481           }
482         }
483         if (rootPath == null)
484           rootPath = "/";
485         ((UIOneNodePathSelector) uiComp).setRootNodeLocation(UIFCCUtils.getPreferenceRepository(),
486                                                              wsName,
487                                                              rootPath);
488         ((UIOneNodePathSelector) uiComp).setShowRootPathSelect(true);
489         ((UIOneNodePathSelector) uiComp).init(WCMCoreUtils.getUserSessionProvider());
490       } else if (uiComp instanceof UINodeTypeSelector) {
491         ((UINodeTypeSelector)uiComp).setRepositoryName(repositoryName);
492           UIFormMultiValueInputSet uiFormMultiValueInputSet = fastContentCreatorActionForm.getChildById(fieldName);
493           List values = uiFormMultiValueInputSet.getValue();
494           ((UINodeTypeSelector)uiComp).init(1, values);
495         }
496 
497       Utils.createPopupWindow(fastContentCreatorActionForm, uiComp, UIFCCConstant.SELECTOR_POPUP_WINDOW, 640);
498       String param = "returnField=" + fieldName ;
499       String[] params = selectorParams == null ? new String[] { param } : new String[] { param,
500           "selectorParams=" + selectorParams };
501       ((ComponentSelector)uiComp).setSourceComponent(fastContentCreatorActionForm, params);
502       if(fastContentCreatorActionForm.isAddNew){
503         uiContainer.setRendered(true);
504       }
505       event.getRequestContext().addUIComponentToUpdateByAjax(uiContainer) ;
506     }
507   }
508 }