001: /*
002: * JBoss, Home of Professional Open Source.
003: * Copyright 2006, Red Hat Middleware LLC, and individual contributors
004: * as indicated by the @author tags. See the copyright.txt file in the
005: * distribution for a full listing of individual contributors.
006: *
007: * This is free software; you can redistribute it and/or modify it
008: * under the terms of the GNU Lesser General Public License as
009: * published by the Free Software Foundation; either version 2.1 of
010: * the License, or (at your option) any later version.
011: *
012: * This software is distributed in the hope that it will be useful,
013: * but WITHOUT ANY WARRANTY; without even the implied warranty of
014: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
015: * Lesser General Public License for more details.
016: *
017: * You should have received a copy of the GNU Lesser General Public
018: * License along with this software; if not, write to the Free
019: * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
020: * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
021: */
022: package org.jboss.deployment;
023:
024: import java.io.File;
025: import java.net.URL;
026:
027: import javax.management.MalformedObjectNameException;
028: import javax.management.ObjectName;
029:
030: import org.jboss.mx.loading.RepositoryClassLoader;
031: import org.jboss.mx.util.MBeanProxyExt;
032: import org.jboss.system.ServiceControllerMBean;
033:
034: /**
035: * A simple subdeployer that deploys a managed object after parsing the
036: * deployment's xml file.
037: *
038: * @author <a href="adrian@jboss.com">Adrian Brock</a>
039: * @version $Revision: 57205 $
040: */
041: public abstract class SimpleSubDeployerSupport extends
042: SubDeployerSupport {
043: /** A proxy to the ServiceController. */
044: private ServiceControllerMBean serviceController;
045:
046: /** Whether we registered the classloader */
047: private boolean registeredClassLoader = false;
048:
049: /**
050: * Get the package extension for this deployment
051: *
052: * @return the package extension
053: */
054: public abstract String getExtension();
055:
056: /**
057: * Get the metadata url
058: *
059: * @return the meta data url
060: */
061: public abstract String getMetaDataURL();
062:
063: /**
064: * Get the object name for this deployment
065: *
066: * @param di the deployment info
067: * @return the object name
068: */
069: public abstract String getObjectName(DeploymentInfo di)
070: throws DeploymentException;
071:
072: /**
073: * Get the deployment class
074: *
075: * @return the deployment class
076: */
077: public abstract String getDeploymentClass();
078:
079: public boolean accepts(DeploymentInfo di) {
080: String urlStr = di.url.toString();
081: String extension = getExtension();
082: return urlStr.endsWith(extension)
083: || urlStr.endsWith(extension + '/');
084: }
085:
086: public void init(DeploymentInfo di) throws DeploymentException {
087: URL url = getMetaDataResource(di);
088: parseMetaData(di, url);
089: resolveWatch(di, url);
090: super .init(di);
091: }
092:
093: public void create(DeploymentInfo di) throws DeploymentException {
094: determineObjectName(di);
095: ObjectName uclName = registerClassLoader(di);
096: try {
097: registerDeployment(di, uclName);
098: try {
099: createService(di);
100: try {
101: super .create(di);
102: } catch (Throwable t) {
103: destroyService(di);
104: }
105: } catch (Throwable t) {
106: unregisterDeployment(di);
107: throw t;
108: }
109: } catch (Throwable t) {
110: unregisterClassLoader(di);
111: DeploymentException.rethrowAsDeploymentException(
112: "Error creating deployment " + di.url, t);
113: }
114: }
115:
116: public void start(DeploymentInfo di) throws DeploymentException {
117: startService(di);
118: try {
119: super .start(di);
120: } catch (Throwable t) {
121: stopService(di);
122: DeploymentException.rethrowAsDeploymentException(
123: "Error in start for deployment " + di.url, t);
124: }
125: }
126:
127: public void stop(DeploymentInfo di) throws DeploymentException {
128: stopService(di);
129: super .stop(di);
130: }
131:
132: public void destroy(DeploymentInfo di) throws DeploymentException {
133: try {
134: destroyService(di);
135: super .destroy(di);
136: } finally {
137: unregisterDeployment(di);
138: unregisterClassLoader(di);
139: }
140: }
141:
142: public void postRegister(Boolean done) {
143: super .postRegister(done);
144:
145: if (done.booleanValue()) {
146: serviceController = (ServiceControllerMBean) MBeanProxyExt
147: .create(ServiceControllerMBean.class,
148: ServiceControllerMBean.OBJECT_NAME, server);
149: }
150: }
151:
152: /**
153: * Get the url of the meta data resource
154: *
155: * @param di the deployment info
156: * @return the url of the meta data resource
157: * @throws DeploymentException for any error
158: */
159: protected URL getMetaDataResource(DeploymentInfo di)
160: throws DeploymentException {
161: URL url = di.localCl.findResource(getMetaDataURL());
162: if (url == null)
163: throw new DeploymentException("Could not find meta data "
164: + getMetaDataURL() + " for deployment " + di.url);
165: return url;
166: }
167:
168: /**
169: * Parse the meta data
170: *
171: * @param di the deployment info
172: * @param url the location of the meta data
173: * @throws DeploymentException for any error
174: */
175: abstract protected void parseMetaData(DeploymentInfo di, URL url)
176: throws DeploymentException;
177:
178: /**
179: * Resolve the watch url
180: *
181: * @param di the deployment info
182: * @param url the location of the meta data
183: * @throws DeploymentException for any error
184: */
185: protected void resolveWatch(DeploymentInfo di, URL url)
186: throws DeploymentException {
187: // Assume we watch the main deployment
188: di.watch = di.url;
189:
190: // Unless it is an unpacked directory
191: if (di.url.getProtocol().equals("file")) {
192: File file = new File(di.url.getFile());
193: if (file.isDirectory())
194: di.watch = url;
195: }
196: }
197:
198: /**
199: * Determine the object name
200: *
201: * @param di the deployment info
202: * @throws DeploymentException for any error
203: */
204: protected void determineObjectName(DeploymentInfo di)
205: throws DeploymentException {
206: String objectName = getObjectName(di);
207: try {
208: di.deployedObject = new ObjectName(objectName);
209: } catch (MalformedObjectNameException e) {
210: throw new DeploymentException(
211: "INTERNAL ERROR: Bad object name. " + objectName);
212: }
213: }
214:
215: /**
216: * Register the UCL classloader
217: *
218: * @param di the deployment info
219: * @return the object name of the classloader
220: * @throws DeploymentException for any error
221: */
222: protected ObjectName registerClassLoader(DeploymentInfo di)
223: throws DeploymentException {
224: ObjectName uclName = null;
225: try {
226: RepositoryClassLoader ucl = di.ucl;
227: uclName = ucl.getObjectName();
228: if (server.isRegistered(uclName) == false) {
229: server.registerMBean(di.ucl, uclName);
230: registeredClassLoader = true;
231: }
232: } catch (Throwable t) {
233: DeploymentException.rethrowAsDeploymentException(
234: "Error registering classloader " + uclName, t);
235: }
236: return uclName;
237: }
238:
239: /**
240: * Unregister the UCL classloader
241: *
242: * @param di the deployment info
243: */
244: protected void unregisterClassLoader(DeploymentInfo di) {
245: ObjectName uclName = null;
246: try {
247: RepositoryClassLoader ucl = di.ucl;
248: if (ucl != null) {
249: uclName = ucl.getObjectName();
250: if (registeredClassLoader
251: && server.isRegistered(uclName)) {
252: server.unregisterMBean(uclName);
253: registeredClassLoader = false;
254: }
255: }
256: } catch (Throwable t) {
257: log.warn("Error unregistering classloader " + uclName, t);
258: }
259: }
260:
261: /**
262: * Register the deployment
263: *
264: * @param di the deployment info
265: * @param uclName the object name of the classloader
266: * @throws DeploymentException for any error
267: */
268: protected void registerDeployment(DeploymentInfo di,
269: ObjectName uclName) throws DeploymentException {
270: try {
271: String deploymentClass = getDeploymentClass();
272: server.createMBean(deploymentClass, di.deployedObject,
273: uclName, new Object[] { di },
274: new String[] { DeploymentInfo.class.getName() });
275: } catch (Throwable t) {
276: DeploymentException.rethrowAsDeploymentException(
277: "Error registering deployment " + di.url, t);
278: }
279: }
280:
281: /**
282: * Unregister the deployment
283: *
284: * @param di the deployment info
285: */
286: protected void unregisterDeployment(DeploymentInfo di) {
287: try {
288: if (server.isRegistered(di.deployedObject))
289: server.unregisterMBean(di.deployedObject);
290: } catch (Throwable t) {
291: log.warn("Error unregistering deployment "
292: + di.deployedObject, t);
293: }
294: }
295:
296: /**
297: * Do the create lifecyle for the deployment
298: *
299: * @param di the deployment info
300: * @throws DeploymentException for any error
301: */
302: protected void createService(DeploymentInfo di)
303: throws DeploymentException {
304: try {
305: serviceController.create(di.deployedObject);
306: } catch (Throwable t) {
307: DeploymentException.rethrowAsDeploymentException(
308: "Error in create for deployment " + di.url, t);
309: }
310: }
311:
312: /**
313: * Do the start lifecyle for the deployment
314: *
315: * @param di the deployment info
316: * @throws DeploymentException for any error
317: */
318: protected void startService(DeploymentInfo di)
319: throws DeploymentException {
320: try {
321: serviceController.start(di.deployedObject);
322: } catch (Throwable t) {
323: DeploymentException.rethrowAsDeploymentException(
324: "Error in start for deployment " + di.url, t);
325: }
326: }
327:
328: /**
329: * Do the stop lifecyle for the deployment
330: *
331: * @param di the deployment info
332: */
333: protected void stopService(DeploymentInfo di) {
334: try {
335: if (di.deployedObject != null)
336: serviceController.stop(di.deployedObject);
337: } catch (Throwable t) {
338: log.warn("Error in stop for deployment " + di.url, t);
339: }
340: }
341:
342: /**
343: * Do the destroy lifecyle for the deployment
344: *
345: * @param di the deployment info
346: */
347: protected void destroyService(DeploymentInfo di)
348: throws DeploymentException {
349: try {
350: if (di.deployedObject != null)
351: serviceController.destroy(di.deployedObject);
352: } catch (Throwable t) {
353: log.warn("Error in destroy for deployment " + di.url, t);
354: }
355: try {
356: if (di.deployedObject != null)
357: serviceController.remove(di.deployedObject);
358: } catch (Throwable t) {
359: log.warn("Error in remove for deployment " + di.url, t);
360: }
361: }
362: }
|