KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > servicemix > jbi > framework > InstallerMBeanImpl


1 /*
2  * Licensed to the Apache Software Foundation (ASF) under one or more
3  * contributor license agreements. See the NOTICE file distributed with
4  * this work for additional information regarding copyright ownership.
5  * The ASF licenses this file to You under the Apache License, Version 2.0
6  * (the "License"); you may not use this file except in compliance with
7  * the License. You may obtain a copy of the License at
8  *
9  * http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  */

17 package org.apache.servicemix.jbi.framework;
18
19 import java.io.File JavaDoc;
20 import java.net.MalformedURLException JavaDoc;
21 import java.net.URL JavaDoc;
22 import java.util.ArrayList JavaDoc;
23 import java.util.List JavaDoc;
24
25 import javax.jbi.JBIException;
26 import javax.jbi.component.Bootstrap;
27 import javax.jbi.component.Component;
28 import javax.jbi.management.DeploymentException;
29 import javax.jbi.management.InstallerMBean;
30 import javax.management.InstanceNotFoundException JavaDoc;
31 import javax.management.MBeanRegistrationException JavaDoc;
32 import javax.management.ObjectName JavaDoc;
33
34 import org.apache.commons.logging.Log;
35 import org.apache.commons.logging.LogFactory;
36 import org.apache.servicemix.jbi.container.JBIContainer;
37 import org.apache.xbean.classloader.DestroyableClassLoader;
38 import org.apache.xbean.classloader.JarFileClassLoader;
39
40 /**
41  * InstallerMBean defines standard installation and uninstallation controls for Binding Components and Service Engines.
42  * Binding Components and Service Engines.
43  *
44  * @version $Revision: 438523 $
45  */

46 public class InstallerMBeanImpl implements InstallerMBean {
47     private static final Log log = LogFactory.getLog(InstallerMBeanImpl.class);
48     private InstallationContextImpl context;
49     private JBIContainer container;
50     private ObjectName JavaDoc objectName;
51     private ObjectName JavaDoc extensionMBeanName;
52     private Bootstrap bootstrap;
53     private boolean initialized;
54
55     /**
56      * Constructor for the InstallerMBean
57      *
58      * @param container
59      * @param ic
60      * @throws DeploymentException
61      */

62     public InstallerMBeanImpl(JBIContainer container,
63                               InstallationContextImpl ic) throws DeploymentException {
64         this.container = container;
65         this.context = ic;
66         bootstrap = createBootstrap();
67         initBootstrap();
68     }
69     
70     protected void initBootstrap() throws DeploymentException {
71         try {
72             if (!initialized) {
73                 // Unregister a previously registered extension mbean,
74
// in case the bootstrap has not done it
75
try {
76                     if (extensionMBeanName != null &&
77                         container.getMBeanServer() != null &&
78                         container.getMBeanServer().isRegistered(extensionMBeanName)) {
79                         container.getMBeanServer().unregisterMBean(extensionMBeanName);
80                     }
81                 } catch (InstanceNotFoundException JavaDoc e) {
82                     // ignore
83
} catch (MBeanRegistrationException JavaDoc e) {
84                     // ignore
85
}
86                 // Init bootstrap
87
bootstrap.init(this.context);
88                 extensionMBeanName = bootstrap.getExtensionMBeanName();
89                 initialized = true;
90             }
91         } catch (JBIException e) {
92             log.error("Could not initialize bootstrap", e);
93             throw new DeploymentException(e);
94         }
95     }
96     
97     protected void cleanUpBootstrap() throws DeploymentException {
98         try {
99             bootstrap.cleanUp();
100         } catch (JBIException e) {
101             log.error("Could not initialize bootstrap", e);
102             throw new DeploymentException(e);
103         } finally {
104             initialized = false;
105         }
106     }
107     
108     protected Bootstrap createBootstrap() throws DeploymentException {
109         ClassLoader JavaDoc oldCl = Thread.currentThread().getContextClassLoader();
110         org.apache.servicemix.jbi.deployment.Component descriptor = context.getDescriptor();
111         try {
112             ClassLoader JavaDoc cl = buildClassLoader(
113                                     context.getInstallRootAsDir(),
114                                     descriptor.getBootstrapClassPath().getPathElements(),
115                                     descriptor.isBootstrapClassLoaderDelegationParentFirst(),
116                                     null);
117             Thread.currentThread().setContextClassLoader(cl);
118             Class JavaDoc bootstrapClass = cl.loadClass(descriptor.getBootstrapClassName());
119             Bootstrap bootstrap = (Bootstrap) bootstrapClass.newInstance();
120             return bootstrap;
121         }
122         catch (MalformedURLException JavaDoc e) {
123             log.error("Could not create class loader", e);
124             throw new DeploymentException(e);
125         }
126         catch (ClassNotFoundException JavaDoc e) {
127             log.error("Class not found: " + descriptor.getBootstrapClassName(), e);
128             throw new DeploymentException(e);
129         }
130         catch (InstantiationException JavaDoc e) {
131             log.error("Could not instantiate : " + descriptor.getBootstrapClassName(), e);
132             throw new DeploymentException(e);
133         }
134         catch (IllegalAccessException JavaDoc e) {
135             log.error("Illegal access on: " + descriptor.getBootstrapClassName(), e);
136             throw new DeploymentException(e);
137         }
138         finally {
139             Thread.currentThread().setContextClassLoader(oldCl);
140         }
141     }
142
143     /**
144      * Get the installation root directory path for this BC or SE.
145      *
146      * @return the full installation path of this component.
147      */

148     public String JavaDoc getInstallRoot() {
149         return context.getInstallRoot();
150     }
151
152     /**
153      * Install a BC or SE.
154      *
155      * @return JMX ObjectName representing the ComponentLifeCycle for the installed component, or null if the
156      * installation did not complete.
157      * @throws javax.jbi.JBIException if the installation fails.
158      */

159     public ObjectName JavaDoc install() throws JBIException {
160         if (isInstalled()) {
161             throw new DeploymentException("Component is already installed");
162         }
163         initBootstrap();
164         bootstrap.onInstall();
165         // TODO: the bootstrap may change the class path for the component,
166
// so we need to persist it somehow
167
ObjectName JavaDoc result = null;
168         try {
169             result = activateComponent();
170             ComponentMBeanImpl lcc = container.getComponent(context.getComponentName());
171             lcc.persistRunningState();
172             context.setInstall(false);
173         } finally {
174             cleanUpBootstrap();
175         }
176         return result;
177     }
178     
179     public ObjectName JavaDoc activateComponent() throws JBIException {
180         ObjectName JavaDoc result = null;
181         ClassLoader JavaDoc oldCl = Thread.currentThread().getContextClassLoader();
182         org.apache.servicemix.jbi.deployment.Component descriptor = context.getDescriptor();
183         try {
184             ClassLoader JavaDoc cl = buildClassLoader(
185                                     context.getInstallRootAsDir(),
186                                     (String JavaDoc[]) context.getClassPathElements().toArray(new String JavaDoc[0]),
187                                     descriptor.isComponentClassLoaderDelegationParentFirst(),
188                                     context.getSharedLibraries());
189             Thread.currentThread().setContextClassLoader(cl);
190             Class JavaDoc componentClass = cl.loadClass(descriptor.getComponentClassName());
191             Component component = (Component) componentClass.newInstance();
192             result = container.activateComponent(
193                                     context.getInstallRootAsDir(),
194                                     component,
195                                     context.getComponentDescription(),
196                                     (ComponentContextImpl) context.getContext(),
197                                     context.isBinding(),
198                                     context.isEngine(),
199                                     context.getSharedLibraries());
200         }
201         catch (MalformedURLException JavaDoc e) {
202             log.error("Could not create class loader", e);
203             throw new DeploymentException(e);
204         }
205         catch (NoClassDefFoundError JavaDoc e) {
206             log.error("Class not found: " + descriptor.getBootstrapClassName(), e);
207             throw new DeploymentException(e);
208         }
209         catch (ClassNotFoundException JavaDoc e) {
210             log.error("Class not found: " + descriptor.getBootstrapClassName(), e);
211             throw new DeploymentException(e);
212         }
213         catch (InstantiationException JavaDoc e) {
214             log.error("Could not instantiate : " + descriptor.getBootstrapClassName(), e);
215             throw new DeploymentException(e);
216         }
217         catch (IllegalAccessException JavaDoc e) {
218             log.error("Illegal access on: " + descriptor.getBootstrapClassName(), e);
219             throw new DeploymentException(e);
220         }
221         catch (JBIException e) {
222             log.error("Could not initialize : " + descriptor.getBootstrapClassName(), e);
223             throw new DeploymentException(e);
224         }
225         finally {
226             Thread.currentThread().setContextClassLoader(oldCl);
227         }
228         return result;
229     }
230
231     /**
232      * Determine whether or not the component is installed.
233      *
234      * @return true if this component is currently installed, false if not.
235      */

236     public boolean isInstalled() {
237         return !context.isInstall();
238     }
239
240     /**
241      * Uninstall a BC or SE. This completely removes the component from the JBI system.
242      *
243      * @throws javax.jbi.JBIException if the uninstallation fails.
244      */

245     public void uninstall() throws javax.jbi.JBIException {
246         // TODO: check component status
247
// the component must not be started and not have any SUs deployed
248
if (!isInstalled()) {
249             throw new DeploymentException("Component is not installed");
250         }
251         String JavaDoc componentName = context.getComponentName();
252         try {
253             container.deactivateComponent(componentName);
254             bootstrap.onUninstall();
255             context.setInstall(true);
256         } finally {
257             cleanUpBootstrap();
258             
259             // If it was found by a destroyable classloader destroy it
260
// XXX Should we be holding the classloader as a member as always destroying it?
261
if (bootstrap.getClass().getClassLoader() instanceof DestroyableClassLoader) {
262                 ((DestroyableClassLoader) bootstrap.getClass().getClassLoader()).destroy();
263             }
264             System.gc();
265             container.getEnvironmentContext().removeComponentRootDirectory(componentName);
266         }
267     }
268
269     /**
270      * Get the installer configuration MBean name for this component.
271      *
272      * @return the MBean object name of the Installer Configuration MBean.
273      * @throws javax.jbi.JBIException if the component is not in the LOADED state or any error occurs during processing.
274      */

275     public ObjectName JavaDoc getInstallerConfigurationMBean() throws javax.jbi.JBIException {
276         return extensionMBeanName;
277     }
278     /**
279      * @return Returns the objectName.
280      */

281     public ObjectName JavaDoc getObjectName() {
282         return objectName;
283     }
284     /**
285      * @param objectName The objectName to set.
286      */

287     public void setObjectName(ObjectName JavaDoc objectName) {
288         this.objectName = objectName;
289     }
290
291     /**
292      * Buld a Custom ClassLoader
293      *
294      * @param dir
295      * @param classPathNames
296      * @param parentFirst
297      * @param list
298      * @return ClassLoader
299      * @throws MalformedURLException
300      * @throws MalformedURLException
301      * @throws DeploymentException
302      */

303     protected ClassLoader JavaDoc buildClassLoader(
304                     File JavaDoc dir,
305                     String JavaDoc[] classPathNames,
306                     boolean parentFirst,
307                     String JavaDoc[] list) throws MalformedURLException JavaDoc, DeploymentException {
308         
309         // Make the current ClassLoader the parent
310
ClassLoader JavaDoc[] parents;
311         
312         // Create a new parent if there are some shared libraries
313
if (list != null && list.length > 0) {
314             parents = new ClassLoader JavaDoc[list.length];
315             for (int i = 0; i < parents.length; i++) {
316                 org.apache.servicemix.jbi.framework.SharedLibrary sl =
317                     container.getRegistry().getSharedLibrary(list[i]);
318                 if (sl == null) {
319                     throw new DeploymentException("Shared library " + list[i] + " is not installed");
320                 }
321                 parents[i] = sl.getClassLoader();
322             }
323         } else {
324             parents = new ClassLoader JavaDoc[] { getClass().getClassLoader() };
325         }
326         
327         List JavaDoc urls = new ArrayList JavaDoc();
328         for (int i = 0; i < classPathNames.length; i++) {
329             File JavaDoc file = new File JavaDoc(dir, classPathNames[i]);
330             if (!file.exists()) {
331                 log.warn("Unable to add File " + file
332                         + " to class path as it doesn't exist: "
333                         + file.getAbsolutePath());
334             }
335             urls.add(file.toURL());
336         }
337
338         ClassLoader JavaDoc cl = new JarFileClassLoader(
339                         "Component ClassLoader",
340                         (URL JavaDoc[]) urls.toArray(new URL JavaDoc[urls.size()]),
341                         parents,
342                         !parentFirst,
343                         new String JavaDoc[0],
344                         new String JavaDoc[] { "java.", "javax." });
345         if (log.isDebugEnabled()) {
346             log.debug("Component class loader: " + cl);
347         }
348         return cl;
349     }
350
351 }
352
Popular Tags