1 /*
2 * JBoss, Home of Professional Open Source
3 * Copyright 2005, JBoss Inc., and individual contributors as indicated
4 * by the @authors tag. See the copyright.txt in the distribution for a
5 * full listing of individual contributors.
6 *
7 * This is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU Lesser General Public License as
9 * published by the Free Software Foundation; either version 2.1 of
10 * the License, or (at your option) any later version.
11 *
12 * This software is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
16 *
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this software; if not, write to the Free
19 * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
20 * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
21 */
22 package org.jboss.deployment;
23
24 import java.io.File;
25 import java.net.URL;
26
27 import javax.management.MalformedObjectNameException;
28 import javax.management.ObjectName;
29
30 import org.jboss.mx.loading.RepositoryClassLoader;
31 import org.jboss.mx.util.MBeanProxyExt;
32 import org.jboss.system.ServiceControllerMBean;
33
34 /**
35 * A simple subdeployer that deploys a managed object after parsing the
36 * deployment's xml file.
37 *
38 * @author <a href="adrian@jboss.com">Adrian Brock</a>
39 * @version $Revision: 57108 $
40 */
41 public abstract class SimpleSubDeployerSupport extends SubDeployerSupport
42 {
43 /** A proxy to the ServiceController. */
44 private ServiceControllerMBean serviceController;
45
46 /** Whether we registered the classloader */
47 private boolean registeredClassLoader = false;
48
49 /**
50 * Get the package extension for this deployment
51 *
52 * @return the package extension
53 */
54 public abstract String getExtension();
55
56 /**
57 * Get the metadata url
58 *
59 * @return the meta data url
60 */
61 public abstract String getMetaDataURL();
62
63 /**
64 * Get the object name for this deployment
65 *
66 * @param di the deployment info
67 * @return the object name
68 */
69 public abstract String getObjectName(DeploymentInfo di) throws DeploymentException;
70
71 /**
72 * Get the deployment class
73 *
74 * @return the deployment class
75 */
76 public abstract String getDeploymentClass();
77
78 public boolean accepts(DeploymentInfo di)
79 {
80 String urlStr = di.url.toString();
81 String extension = getExtension();
82 return urlStr.endsWith(extension) || urlStr.endsWith(extension + '/');
83 }
84
85 public void init(DeploymentInfo di) throws DeploymentException
86 {
87 URL url = getMetaDataResource(di);
88 parseMetaData(di, url);
89 resolveWatch(di, url);
90 super.init(di);
91 }
92
93 public void create(DeploymentInfo di) throws DeploymentException
94 {
95 determineObjectName(di);
96 ObjectName uclName = registerClassLoader(di);
97 try
98 {
99 registerDeployment(di, uclName);
100 try
101 {
102 createService(di);
103 try
104 {
105 super.create(di);
106 }
107 catch (Throwable t)
108 {
109 destroyService(di);
110 }
111 }
112 catch (Throwable t)
113 {
114 unregisterDeployment(di);
115 throw t;
116 }
117 }
118 catch (Throwable t)
119 {
120 unregisterClassLoader(di);
121 DeploymentException.rethrowAsDeploymentException("Error creating deployment " + di.url, t);
122 }
123 }
124
125 public void start(DeploymentInfo di) throws DeploymentException
126 {
127 startService(di);
128 try
129 {
130 super.start(di);
131 }
132 catch (Throwable t)
133 {
134 stopService(di);
135 DeploymentException.rethrowAsDeploymentException("Error in start for deployment " + di.url, t);
136 }
137 }
138
139 public void stop(DeploymentInfo di) throws DeploymentException
140 {
141 stopService(di);
142 super.stop(di);
143 }
144
145 public void destroy(DeploymentInfo di) throws DeploymentException
146 {
147 try
148 {
149 destroyService(di);
150 super.destroy(di);
151 }
152 finally
153 {
154 unregisterDeployment(di);
155 unregisterClassLoader(di);
156 }
157 }
158
159 public void postRegister(Boolean done)
160 {
161 super.postRegister(done);
162
163 if (done.booleanValue())
164 {
165 serviceController = (ServiceControllerMBean)
166 MBeanProxyExt.create(ServiceControllerMBean.class,
167 ServiceControllerMBean.OBJECT_NAME,
168 server);
169 }
170 }
171
172 /**
173 * Get the url of the meta data resource
174 *
175 * @param di the deployment info
176 * @return the url of the meta data resource
177 * @throws DeploymentException for any error
178 */
179 protected URL getMetaDataResource(DeploymentInfo di) throws DeploymentException
180 {
181 URL url = di.localCl.findResource(getMetaDataURL());
182 if (url == null)
183 throw new DeploymentException("Could not find meta data " + getMetaDataURL() + " for deployment " + di.url);
184 return url;
185 }
186
187 /**
188 * Parse the meta data
189 *
190 * @param di the deployment info
191 * @param url the location of the meta data
192 * @throws DeploymentException for any error
193 */
194 abstract protected void parseMetaData(DeploymentInfo di, URL url) throws DeploymentException;
195
196 /**
197 * Resolve the watch url
198 *
199 * @param di the deployment info
200 * @param url the location of the meta data
201 * @throws DeploymentException for any error
202 */
203 protected void resolveWatch(DeploymentInfo di, URL url) throws DeploymentException
204 {
205 // Assume we watch the main deployment
206 di.watch = di.url;
207
208 // Unless it is an unpacked directory
209 if (di.url.getProtocol().equals("file"))
210 {
211 File file = new File(di.url.getFile());
212 if (file.isDirectory())
213 di.watch = url;
214 }
215 }
216
217 /**
218 * Determine the object name
219 *
220 * @param di the deployment info
221 * @throws DeploymentException for any error
222 */
223 protected void determineObjectName(DeploymentInfo di) throws DeploymentException
224 {
225 String objectName = getObjectName(di);
226 try
227 {
228 di.deployedObject = new ObjectName(objectName);
229 }
230 catch (MalformedObjectNameException e)
231 {
232 throw new DeploymentException("INTERNAL ERROR: Bad object name. " + objectName);
233 }
234 }
235
236 /**
237 * Register the UCL classloader
238 *
239 * @param di the deployment info
240 * @return the object name of the classloader
241 * @throws DeploymentException for any error
242 */
243 protected ObjectName registerClassLoader(DeploymentInfo di) throws DeploymentException
244 {
245 ObjectName uclName = null;
246 try
247 {
248 RepositoryClassLoader ucl = di.ucl;
249 uclName = ucl.getObjectName();
250 if (server.isRegistered(uclName) == false)
251 {
252 server.registerMBean(di.ucl, uclName);
253 registeredClassLoader = true;
254 }
255 }
256 catch (Throwable t)
257 {
258 DeploymentException.rethrowAsDeploymentException("Error registering classloader " + uclName, t);
259 }
260 return uclName;
261 }
262
263 /**
264 * Unregister the UCL classloader
265 *
266 * @param di the deployment info
267 */
268 protected void unregisterClassLoader(DeploymentInfo di)
269 {
270 ObjectName uclName = null;
271 try
272 {
273 RepositoryClassLoader ucl = di.ucl;
274 if (ucl != null)
275 {
276 uclName = ucl.getObjectName();
277 if (registeredClassLoader && server.isRegistered(uclName))
278 {
279 server.unregisterMBean(uclName);
280 registeredClassLoader = false;
281 }
282 }
283 }
284 catch (Throwable t)
285 {
286 log.warn("Error unregistering classloader " + uclName, t);
287 }
288 }
289
290 /**
291 * Register the deployment
292 *
293 * @param di the deployment info
294 * @param uclName the object name of the classloader
295 * @throws DeploymentException for any error
296 */
297 protected void registerDeployment(DeploymentInfo di, ObjectName uclName) throws DeploymentException
298 {
299 try
300 {
301 String deploymentClass = getDeploymentClass();
302 server.createMBean(deploymentClass, di.deployedObject, uclName, new Object[] { di }, new String[] { DeploymentInfo.class.getName() });
303 }
304 catch (Throwable t)
305 {
306 DeploymentException.rethrowAsDeploymentException("Error registering deployment " + di.url, t);
307 }
308 }
309
310 /**
311 * Unregister the deployment
312 *
313 * @param di the deployment info
314 */
315 protected void unregisterDeployment(DeploymentInfo di)
316 {
317 try
318 {
319 if (server.isRegistered(di.deployedObject))
320 server.unregisterMBean(di.deployedObject);
321 }
322 catch (Throwable t)
323 {
324 log.warn("Error unregistering deployment " + di.deployedObject, t);
325 }
326 }
327
328 /**
329 * Do the create lifecyle for the deployment
330 *
331 * @param di the deployment info
332 * @throws DeploymentException for any error
333 */
334 protected void createService(DeploymentInfo di) throws DeploymentException
335 {
336 try
337 {
338 serviceController.create(di.deployedObject);
339 }
340 catch (Throwable t)
341 {
342 DeploymentException.rethrowAsDeploymentException("Error in create for deployment " + di.url, t);
343 }
344 }
345
346 /**
347 * Do the start lifecyle for the deployment
348 *
349 * @param di the deployment info
350 * @throws DeploymentException for any error
351 */
352 protected void startService(DeploymentInfo di) throws DeploymentException
353 {
354 try
355 {
356 serviceController.start(di.deployedObject);
357 }
358 catch (Throwable t)
359 {
360 DeploymentException.rethrowAsDeploymentException("Error in start for deployment " + di.url, t);
361 }
362 }
363
364 /**
365 * Do the stop lifecyle for the deployment
366 *
367 * @param di the deployment info
368 */
369 protected void stopService(DeploymentInfo di)
370 {
371 try
372 {
373 if (di.deployedObject != null)
374 serviceController.stop(di.deployedObject);
375 }
376 catch (Throwable t)
377 {
378 log.warn("Error in stop for deployment " + di.url, t);
379 }
380 }
381
382 /**
383 * Do the destroy lifecyle for the deployment
384 *
385 * @param di the deployment info
386 */
387 protected void destroyService(DeploymentInfo di) throws DeploymentException
388 {
389 try
390 {
391 if (di.deployedObject != null)
392 serviceController.destroy(di.deployedObject);
393 }
394 catch (Throwable t)
395 {
396 log.warn("Error in destroy for deployment " + di.url, t);
397 }
398 try
399 {
400 if (di.deployedObject != null)
401 serviceController.remove(di.deployedObject);
402 }
403 catch (Throwable t)
404 {
405 log.warn("Error in remove for deployment " + di.url, t);
406 }
407 }
408 }