1 /**
2 * Copyright 2005-2007 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.core.InfrastructureException;
20 import org.figure8.join.core.DuplicateEntityException;
21 import org.figure8.join.businessobjects.environment.Resource;
22 import org.figure8.join.businessobjects.environment.AbstractResource;
23 import org.figure8.join.businessobjects.environment.AbstractResourceType;
24 import org.figure8.join.businessobjects.environment.Machine;
25 import org.figure8.join.businessfacades.environment.ResourceManager;
26 import org.figure8.join.util.LogUtil;
27
28 import org.apache.commons.logging.Log;
29 import org.apache.commons.beanutils.PropertyUtils;
30 import org.apache.struts.action.ActionForm;
31 import org.apache.struts.action.ActionMapping;
32 import org.apache.struts.action.ActionForward;
33
34 import javax.servlet.http.HttpSession;
35 import javax.servlet.http.HttpServletRequest;
36 import javax.servlet.http.HttpServletResponse;
37
38 import java.util.List;
39 import java.lang.reflect.Constructor;
40 /**
41 * This is a Struts action for managing all operations related to AbstractResource entities.
42 * @author <a href="mailto:laurent.broudoux@free.fr">Laurent Broudoux</a>
43 * @version $Revision: 1.2 $
44 *
45 * @struts.action path="/resource" name="resourceForm"
46 * scope="request" parameter="op" validate="true"
47 * input="/pages/mainpage.jsp?body=/jsp/environment/resources.jsp"
48 * @struts.action-forward name="Resources" path="/jsp/environment/resources.jsp"
49 */
50 public class ResourceActions extends JoinAction{
51
52
53
54 /** Get a commons logger. */
55 private static final Log log = LogUtil.getLog(ResourceActions.class);
56
57 /** Operation code for showing an empty resource creation form */
58 public static final String FORM_OP = "form";
59 /** Operation code for loading a specified Resource */
60 public static final String LOAD_OP = "load";
61 /** Operation code for saving (create or update) a specified Resource */
62 public static final String SAVE_OP = "save";
63 /** Operation code for searching resources using their type */
64 public static final String SEARCH_OP = "search";
65 /** Operation code for getting resource configuration details at specified date */
66 public static final String CONFIG_OP = "config";
67 /** Operation code for getting resource configuration changes for tracking period */
68 public static final String CHANGES_OP = "changes";
69
70 /**
71 * The session scope attribute under which the Resource object
72 * currently selected by our logged-in User is stored.
73 */
74 public static final String RESOURCE_KEY = "resource";
75 /**
76 * The request scope attribute under which the retrieved Resources
77 * list is stored.
78 */
79 public static final String RESOURCES_KEY = "resources";
80 /**
81 * The request scope attribute under which is stored the Resource that
82 * has raised a DuplicateEntityException during save of another one.
83 */
84 public static final String DUPLICATE_RESOURCE_KEY = "duplicate";
85
86
87
88
89 /** The ResourceManager to use */
90 private ResourceManager resourceManager = null;
91
92
93
94
95 /** Creates a new instance of ResourceActions */
96 public ResourceActions(){
97 }
98
99
100
101
102 /** @param manager The ResourceManager to use */
103 public void setResourceManager(ResourceManager manager){
104 this.resourceManager = manager;
105 }
106
107 /**
108 * Create a new resource instance from informations contained into ResourceForm.
109 * This is a hook to allow subclasses treating specific resource categories. This implementation
110 * maskes 1 assumption : Resource implementation needs to have a constructor with 2 parameters
111 * (the resource name and the resource type object).
112 * @param form The ResourceForm (or a subclass) to create persistent resource from
113 * @return The persistent AbstractResourceType corresponding to given form
114 */
115 public AbstractResource createResourceInstance(ResourceForm form){
116 String classStr = ResourceForm.getSupportedImplementation(form.getCategory());
117 AbstractResourceType type = (AbstractResourceType)resourceManager.getResourceType(form.getResourceTypeKey());
118
119 try{
120 Class clazz = Thread.currentThread().getContextClassLoader().loadClass(classStr);
121 Class typeClazz = Thread.currentThread().getContextClassLoader().loadClass(classStr + "Type");
122 Constructor constructor = clazz.getDeclaredConstructor(new Class[]{String.class, typeClazz});
123 return (AbstractResource)constructor.newInstance(new Object[]{form.getName(), type});
124 }
125 catch (ClassNotFoundException cnfe){
126
127 log.error("ClassNotFoundException while trying to load " + classStr + " class");
128 log.error("Check your supported resource categories...");
129 throw new InfrastructureException("Unable to load specified resource category", cnfe);
130 }
131 catch (NoSuchMethodException nsme){
132
133 log.error("NoSuchMethodException while trying to get " + classStr + " constructor");
134 log.error("Check your supported resource categories...");
135 throw new InfrastructureException("Unable to create specified resource category", nsme);
136 }
137 catch (Exception e){
138
139 log.error("Unexpected exception while trying to create a " + classStr + " instance");
140 log.error("Here'svthe detailed error message: " + e.getMessage());
141 throw new InfrastructureException("Unexpected exception while trying to create a resource", e);
142 }
143 }
144
145
146
147
148 /**
149 *
150 * @param operation String representing the operation to invoke on Action
151 * @param mapping Mapping between forwards name and path for this action
152 * @param form The form object containing request parameters
153 * @param request The servlet container request wrapper
154 * @param response The servlet container response wrapper
155 * @return A forward to the next view to render and display
156 * @throws Exception such as InfrastructureExceptions...
157 */
158 public ActionForward doExecute(String operation, ActionMapping mapping, ActionForm form,
159 HttpServletRequest request, HttpServletResponse response) throws Exception{
160
161 log.debug("doExecute() called for '" + operation + "' operation");
162
163
164 List resourceTypes = resourceManager.getResourceTypes(request.getParameter("category"));
165 request.setAttribute(ResourceTypeActions.RESOURCE_TYPES_KEY, resourceTypes);
166
167 if (FORM_OP.equals(operation)){
168 return showResourceForm(mapping, form, request, response);
169 }
170 else if (LOAD_OP.equals(operation)){
171 return loadResource(mapping, form, request, response);
172 }
173 else if (SAVE_OP.equals(operation)){
174 return saveResource(mapping, form, request, response);
175 }
176 else if (SEARCH_OP.equals(operation)){
177
178 request.getSession().removeAttribute(RESOURCE_KEY);
179 removeObsoleteForm(mapping, request);
180 return searchResources(mapping, form, request, response);
181 }
182 else{
183
184 request.getSession().removeAttribute(RESOURCE_KEY);
185 return mapping.findForward("Resources");
186 }
187 }
188
189
190
191
192 /**
193 * Prepare all we need for displaying a resource creation form
194 * @return A forward to the next view to render and display
195 */
196 protected ActionForward showResourceForm(ActionMapping mapping, ActionForm form,
197 HttpServletRequest request, HttpServletResponse response) throws Exception{
198
199 request.setAttribute(MachineActions.MACHINES_KEY, resourceManager.getMachines());
200 return searchResources(mapping, form, request, response);
201 }
202
203 /**
204 * Load a specified resource from datastore and fill form with it.
205 * @return A forward to the next view to render and display
206 */
207 protected ActionForward loadResource(ActionMapping mapping, ActionForm form,
208 HttpServletRequest request, HttpServletResponse response) throws Exception{
209 if (form instanceof ResourceForm){
210
211 ResourceForm rForm = (ResourceForm)form;
212 Resource resource = resourceManager.getResource(rForm.getId());
213
214
215 HttpSession session = request.getSession();
216 session.setAttribute(RESOURCE_KEY, resource);
217
218 PropertyUtils.copyProperties(rForm, resource);
219 rForm.setResourceTypeKey(resource.getResourceType().getKey());
220
221
222 request.setAttribute(MachineActions.MACHINES_KEY, resourceManager.getMachines());
223 return searchResources(mapping, form, request, response);
224 }
225
226 return null;
227 }
228
229 /**
230 * Save a resource into datastore. The resource may be an already existing
231 * one or a new one (this is indeed a create or update method).
232 * @return A forward to the next view to render and display
233 */
234 protected ActionForward saveResource(ActionMapping mapping, ActionForm form,
235 HttpServletRequest request, HttpServletResponse response) throws Exception{
236 if (form instanceof ResourceForm){
237 ResourceForm rForm = (ResourceForm)form;
238
239
240 HttpSession session = request.getSession();
241 AbstractResource resource = (AbstractResource)session.getAttribute(RESOURCE_KEY);
242
243
244 if (resource == null){
245 log.info("Creation of a new Resource with name: " + rForm.getName());
246 resource = createResourceInstance(rForm);
247 resource.setLogDirPath(rForm.getLogDirPath());
248 resource.setLogFilePath(rForm.getLogFilePath());
249 }
250 else{
251 log.info("Update of existing Resource having name: " + rForm.getName());
252 PropertyUtils.copyProperties(resource, rForm);
253 }
254
255 if (rForm.getMachineId() != -1){
256 Machine machine = resourceManager.getMachine(rForm.getMachineId());
257 resource.setMachine(machine);
258 machine.addHostedResource(resource);
259 }
260
261 try {resourceManager.saveResource(resource);}
262 catch (DuplicateEntityException dee){
263
264 request.setAttribute(DUPLICATE_RESOURCE_KEY, dee);
265 return searchResources(mapping, form, request, response);
266 }
267
268
269 session.removeAttribute(RESOURCE_KEY);
270 removeObsoleteForm(mapping, request);
271
272
273 return searchResources(mapping, form, request, response);
274 }
275
276 return null;
277 }
278
279 /**
280 * Retrieve a list of Resources using the resource type criteria.
281 * @return A forward to the next view to render and display
282 */
283 protected ActionForward searchResources(ActionMapping mapping, ActionForm form,
284 HttpServletRequest request, HttpServletResponse response) throws Exception{
285 if (form instanceof ResourceForm){
286 ResourceForm rForm = (ResourceForm)form;
287
288
289 AbstractResourceType resourceType = (AbstractResourceType)resourceManager.getResourceType(
290 rForm.getResourceTypeKey());
291 List resources = resourceManager.getResources(resourceType);
292
293
294 request.setAttribute(RESOURCES_KEY, resources);
295 request.setAttribute("resourceTypeKey", rForm.getResourceTypeKey());
296 return mapping.findForward("Resources");
297 }
298
299 return null;
300 }
301 }