KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > objectweb > petals > jbi > management > service > InstallationServiceImpl


1 /**
2  * PETALS - PETALS Services Platform.
3  * Copyright (c) 2005 Fossil E-Commerce, http://www.fossilec.com/
4  *
5  * This library is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU Lesser General Public
7  * License as published by the Free Software Foundation; either
8  * version 2.1 of the License, or (at your option) any later version.
9  * This library is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12  * Lesser General Public License for more details.
13  *
14  * You should have received a copy of the GNU Lesser General Public
15  * License along with this library; if not, write to the Free Software
16  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17  *
18  * -------------------------------------------------------------------------
19  * $Id: InstallationServiceImpl.java 154 2006-03-27 15:30:10Z alouis $
20  * -------------------------------------------------------------------------
21  */

22 package org.objectweb.petals.jbi.management.service;
23
24 import java.io.File JavaDoc;
25 import java.io.IOException JavaDoc;
26 import java.net.MalformedURLException JavaDoc;
27 import java.net.URI JavaDoc;
28 import java.net.URL JavaDoc;
29 import java.util.ArrayList JavaDoc;
30 import java.util.Collection JavaDoc;
31 import java.util.Iterator JavaDoc;
32 import java.util.List JavaDoc;
33 import java.util.zip.ZipFile JavaDoc;
34
35 import javax.jbi.management.LifeCycleMBean;
36 import javax.jbi.management.MBeanNames;
37 import javax.management.MBeanServer JavaDoc;
38 import javax.management.ObjectName JavaDoc;
39 import javax.naming.InitialContext JavaDoc;
40 import javax.naming.NamingException JavaDoc;
41
42 import org.apache.commons.io.FileUtils;
43 import org.objectweb.fractal.fraclet.annotation.FractalComponent;
44 import org.objectweb.fractal.fraclet.annotation.Interface;
45 import org.objectweb.fractal.fraclet.annotation.LifeCycle;
46 import org.objectweb.fractal.fraclet.annotation.LifeCycleType;
47 import org.objectweb.fractal.fraclet.annotation.Monolog;
48 import org.objectweb.fractal.fraclet.annotation.Provides;
49 import org.objectweb.fractal.fraclet.annotation.Requires;
50 import org.objectweb.petals.PetalsException;
51 import org.objectweb.petals.classloader.LoaderManager;
52 import org.objectweb.petals.jbi.component.context.ComponentContextImpl;
53 import org.objectweb.petals.jbi.component.context.ComponentInitialContext;
54 import org.objectweb.petals.jbi.component.lifecycle.ComponentLifeCycle;
55 import org.objectweb.petals.jbi.component.lifecycle.Installer;
56 import org.objectweb.petals.jbi.management.autoload.AutoLoaderImpl;
57 import org.objectweb.petals.jbi.management.systemstate.ComponentState;
58 import org.objectweb.petals.jbi.management.systemstate.SharedLibraryState;
59 import org.objectweb.petals.jbi.management.systemstate.SystemState;
60 import org.objectweb.petals.jbi.registry.ConsumerEndpoint;
61 import org.objectweb.petals.jbi.registry.Registry;
62 import org.objectweb.petals.jbi.routing.Router;
63 import org.objectweb.petals.repository.RepositoryService;
64 import org.objectweb.petals.tools.jbicommon.descriptor.ComponentDescription;
65 import org.objectweb.petals.tools.jbicommon.descriptor.JBIDescriptor;
66 import org.objectweb.petals.tools.jbicommon.descriptor.SharedLibrary;
67 import org.objectweb.petals.tools.jbicommon.descriptor.SharedLibraryList;
68 import org.objectweb.petals.util.LoggingUtil;
69 import org.objectweb.petals.util.ParameterCheckHelper;
70 import org.objectweb.petals.util.StringHelper;
71 import org.objectweb.petals.util.SystemUtil;
72 import org.objectweb.petals.util.ZipUtil;
73 import org.objectweb.util.monolog.api.Logger;
74
75 /**
76  * JBI installation service implementation.
77  *
78  * @version $Rev: 154 $ $Date: 2006-03-27 17:30:10 +0200 (lun., 27 mars 2006) $
79  * @since Petals 1.0
80  * @author <a HREF="mailto:rmarins@fossilec.com">Rafael Marins</a>
81  * @author ofabre - EBM Websourcing
82  */

83 @FractalComponent
84 @Provides(interfaces=@Interface(name="service",signature=org.objectweb.petals.jbi.management.service.InstallationService.class))
85 public class InstallationServiceImpl implements InstallationService {
86
87     public static final String JavaDoc ERROR_INSTALL_SHARED_LIBRARY = "Could not install the shared library ";
88
89     /**
90      * The endpointService is used to manage all the endpoint interfaces in a
91      * distributed context
92      */

93     @Requires(name="endpoint-service",signature=org.objectweb.petals.jbi.management.service.EndpointService.class)
94     protected EndpointService endpointService;
95
96     /**
97      * JBI Container :: JMX Agent Admin
98      */

99     @Requires(name="lifecyclemanager",signature=org.objectweb.petals.jbi.management.service.LifeCycleManagerService.class)
100     protected LifeCycleManagerService jmxAdmin;
101
102     /**
103      * Platform Component :: Loader Service
104      */

105     @Requires(name="classloader",signature=org.objectweb.petals.classloader.LoaderManager.class)
106     protected LoaderManager loaderSrv;
107
108     /**
109      * logger wrapper
110      */

111     protected LoggingUtil log;
112
113     /**
114      * Monolog Logger instance.
115      */

116     @Monolog(name="logger")
117     protected Logger logger;
118
119     /**
120      * Package Handler
121      */

122     protected PackageHandler packageHandler;
123
124     /**
125      * A {@link List} of loaded components.
126      */

127     protected List JavaDoc<String JavaDoc> componentLoadedCache;
128
129     /**
130      * A {@link List} of loaded shared libaries.
131      */

132     protected List JavaDoc<String JavaDoc> slLoadedCache;
133
134     /**
135      * JBI Container :: Recovery Service
136      */

137     @Requires(name="systemstate",signature=org.objectweb.petals.jbi.management.systemstate.SystemState.class)
138     protected SystemState recoverySrv;
139
140     /**
141      * JBI Container :: Recovery Service
142      */

143     @Requires(name="registry",signature=org.objectweb.petals.jbi.registry.Registry.class)
144     protected Registry registryService;
145
146     /**
147      * Platform Component :: Repository Service
148      */

149     @Requires(name="repository",signature=org.objectweb.petals.repository.RepositoryService.class)
150     protected RepositoryService repositorySrv;
151
152     /**
153      * The container router instance.
154      */

155     @Requires(name="router",signature=org.objectweb.petals.jbi.routing.Router.class)
156     protected Router router;
157
158     protected InitialContext JavaDoc componentInitialContext;
159
160     /**
161      * Default constructor.
162      */

163     public InstallationServiceImpl() {
164
165     }
166
167     /**
168      * @see javax.jbi.management.InstallationServiceMBean#installSharedLibrary(java.lang.String)
169      * Return ERROR_INSTALL_SHARED_LIBRARY if shared library can't be
170      * loaded correctly. It's an implementation choice !
171      */

172     public synchronized String JavaDoc installSharedLibrary(String JavaDoc slZipURL) {
173         log.start();
174         ParameterCheckHelper.isNullParameterWithLog(slZipURL, "slZipURL", log);
175         ParameterCheckHelper.isEmptyParameterWithLog(slZipURL, "slZipURL", log);
176         try {
177             new URL JavaDoc(slZipURL);
178         } catch (MalformedURLException JavaDoc e) {
179             throw new IllegalArgumentException JavaDoc("slZipURL is not a valid URL");
180         }
181
182         String JavaDoc msg;
183         String JavaDoc result = null;
184
185         JBIDescriptor descriptor = null;
186         String JavaDoc slName = null;
187         URI JavaDoc archiveURI = null;
188
189         try {
190             /*
191              * Transforming URL into URI
192              */

193
194             archiveURI = packageHandler.processAndGetPackageURI(slZipURL, true);
195
196             /*
197              * Loading descriptor and getting name
198              */

199
200             descriptor = packageHandler.loadDescriptor(archiveURI);
201
202             /*
203              * Checking shared lib package
204              */

205
206             checkSharedLibrary(descriptor, archiveURI);
207         } catch (Throwable JavaDoc e) {
208             msg = "Shared library package (" + slZipURL + ") isn't validated.";
209             log.error(msg, e);
210             throw new RuntimeException JavaDoc(msg);
211         }
212         try {
213             slName = getSharedLibraryName(descriptor);
214             /*
215              * Exploding shared library into the installation repository
216              */

217
218             URI JavaDoc installationRoot = explodeSL(slName, archiveURI);
219
220             /*
221              * Performing shared library installation
222              */

223
224             result = installSharedLibrary(installationRoot, descriptor);
225
226             /*
227              * Creating state holder for shared lib
228              */

229             File JavaDoc file = createFileFromURI(archiveURI);
230             File JavaDoc installedArchive = getInstalledArchive(file);
231             recoverySrv.createSharedLibraryStateHolder(slName, installationRoot
232                 .toURL().toString(), installedArchive.toURL().toString());
233
234             /*
235              * Copy archive file to installed dir
236              */

237             copyFile(file, installedArchive);
238
239             /*
240              * Create success file in workdir
241              */

242             createSuccessFile(installedArchive);
243
244             log.info("Shared library " + slName + " correctly installed !");
245         } catch (Throwable JavaDoc e) {
246             msg = ERROR_INSTALL_SHARED_LIBRARY + slZipURL;
247             log.error(msg, e);
248
249             // Reverse sl installation process in order to reput the system in
250
// its
251
// state before sl installation
252
reverseSLInstallation(slName);
253
254             throw new RuntimeException JavaDoc(msg);
255         }
256
257         log.end();
258
259         return result;
260     }
261
262     /**
263      * Expand the given package into the system repository
264      *
265      * @param slName
266      * the unique identifier of the shared lib
267      * @param archiveURI
268      * the shared lib zip archive URI
269      * @return return installation URI of the expanded package, null if it fails
270      * @throws ManagementException
271      * if the zip archive fails to deploy or if returned install
272      * root is null
273      */

274     protected URI JavaDoc explodeSL(String JavaDoc slName, URI JavaDoc archiveURI)
275         throws ManagementException {
276         String JavaDoc msg;
277         URI JavaDoc installationRoot = null;
278
279         try {
280             installationRoot = repositorySrv.addSharedLibPackage(slName,
281                 archiveURI);
282
283         } catch (PetalsException pe) {
284             msg = "Unexpected error adding JBI installation "
285                 + "package into repository. ";
286             log.error(msg, pe);
287             throw new ManagementException(msg, pe);
288         }
289
290         if (installationRoot == null) {
291             msg = "Unexpected Platform repository service error. The SL"
292                 + "installation root must NOT be null: " + slName;
293             log.error(msg);
294             throw new ManagementException(msg);
295         }
296         return installationRoot;
297     }
298
299     /**
300      * (non-Javadoc)
301      *
302      * @see org.objectweb.petals.jbi.management.service.InstallationService#installSharedLibrary(java.net.URI,
303      * org.objectweb.petals.tools.jbicommon.descriptor.JBIDescriptor)
304      */

305     public synchronized String JavaDoc installSharedLibrary(URI JavaDoc installationRoot,
306         JBIDescriptor descriptor) throws PetalsException {
307         log.start();
308         ParameterCheckHelper.isNullParameterWithLog(installationRoot,
309             "installationRoot", log);
310         ParameterCheckHelper.isNullParameterWithLog(descriptor, "descriptor",
311             log);
312         String JavaDoc msg;
313
314         /*
315          * Get shared library production element
316          */

317         SharedLibrary sl = descriptor.getSharedLibrary();
318
319         /*
320          * Get classloader delegation mode
321          */

322         boolean parentFirst = isParentFirst(sl);
323
324         /*
325          * Create baseUrls Array for shared lib classloader
326          */

327
328         List JavaDoc<URL JavaDoc> urls = new ArrayList JavaDoc<URL JavaDoc>();
329
330         try {
331             urls.add(installationRoot.toURL());
332         } catch (MalformedURLException JavaDoc e) {
333             // simple do nothing - JBI Package has responsibility in
334
// checking the archive contents against informations
335
// contained in JBI Descriptor first.
336
msg = "Unexpected error creating URL for shared lib classloader.";
337             log.info(msg, e);
338             throw new PetalsException(msg, e);
339         }
340
341         URL JavaDoc[] baseUrls = urls.toArray(new URL JavaDoc[] {});
342
343         /*
344          * Create shared lib classloader
345          */

346         String JavaDoc slName = sl.getIdentification().getName();
347         try {
348             loaderSrv.createSharedLibraryClassLoader(slName, baseUrls, sl
349                 .getSharedLibraryClassPath(), parentFirst);
350         } catch (PetalsException pe) {
351             msg = "Unexpected error creating class loader. ";
352             log.error(msg, pe);
353             throw new PetalsException(msg, pe);
354         }
355
356         /*
357          * add shared library to the loaded cache list
358          */

359         slLoadedCache.add(slName);
360
361         log.end();
362         return slName;
363     }
364
365     /**
366      * Check if the given sl is already loaded
367      *
368      * @param slID
369      * @return true if already loaded, false otherwise
370      */

371     public boolean isSLLoaded(String JavaDoc slID) {
372         return slLoadedCache.contains(slID);
373     }
374
375     /**
376      * Check if the given component is already loaded
377      *
378      * @param compID
379      * @return true if already loaded, false otherwise
380      */

381     public boolean isComponentLoaded(String JavaDoc compID) {
382         return componentLoadedCache.contains(compID);
383     }
384
385     /**
386      * @see javax.jbi.management.InstallationServiceMBean#loadInstaller(java.lang.String)
387      */

388     public synchronized ObjectName JavaDoc loadInstaller(String JavaDoc componentName) {
389         ParameterCheckHelper.isNullParameterWithLog(componentName,
390             "componentName", log);
391         ParameterCheckHelper.isEmptyParameterWithLog(componentName,
392             "componentName", log);
393         ObjectName JavaDoc result = null;
394         result = jmxAdmin.getInstallerByName(componentName);
395         return result;
396     }
397
398     /**
399      * @see javax.jbi.management.InstallationServiceMBean#loadNewInstaller(java.lang.String)
400      * Return a specific ObjectName if component can't be installed
401      * correctly. It's an implementation choice !
402      * @throws RuntimeException
403      * if an error occurs during installation process. We have
404      * chosen this type of exception because, in the specification,
405      * this method doesn't return an exception
406      */

407     public synchronized ObjectName JavaDoc loadNewInstaller(String JavaDoc installZipURL) {
408         log.start();
409         ParameterCheckHelper.isNullParameterWithLog(installZipURL,
410             "installZipURL", log);
411         ParameterCheckHelper.isEmptyParameterWithLog(installZipURL,
412             "installZipURL", log);
413         try {
414             new URL JavaDoc(installZipURL);
415         } catch (Throwable JavaDoc e) {
416             throw new IllegalArgumentException JavaDoc(
417                 "installZipUrl must be a legal url", e);
418         }
419         String JavaDoc msg = null;
420         ObjectName JavaDoc result = null;
421         JBIDescriptor descriptor = null;
422         String JavaDoc componentName = null;
423         URI JavaDoc archiveURI = null;
424
425         try {
426             /*
427              * Transforming URL into URI
428              */

429
430             archiveURI = packageHandler.processAndGetPackageURI(installZipURL,
431                 true);
432
433             /*
434              * Loading descriptor and getting name
435              */

436
437             descriptor = packageHandler.loadDescriptor(archiveURI);
438
439             /*
440              * Checking component package
441              */

442
443             checkComponent(descriptor, archiveURI);
444
445         } catch (Throwable JavaDoc e) {
446             msg = "Component package (" + installZipURL + ") isn't validated.";
447             log.error(msg, e);
448
449             throw new RuntimeException JavaDoc(msg);
450         }
451
452         try {
453             componentName = getComponentNameFromJBIDescriptor(descriptor);
454
455             /*
456              * Exploding component into the installation repository
457              */

458
459             URI JavaDoc installationRoot = explodeComponent(componentName, archiveURI);
460
461             /*
462              * Performing shared library installation
463              */

464
465             result = loadNewInstaller(installationRoot, descriptor);
466
467             /*
468              * Creating state holder for component
469              */

470             File JavaDoc file = createFileFromURI(archiveURI);
471             File JavaDoc installedArchive = getInstalledArchive(file);
472             recoverySrv.createComponentStateHolder(componentName,
473                 installationRoot.toURL().toString(), installedArchive.toURI()
474                     .toString(), Installer.UNINSTALLED, LifeCycleMBean.UNKNOWN);
475
476             /*
477              * Copy archive file to installed dir
478              */

479             copyFile(file, installedArchive);
480
481             /*
482              * Create success file in workdir
483              */

484             createSuccessFile(installedArchive);
485
486             log.info("Component " + componentName + " correctly installed ! ");
487         } catch (Throwable JavaDoc e) {
488             msg = "Component can't be installed: " + installZipURL;
489             log.error(msg, e);
490
491             // Reverse installation process in order to reput the system in its
492
// state before component installation
493
reverseComponentInstallation(componentName, result);
494
495             throw new RuntimeException JavaDoc(msg);
496         }
497         log.end();
498
499         return result;
500     }
501
502     /**
503      * Expand the given package into the system repository
504      *
505      * @param componentName
506      * the unique identifier of the component
507      * @param archiveURI
508      * the component zip archive URI
509      * @return return installation URI of the expanded package, null if it fails
510      * @throws ManagementException
511      * if the zip archive fails to deploy or if returned install
512      * root is null
513      */

514     protected URI JavaDoc explodeComponent(String JavaDoc componentName, URI JavaDoc archiveURI)
515         throws ManagementException {
516         String JavaDoc msg;
517         URI JavaDoc installationRoot = null;
518
519         try {
520             installationRoot = repositorySrv.addComponentPackage(componentName,
521                 archiveURI);
522
523         } catch (PetalsException pe) {
524             msg = "Unexpected error adding JBI installation "
525                 + "package into repository. ";
526             log.error(msg, pe);
527             throw new ManagementException(msg, pe);
528         }
529
530         if (installationRoot == null) {
531             msg = "Unexpected Platform repository service error. The Component"
532                 + "installation root must NOT be null: " + componentName;
533             log.error(msg);
534             throw new ManagementException(msg);
535         }
536         return installationRoot;
537     }
538
539     /**
540      * (non-Javadoc)
541      *
542      * @see org.objectweb.petals.jbi.management.service.InstallationService#loadNewInstaller(java.net.URI,
543      * org.objectweb.petals.tools.jbicommon.descriptor.JBIDescriptor)
544      */

545     public synchronized ObjectName JavaDoc loadNewInstaller(URI JavaDoc installationRoot,
546         JBIDescriptor descriptor) throws PetalsException {
547         log.start();
548         ParameterCheckHelper.isNullParameterWithLog(installationRoot,
549             "installationRoot", log);
550         ParameterCheckHelper.isNullParameterWithLog(descriptor, "descriptor",
551             log);
552
553         /*
554          * Check installed shared lib for component : a shared lib must be
555          * installed before a component can be installed that makes use of the
556          * shared lib
557          */

558         checkInstalledSLForComp(descriptor);
559
560         /*
561          * Creating Component and Installation contexts
562          */

563
564         ComponentContextImpl compContextImpl = createComponentContext(
565             descriptor, installationRoot);
566
567         /*
568          * Creating and registering installer mbean
569          */

570
571         ObjectName JavaDoc result = createAndRegisterInstallerMBean(compContextImpl,
572             descriptor, installationRoot);
573
574         /*
575          * Adding component to the loaded cache list
576          */

577
578         componentLoadedCache.add(getComponentNameFromJBIDescriptor(descriptor));
579
580         log.end();
581         return result;
582     }
583
584     /**
585      * @see javax.jbi.management.InstallationServiceMBean#uninstallSharedLibrary(java.lang.String)
586      */

587     public synchronized boolean uninstallSharedLibrary(String JavaDoc slName) {
588         log.start();
589         ParameterCheckHelper.isNullParameterWithLog(slName, "slName", log);
590         ParameterCheckHelper.isEmptyParameterWithLog(slName, "slName", log);
591         boolean result = false;
592
593         /*
594          * The slName must be non null and all components that makes use of the
595          * given sl must be in the shutdown state
596          */

597         if (checkComponentShutdownStateForSL(slName)) {
598             /*
599              * unload shared library class loaders and clean cache
600              */

601             loaderSrv.deleteClassLoader(slName);
602
603             slLoadedCache.remove(slName);
604
605             /*
606              * Remove shared lib from state holder file
607              */

608             SharedLibraryState slState = null;
609             try {
610                 slState = recoverySrv.deleteSharedLibraryStateHolder(slName);
611             } catch (Exception JavaDoc e) {
612                 String JavaDoc msg = "Shared library isn't completely uninstalled ! "
613                     + "State holder isn't deleted";
614                 log.error(msg, e);
615                 return false;
616             }
617
618             /*
619              * clean package installation from platform repository
620              */

621             try {
622                 result = repositorySrv.removeSharedLibPackage(slName);
623             } catch (PetalsException e1) {
624                 String JavaDoc msg = "Shared library isn't completely uninstalled ! "
625                     + "Failed to remove shared lib package.";
626                 log.error(msg, e1);
627                 return false;
628             }
629
630             /*
631              * Move archive file to uninstalled dir
632              */

633             try {
634                 File JavaDoc installedArchive = null;
635                 if (slState != null) {
636                     URI JavaDoc archiveURI = packageHandler.processAndGetPackageURI(
637                         slState.getArchiveURL(), false);
638                     installedArchive = createFileFromURI(archiveURI);
639                 }
640                 if (installedArchive != null && installedArchive.exists()) {
641                     File JavaDoc uninstalledArchive = getUninstalledArchive(installedArchive);
642                     installedArchive.renameTo(uninstalledArchive);
643                     installedArchive = null;
644
645                 }
646             } catch (IllegalArgumentException JavaDoc e) {
647                 log.error("Error getting URI from package url. ", e);
648                 return false;
649             }
650         }
651         log.end();
652
653         return result;
654     }
655
656     /**
657      * TODO isToBeDeleted parameter isn't used for the moment : this method
658      * completly deletes the component from the container TODO Refactoring
659      * failure cases
660      *
661      * @see javax.jbi.management.InstallationServiceMBean#unloadInstaller(java.lang.String,
662      * boolean)
663      */

664     public synchronized boolean unloadInstaller(String JavaDoc componentName,
665         boolean isToBeDeleted) {
666         log.start();
667         ParameterCheckHelper.isNullParameterWithLog(componentName,
668             "componentName", log);
669         ParameterCheckHelper.isEmptyParameterWithLog(componentName,
670             "componentName", log);
671         boolean result = false;
672
673         /*
674          * Call uninstall on Installer
675          */

676         ObjectName JavaDoc instName = jmxAdmin.getInstallerByName(componentName);
677         MBeanServer JavaDoc mbeanSrv = jmxAdmin.getMBeanServer();
678         Object JavaDoc[] nullObjects = new Object JavaDoc[0];
679         String JavaDoc[] nullStrings = new String JavaDoc[0];
680         try {
681             boolean isInstalled = ((Boolean JavaDoc) mbeanSrv.getAttribute(instName,
682                 "Installed")).booleanValue();
683             if (isInstalled) {
684                 mbeanSrv
685                     .invoke(instName, "uninstall", nullObjects, nullStrings);
686             }
687         } catch (Throwable JavaDoc e) {
688             log.error("Error uninstalling component : " + componentName + "."
689                 + e.getMessage(), e);
690             return false;
691         }
692
693         /*
694          * unload installer from manager service
695          */

696         try {
697             jmxAdmin.unregisterInstaller(instName);
698         } catch (ManagementException e) {
699             log.error("Error uninstalling component : " + componentName + "."
700                 + e.getMessage(), e);
701             return false;
702         }
703
704         /*
705          * Clean package loaded
706          */

707         componentLoadedCache.remove(componentName);
708
709         /*
710          * Remove component from state holder file
711          */

712         ComponentState componentState = null;
713         try {
714             componentState = recoverySrv
715                 .deleteComponentStateHolder(componentName);
716         } catch (Exception JavaDoc e) {
717             String JavaDoc msg = "Component isn't completely uninstalled ! "
718                 + "State holder isn't deleted";
719             log.error(msg, e);
720             return false;
721         }
722
723         /*
724          * clean package installation from platform repository
725          */

726
727         try {
728             result = repositorySrv.removeComponentPackage(componentName);
729         } catch (PetalsException e1) {
730             String JavaDoc msg = "Component isn't completely uninstalled ! "
731                 + "Failed to delete component package";
732             log.error(msg, e1);
733             return false;
734         }
735
736         /*
737          * Move archive file to uninstalled dir
738          */

739         try {
740             File JavaDoc installedArchive = null;
741             if (componentState != null) {
742                 URI JavaDoc archiveURI = packageHandler.processAndGetPackageURI(
743                     componentState.getArchiveURL(), false);
744                 installedArchive = createFileFromURI(archiveURI);
745
746             }
747             if (installedArchive != null && installedArchive.exists()) {
748                 File JavaDoc uninstalledArchive = getUninstalledArchive(installedArchive);
749                 installedArchive.renameTo(uninstalledArchive);
750                 installedArchive = null;
751                 /*
752                  * FileUtils.copyFile(installedArchive, uninstalledArchive);
753                  * FileUtils.forceDelete(installedArchive);
754                  */

755
756             }
757             /*
758              * } catch (IOException e) { log.error( "Error moving archive from
759              * installed to uninstalled dir. " + e.getMessage(), e); return
760              * false;
761              */

762         } catch (IllegalArgumentException JavaDoc e) {
763             log.error("Error uninstalling component : " + componentName + "."
764                 + e.getMessage(), e);
765             return false;
766         }
767
768         log.end();
769         return result;
770     }
771
772     /**
773      * Check the classpath element of the jbi descriptor
774      *
775      * @param archive
776      * a ZipFile object mapping a real zip file entity
777      * @param classPath
778      * a List of classpath elements to check
779      * @throws PetalsException
780      */

781     protected void checkClassPathElements(ZipFile JavaDoc archive,
782         List JavaDoc<String JavaDoc> classPath) throws PetalsException {
783         String JavaDoc msg;
784
785         for (String JavaDoc pathElement : classPath) {
786
787             /*
788              * empty class-path elements is not allowed
789              */

790             if (pathElement == null || "".equals(pathElement.trim())) {
791                 msg = "An empty class-path element found "
792                     + "in the JBI Descriptor file (jbi.xml).";
793                 throw new PetalsException(msg);
794             }
795
796             /*
797              * check if the specified path element exists within archive
798              */

799             if (!hasEntry(archive, pathElement)) {
800                 msg = "A class-path element " + pathElement + " declared in "
801                     + "JBI Descriptor not found within installation "
802                     + "package Zip archive file.";
803                 throw new PetalsException(msg);
804             }
805         }
806     }
807
808     /**
809      * Check the validity of the component archive
810      *
811      * @param descriptor
812      * the component <code>JBIDescriptor</code>
813      * @param archiveURI
814      * URI representing the component archive
815      * @return true if checking is completly ok and false otherwise
816      * @throws PetalsException
817      * if component element or name is null or empty, if component
818      * is already installed or if some classpath elements of the
819      * component are missing
820      */

821     protected void checkComponent(JBIDescriptor descriptor, URI JavaDoc archiveURI)
822         throws PetalsException {
823         String JavaDoc msg = null;
824
825         /*
826          * check if jbi descriptor has a component element
827          */

828
829         ComponentDescription comp = descriptor.getComponent();
830         if (comp == null) {
831             msg = "The component production element was not found in "
832                 + "JBI Descriptor within installation package: "
833                 + archiveURI.getPath();
834             log.error(msg);
835             throw new PetalsException(msg);
836         } else {
837
838             /*
839              * check if it is already loaded by package uuid
840              */

841
842             String JavaDoc compName = comp.getIdentification().getName();
843
844             if (StringHelper.isEmpty(compName)) {
845                 msg = "The component name must be non null and non empty for the new component :"
846                     + archiveURI.getPath();
847                 log.error(msg);
848                 throw new PetalsException(msg);
849             }
850
851             if (isComponentLoaded(compName)) {
852                 msg = "Other installation package already exists loaded in "
853                     + "the component framework: " + compName;
854
855                 log.error(msg);
856                 throw new PetalsException(msg);
857             } else {
858
859                 /*
860                  * Check the classpath elements of the component
861                  */

862
863                 ZipFile JavaDoc zipArchive = openZipFile(archiveURI);
864
865                 try {
866                     checkClassPathElements(zipArchive, comp
867                         .getBootstrapClassPath());
868                     checkClassPathElements(zipArchive, comp
869                         .getComponentClassPath());
870                 } finally {
871                     try {
872                         zipArchive.close();
873                     } catch (IOException JavaDoc e) {
874                         msg = "Component archive can't be closed";
875                         log.error(msg);
876                         throw new PetalsException(msg, e);
877                     }
878                 }
879             }
880         }
881     }
882
883     /**
884      * Check that all components that makes use of the given sl are in the
885      * shutdown state.
886      *
887      * @param slName
888      * the sl identifier
889      * @return true if all components that makes use of the given sl are in the
890      * shutdown state, false otherwise
891      */

892     protected boolean checkComponentShutdownStateForSL(String JavaDoc slName) {
893         boolean result = true;
894
895         /*
896          * Check for bindings
897          */

898         Collection JavaDoc<ComponentLifeCycle> bindings = jmxAdmin
899             .getBindingCompoLifeCycles().values();
900         for (Iterator JavaDoc iter = bindings.iterator(); iter.hasNext() && result;) {
901             ComponentLifeCycle cycle = (ComponentLifeCycle) iter.next();
902
903             /*
904              * Retrieve the list of used sl
905              */

906             ComponentDescription description = cycle.getComponentDescription();
907             List JavaDoc<SharedLibraryList> sls = description.getSharedLibraryList();
908
909             if (sls != null) {
910                 for (Iterator JavaDoc iter2 = sls.iterator(); iter2.hasNext() && result;) {
911                     SharedLibraryList sl = (SharedLibraryList) iter2.next();
912
913                     /*
914                      * If a used component isn't in the shutdown state, shared
915                      * lib can't be uninstalled
916                      */

917                     if (slName.equals(sl.getName())
918                         && !(LifeCycleMBean.SHUTDOWN.equals(cycle
919                             .getCurrentState()))) {
920                         log
921                             .error("The shared lib can't be uninstalled because the following "
922                                 + "component isn't in the shutdown state : "
923                                 + description.getIdentification().getName());
924                         result = false;
925                     }
926                 }
927             }
928         }
929
930         /*
931          * Check for engines
932          */

933         Collection JavaDoc<ComponentLifeCycle> engines = jmxAdmin
934             .getEngineCompoLifeCycles().values();
935         for (Iterator JavaDoc iter = engines.iterator(); iter.hasNext() && result;) {
936             ComponentLifeCycle cycle = (ComponentLifeCycle) iter.next();
937
938             /*
939              * Retrieve the list of used sl
940              */

941             ComponentDescription description = cycle.getComponentDescription();
942             List JavaDoc<SharedLibraryList> sls = description.getSharedLibraryList();
943
944             if (sls != null) {
945                 for (Iterator JavaDoc iter2 = sls.iterator(); iter2.hasNext() && result;) {
946                     SharedLibraryList sl = (SharedLibraryList) iter2.next();
947
948                     /*
949                      * If a used component isn't in the shutdown state, shared
950                      * lib can't be uninstalled
951                      */

952                     if (slName.equals(sl.getName())
953                         && !(LifeCycleMBean.SHUTDOWN.equals(cycle
954                             .getCurrentState()))) {
955                         log
956                             .error("The shared lib "
957                                 + slName
958                                 + " can't be uninstalled because"
959                                 + " the following component isn't in the shutdown state : "
960                                 + description.getIdentification().getName());
961                         result = false;
962                     }
963                 }
964             }
965         }
966
967         return result;
968     }
969
970     /**
971      * Check installed shared lib for component
972      *
973      * @param descriptor
974      * the component <code>JBIDescriptor</code>
975      * @throws PetalsException
976      * if a shared library is missing for the component being
977      * installed
978      */

979     protected void checkInstalledSLForComp(JBIDescriptor descriptor)
980         throws PetalsException {
981         List JavaDoc<SharedLibraryList> sls = descriptor.getComponent()
982             .getSharedLibraryList();
983
984         if (sls != null) {
985             for (SharedLibraryList list : sls) {
986                 if (!slLoadedCache.contains(list.getName())) {
987                     String JavaDoc msg = "Component depends on a not installed shared library : "
988                         + list.getName();
989
990                     log.error(msg);
991                     throw new PetalsException(msg);
992                 }
993             }
994         }
995     }
996
997     /**
998      * Check the validity of the shared lib archive
999      *
1000     * @param descriptor
1001     * the shared lib <code>JBIDescriptor</code>
1002     * @param archiveURI
1003     * URI representing the shared lib archive
1004     * @return true if checking is completly ok and false otherwise
1005     * @throws PetalsException
1006     * @throws ComponentCheckingException
1007     */

1008    protected void checkSharedLibrary(JBIDescriptor descriptor, URI JavaDoc archiveURI)
1009        throws PetalsException {
1010        String JavaDoc msg = null;
1011
1012        /*
1013         * check if jbi descriptor has a shared-library element
1014         */

1015
1016        SharedLibrary sl = descriptor.getSharedLibrary();
1017        if (sl == null) {
1018            msg = "The shared-library production element was not found in "
1019                + "JBI Descriptor within installation package: "
1020                + archiveURI.getPath();
1021
1022            log.error(msg);
1023            throw new PetalsException(msg);
1024        } else {
1025
1026            /*
1027             * check if it is already loaded by package uuid
1028             */

1029
1030            String JavaDoc slName = sl.getIdentification().getName();
1031
1032            if (isSLLoaded(slName)) {
1033                msg = "Other installation package already exists loaded in "
1034                    + "the component framework: " + slName;
1035
1036                log.error(msg);
1037
1038                throw new PetalsException(msg);
1039            } else {
1040
1041                /*
1042                 * Check the classpath element of the shared library
1043                 */

1044
1045                ZipFile JavaDoc zipArchive = openZipFile(archiveURI);
1046
1047                try {
1048                    checkClassPathElements(zipArchive, sl
1049                        .getSharedLibraryClassPath());
1050                } finally {
1051                    try {
1052                        zipArchive.close();
1053                    } catch (IOException JavaDoc e) {
1054                        msg = "Shared library archive can't be closed";
1055                        log.error(msg, e);
1056                        throw new PetalsException(msg, e);
1057                    }
1058                }
1059            }
1060
1061        }
1062    }
1063
1064    /**
1065     * Copies a file from source to destination
1066     *
1067     * @param src
1068     * source file
1069     * @param dest
1070     * destination file
1071     * @throws IOException
1072     * if an error occurs during copy process
1073     */

1074    protected void copyFile(File JavaDoc src, File JavaDoc dest) throws IOException JavaDoc {
1075        FileUtils.copyFile(src, dest);
1076    }
1077
1078    /**
1079     * Create and register a new InstallerMBean for the loaded component
1080     *
1081     * @param componentContext
1082     * the new Component execution context
1083     * @param installationContext
1084     * the new Component installaion context
1085     * @param descriptor
1086     * the component JBIDescriptor
1087     * @param installationRoot
1088     * the URI representing the component installation folder
1089     * @return the new InstallerMBean name
1090     * @throws PetalsException
1091     */

1092    protected ObjectName JavaDoc createAndRegisterInstallerMBean(
1093        ComponentContextImpl componentContext, JBIDescriptor descriptor,
1094        URI JavaDoc installationRoot) throws PetalsException {
1095        log.start();
1096        ObjectName JavaDoc result = null;
1097        ComponentDescription componentDescription = descriptor.getComponent();
1098        try {
1099            MBeanNamesImpl mbeanNames = jmxAdmin.getMBeanNames();
1100            result = mbeanNames.createInstallerMBeanName(componentDescription
1101                .getIdentification().getName());
1102            
1103            Installer installerMBean = new Installer(installationRoot,
1104                loaderSrv, componentContext, componentDescription, jmxAdmin,
1105                recoverySrv, result, logger);
1106
1107            jmxAdmin.registerInstaller(installerMBean);
1108        } catch (ManagementException e) {
1109            String JavaDoc msg = "Error creating installerMBean.";
1110            log.error(msg, e);
1111            throw new PetalsException(msg, e);
1112        }
1113        log.end();
1114        return result;
1115    }
1116
1117    /**
1118     * Create a new ComponentContext for the loaded component with a new
1119     * DeliveryChannel
1120     *
1121     * @param descriptor
1122     * the component <code>JBIDescriptor</code>
1123     * @param installationRoot
1124     * the component installation folder
1125     * @return a new <code>ComponentContext</code> implementation
1126     * @throws PetalsException
1127     * if the creation of an initial context for components fails
1128     */

1129    protected ComponentContextImpl createComponentContext(
1130        JBIDescriptor descriptor, URI JavaDoc installationRoot) throws PetalsException {
1131        log.start();
1132
1133        String JavaDoc componentName = descriptor.getComponent().getIdentification()
1134            .getName();
1135
1136        String JavaDoc installationRootPath = new File JavaDoc(installationRoot)
1137            .getAbsolutePath();
1138
1139        String JavaDoc workingRootPath = repositorySrv.getComponentWorkRoot(
1140            componentName).getAbsolutePath();
1141
1142        MBeanServer JavaDoc beanServer = jmxAdmin.getMBeanServer();
1143        MBeanNames beanNames = jmxAdmin.getMBeanNames();
1144
1145        ConsumerEndpoint address = new ConsumerEndpoint(componentName,
1146            SystemUtil.getContainerName());
1147
1148        if (componentInitialContext == null) {
1149            try {
1150                componentInitialContext = new ComponentInitialContext(
1151                    registryService.getUsersContext());
1152            } catch (NamingException JavaDoc e) {
1153                String JavaDoc msg = "Error creating InitialContext for components";
1154                log.error(msg, e);
1155                throw new PetalsException(msg, e);
1156            }
1157        }
1158
1159        ComponentContextImpl componentContextImpl = new ComponentContextImpl(
1160            descriptor, installationRootPath, workingRootPath, beanNames,
1161            beanServer, jmxAdmin, address, endpointService, logger, router,
1162            componentInitialContext);
1163
1164        log.end();
1165
1166        return componentContextImpl;
1167    }
1168    
1169    /**
1170     * Create a new File instance with the fileURI
1171     *
1172     * @param fileURI
1173     * URI of the file to create
1174     * @return a new File instance
1175     */

1176    protected File JavaDoc createFileFromURI(URI JavaDoc fileURI) {
1177        return new File JavaDoc(fileURI);
1178    }
1179
1180    /**
1181     * Create a ".success" file in the work directory. The name of the new file
1182     * is the name of the "file" parameter with the suffix ".succes"
1183     *
1184     * @param file
1185     * file from which the name is computed
1186     * @throws IOException
1187     * If an error occurs at the file creation
1188     */

1189    protected void createSuccessFile(File JavaDoc file) throws IOException JavaDoc {
1190        new File JavaDoc(AutoLoaderImpl.getWorkDirectory(), file.getName() + ".success")
1191            .createNewFile();
1192    }
1193
1194    /**
1195     * Return the name of from the component description found in the descriptor
1196     *
1197     * @param descriptor
1198     * the JBI descriptor
1199     * @return the name of the component
1200     */

1201    protected String JavaDoc getComponentNameFromJBIDescriptor(JBIDescriptor descriptor) {
1202        return descriptor.getComponent().getIdentification().getName();
1203    }
1204
1205    /**
1206     * Returns the shared library installedArchive
1207     *
1208     * @param file
1209     * the shared library file name
1210     * @return a File pointing at the shared library installed archive
1211     */

1212    protected File JavaDoc getInstalledArchive(File JavaDoc file) {
1213        return new File JavaDoc(AutoLoaderImpl.getInstalledDirectory(), file.getName());
1214    }
1215
1216    /**
1217     * Get the sharedLibrary name from the JBI descriptor
1218     *
1219     * @param descriptor
1220     * the JBI descriptor
1221     * @return shared library name
1222     */

1223    protected String JavaDoc getSharedLibraryName(JBIDescriptor descriptor) {
1224        return descriptor.getSharedLibrary().getIdentification().getName();
1225    }
1226
1227    /**
1228     * Returns the shared library uninstalledArchive
1229     *
1230     * @param file
1231     * the shared library file name
1232     * @return a File pointing at the shared library uninstalled archive
1233     */

1234    protected File JavaDoc getUninstalledArchive(File JavaDoc file) {
1235        return new File JavaDoc(AutoLoaderImpl.getUninstalledDirectory(), file
1236            .getName());
1237    }
1238
1239    /**
1240     * Checks if the zip archive has one element with the pathElement name
1241     *
1242     * @param archive
1243     * the zip archive
1244     * @param pathElement
1245     * the element to find
1246     * @return true if the element was found in the zip archive
1247     */

1248    protected boolean hasEntry(ZipFile JavaDoc archive, String JavaDoc pathElement) {
1249        return ZipUtil.hasEntry(archive, pathElement);
1250    }
1251
1252    /**
1253     * Initialize the InstallationServiceImpl
1254     */

1255    @LifeCycle(on=LifeCycleType.START)
1256    protected void start() {
1257        log = new LoggingUtil(logger);
1258        log.start();
1259
1260        /*
1261         * initialize entity loaded cache
1262         */

1263        slLoadedCache = new ArrayList JavaDoc<String JavaDoc>();
1264        componentLoadedCache = new ArrayList JavaDoc<String JavaDoc>();
1265
1266        /*
1267         * Initialize package handler
1268         */

1269        packageHandler = new PackageHandler(logger, repositorySrv);
1270
1271        log.end();
1272    }
1273
1274    /**
1275     * @param sl
1276     * @return
1277     */

1278    protected boolean isParentFirst(SharedLibrary sl) {
1279        return JBIDescriptor.isParentFirst(sl.getClassLoaderDelegation());
1280    }
1281
1282    /**
1283     * Get the zip archive at the archiveURI
1284     *
1285     * @param archiveURI
1286     * the URI of the zip archive
1287     * @return the zip archive
1288     * @throws PetalsException
1289     * if the archive can not be found or opened
1290     */

1291    protected ZipFile JavaDoc openZipFile(URI JavaDoc archiveURI) throws PetalsException {
1292        return ZipUtil.openZipFile(archiveURI);
1293    }
1294
1295    /**
1296     * Reverse component installation process in order to reput the system in
1297     * its state before component installation
1298     *
1299     * @param componentName
1300     * the component unique identifier
1301     * @param installerMBeanName
1302     * the created installer MBean name
1303     */

1304    protected void reverseComponentInstallation(String JavaDoc componentName,
1305        ObjectName JavaDoc installerMBeanName) {
1306        if (!StringHelper.isEmpty(componentName)) {
1307            // Reverse installer MBean registration
1308
if (installerMBeanName != null) {
1309                try {
1310                    jmxAdmin.unregisterInstaller(installerMBeanName);
1311                } catch (ManagementException e) {
1312                    // Nothing to do just log
1313
log
1314                        .warning("Component installer can't be unregistered or doesn't exist");
1315                }
1316            }
1317
1318            // Delete component from already loaded component
1319
if (isComponentLoaded(componentName)) {
1320                componentLoadedCache.remove(componentName);
1321            }
1322
1323            // Reverse state holder creation
1324
try {
1325                recoverySrv.deleteComponentStateHolder(componentName);
1326            } catch (Exception JavaDoc e) {
1327                // Nothing to do just log
1328
log
1329                    .warning("Component state can't be deleted or doesn't exist");
1330            }
1331
1332            // Reverse component file system creation
1333
try {
1334                File JavaDoc compRoot = repositorySrv.getComponentRoot(componentName);
1335                if (compRoot.exists()) {
1336
1337                    FileUtils.forceDelete(compRoot);
1338                }
1339            } catch (Exception JavaDoc e) {
1340                // Nothing to do just log
1341
log.warning("Component root can't be deleted or doesn't exist");
1342            }
1343        }
1344    }
1345
1346    /**
1347     * Reverse sl installation process in order to reput the system in its state
1348     * before sl installation
1349     *
1350     * @param slName
1351     * the sl unique identifier
1352     */

1353    protected void reverseSLInstallation(String JavaDoc slName) {
1354        if (!StringHelper.isEmpty(slName)) {
1355
1356            // Reverse classloader creation
1357
loaderSrv.deleteClassLoader(slName);
1358
1359            // Delete sl from already loaded sl
1360
if (isComponentLoaded(slName)) {
1361                slLoadedCache.remove(slName);
1362            }
1363
1364            // Reverse state holder creation
1365
try {
1366                recoverySrv.deleteSharedLibraryStateHolder(slName);
1367            } catch (Exception JavaDoc e) {
1368                // Nothing to do just log
1369
log
1370                    .warning("Shared lib state can't be deleted or doesn't exist");
1371            }
1372
1373            // Reverse sl file system creation
1374
try {
1375                File JavaDoc compRoot = repositorySrv.getSharedLibRoot(slName);
1376                if (compRoot.exists()) {
1377
1378                    FileUtils.forceDelete(compRoot);
1379                }
1380            } catch (Exception JavaDoc e) {
1381                // Nothing to do just log
1382
log
1383                    .warning("Shared lib root can't be deleted or doesn't exist");
1384            }
1385        }
1386    }
1387
1388    /**
1389     * Stop the InstallationServiceImpl
1390     */

1391    @LifeCycle(on=LifeCycleType.STOP)
1392    public void stop() {
1393        log.start();
1394
1395        slLoadedCache = null;
1396        componentLoadedCache = null;
1397
1398        log.end();
1399    }
1400
1401    /**
1402     * Shutdown the InstallationService. All shared libraries and components are
1403     * uninstalled
1404     */

1405    public void shutdown() throws Exception JavaDoc {
1406        // Uninstall all components
1407
List JavaDoc<String JavaDoc> removeList = new ArrayList JavaDoc<String JavaDoc>(componentLoadedCache);
1408        for (String JavaDoc compName : removeList) {
1409            unloadInstaller(compName, true);
1410        }
1411
1412        // Uninstall all shared libs
1413
removeList = new ArrayList JavaDoc<String JavaDoc>(slLoadedCache);
1414        for (String JavaDoc slName : removeList) {
1415            uninstallSharedLibrary(slName);
1416        }
1417
1418    }
1419
1420}
1421
Popular Tags