View Javadoc

1   /**
2    * Copyright 2005-2006 the original author or authors.
3    *
4    * Licensed under the Gnu General Pubic License, Version 2.0 (the
5    * "License"); you may not use this file except in compliance with
6    * the License. You may obtain a copy of the License at
7    *
8    *      http://www.opensource.org/licenses/gpl-license.php
9    *
10   * This program is distributed in the hope that it will be useful,
11   * but WITHOUT ANY WARRANTY; without even the implied warranty of
12   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
13   * See the Gnu General Public License for more details.
14   */
15  package org.figure8.join.control.action;
16  
17  import org.figure8.join.control.JoinAction;
18  import org.figure8.join.control.form.ResourceForm;
19  import org.figure8.join.control.form.ResourceTypeForm;
20  import org.figure8.join.core.InfrastructureException;
21  import org.figure8.join.core.DuplicateEntityException;
22  import org.figure8.join.businessobjects.environment.ResourceType;
23  import org.figure8.join.businessobjects.environment.AbstractResourceType;
24  import org.figure8.join.businessfacades.environment.ResourceManager;
25  import org.figure8.join.util.LogUtil;
26  
27  import org.apache.commons.logging.Log;
28  import org.apache.commons.beanutils.PropertyUtils;
29  import org.apache.struts.action.ActionForm;
30  import org.apache.struts.action.ActionMapping;
31  import org.apache.struts.action.ActionForward;
32  
33  import javax.servlet.http.HttpSession;
34  import javax.servlet.http.HttpServletRequest;
35  import javax.servlet.http.HttpServletResponse;
36  
37  import java.lang.reflect.Constructor;
38  /**
39   * This is a Struts action for managing all operations related to AbstractResourceType entities.
40   * @author <a href="mailto:laurent.broudoux@free.fr">Laurent Broudoux</a>
41   * @version $Revision: 1.1 $
42   *
43   * @struts.action path="/resourceType" name="resourceTypeForm"
44   *                scope="request" parameter="op" validate="true"
45   *                input="/pages/mainpage.jsp?body=/jsp/environment/resourcetypes.jsp"
46   * @struts.action-forward name="ResourceTypes" path="/jsp/environment/resourcetypes.jsp"
47   */
48  public class ResourceTypeActions extends JoinAction{
49     
50     // Static -------------------------------------------------------------------
51     
52     /** Get a commons logger. */
53     private static final Log log = LogUtil.getLog(ResourceTypeActions.class);
54  
55     /** Operation code for loading a specified ResourceType */
56     public static final String LOAD_OP = "load";
57     /** Operation code for saving (create or update) a specified ResourceType */
58     public static final String SAVE_OP = "save";
59  
60     /**
61      * The session scope attribute under which the ResourceType object
62      * currently selected by our logged-in User is stored.
63      */
64     public static final String RESOURCE_TYPE_KEY = "resourceType";
65     /**
66      * The request scope attribute under which the retrieved ResourceTypes
67      * list is stored.
68      */
69     public static final String RESOURCE_TYPES_KEY = "resourceTypes";
70     /**
71      * The request scope attribute under which is stored the ResourceTypes that
72      * has raised a DuplicateEntityException during save of another one.
73      */
74     public static final String DUPLICATE_RESOURCE_TYPE_KEY = "duplicate";
75  
76  
77     // Attributes ---------------------------------------------------------------
78  
79     /** The ResourceManager to use */
80     private ResourceManager resourceManager = null;
81  
82  
83     // Constructors -------------------------------------------------------------
84     
85     /** Creates a new instance of ResourceTypeActions */
86     public ResourceTypeActions(){
87     }
88   
89     
90     // Public -------------------------------------------------------------------
91  
92     /** @param manager The ResourceManager to use */
93     public void setResourceManager(ResourceManager manager){
94        this.resourceManager = manager;
95     }
96  
97     /**
98      * Create a new resource type instance from informations contained into ResourceTypeForm.
99      * This is a hook to allow subclasses treating specific resource categories. This implementation
100     * maskes 2 assumptions : it is looking for a class named <code>form.getCategory() + "Type"</code>
101     * and this it needs to have a constructor with 2 string parameters (the resource type key
102     * and its label).
103     * @param form The ResourceTypeForm (or a subclass) to create persistent resource type from
104     * @return The persistent AbstractResourceType corresponding to given form
105     */
106    public AbstractResourceType createResourceTypeInstance(ResourceTypeForm form){
107       String classStr = ResourceForm.getSupportedImplementation(form.getCategory());
108       try{
109          Class clazz = Thread.currentThread().getContextClassLoader().loadClass(classStr + "Type");
110          Constructor constructor = clazz.getDeclaredConstructor(new Class[]{String.class, String.class});
111          return (AbstractResourceType)constructor.newInstance(new Object[]{form.getKey(), form.getLabel()});
112       }
113       catch (ClassNotFoundException cnfe){
114          // Log and wrap this into infrastructure exception.
115          log.error("ClassNotFoundException while trying to load " + classStr + "Type class");
116          log.error("Check your supported resource categories...");
117          throw new InfrastructureException("Unable to load specified resource type category", cnfe);
118       }
119       catch (NoSuchMethodException nsme){
120          // Log and wrap this into infrastructure exception.
121          log.error("NoSuchMethodException while trying to get " + classStr + "Type constructor");
122          log.error("Check your supported resource categories...");
123          throw new InfrastructureException("Unable to create specified resource type category", nsme);
124       }
125       catch (Exception e){
126          // Log and wrap this into infrastructure exception.
127          log.error("Unexpected exception while trying to create a " + classStr + "Type instance");
128          log.error("Here'svthe detailed error message: " + e.getMessage());
129          throw new InfrastructureException("Unexpected exception while trying to create a resource type", e);
130       }
131    }
132 
133 
134    // Implementation of JoinAction ---------------------------------------------
135    
136    /**
137     *
138     * @param operation String representing the operation to invoke on Action
139     * @param mapping Mapping between forwards name and path for this action
140     * @param form The form object containing request parameters
141     * @param request The servlet container request wrapper
142     * @param response The servlet container response wrapper
143     * @return A forward to the next view to render and display
144     */
145    public ActionForward doExecute(String operation, ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception{
146       // Trace operation to execute.
147       log.debug("doExecute() called for '" + operation + "' operation");
148 
149       if (LOAD_OP.equals(operation)){
150          return loadResourceType(mapping, form, request, response);
151       }
152       else if (SAVE_OP.equals(operation)){
153          return saveResourceType(mapping, form, request, response);
154       }
155       else{
156          // Default : empty resource types management page.
157          request.getSession().removeAttribute(RESOURCE_TYPE_KEY);
158          request.setAttribute(RESOURCE_TYPES_KEY, resourceManager.getResourceTypes(request.getParameter("category")));
159          return mapping.findForward("ResourceTypes");
160       }
161    }
162 
163 
164    // Protected ----------------------------------------------------------------
165 
166    /**
167     * Load a specified resource type from datastore and fill form with it.
168     * @return A forward to the next view to render and display
169     */
170    protected ActionForward loadResourceType(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response)
171       throws Exception{
172 
173       if (form instanceof ResourceTypeForm){
174          // Get the request resource type from manager.
175          ResourceTypeForm rForm = (ResourceTypeForm)form;
176          ResourceType type = resourceManager.getResourceType(rForm.getKey());
177 
178          // Store resource type within session.
179          HttpSession session = request.getSession();
180          session.setAttribute(RESOURCE_TYPE_KEY, type);
181          // Copy resource type into form properties.
182          PropertyUtils.copyProperties(rForm, type);
183 
184          // Add resource types list before forwarding.
185          request.setAttribute(RESOURCE_TYPES_KEY, resourceManager.getResourceTypes(rForm.getCategory()));
186          return mapping.findForward("ResourceTypes");
187       }
188       // This should not happen...
189       return null;
190    }
191 
192    /**
193     * Save a resource type into datastore. The resource type may be an already existing
194     * one or a new one (this is indeed a create or update method).
195     * @return A forward to the next view to render and display
196     */
197    protected ActionForward saveResourceType(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response)
198       throws Exception{
199 
200       if (form instanceof ResourceTypeForm){
201          ResourceTypeForm rForm = (ResourceTypeForm)form;
202 
203          // Is there a resource type to update in session ?
204          HttpSession session = request.getSession();
205          AbstractResourceType type = (AbstractResourceType)session.getAttribute(RESOURCE_TYPE_KEY);
206 
207          // Create a new resource type or populate existing with form.
208          if (type == null){
209             log.info("Creation of a new ResourceType with key: " + rForm.getKey());
210             type = createResourceTypeInstance(rForm);
211          }
212          else{
213             log.info("Update of existing ResourceType having key: " + rForm.getKey());
214             PropertyUtils.copyProperties(type, rForm);
215          }
216          // Save resource type using manager.
217          try {resourceManager.saveResourceType(type);}
218          catch (DuplicateEntityException dee){
219             // Store exception within request.
220             request.setAttribute(DUPLICATE_RESOURCE_TYPE_KEY, dee.getOriginalEntity());
221             request.setAttribute(RESOURCE_TYPES_KEY, resourceManager.getResourceTypes(rForm.getCategory()));
222             return mapping.findForward("ResourceTypes");
223          }
224 
225          // Remove form and session attribute if present.
226          session.removeAttribute(RESOURCE_TYPE_KEY);
227          removeObsoleteForm(mapping, request);
228 
229          // Add resource types list before forwarding.
230          request.setAttribute(RESOURCE_TYPES_KEY, resourceManager.getResourceTypes(rForm.getCategory()));
231          return mapping.findForward("ResourceTypes");
232       }
233       // This should not happen...
234       return null;
235    }
236 }