User: schulze 
  Date: 00/11/24 15:28:21

  Modified:    src/main/org/jboss/deployment Deployment.java
                        URLWizzard.java J2eeDeployer.java
  Added:       src/main/org/jboss/deployment Installer.java
                        InstallerFactory.java
  Log:
  moved the installation code out of the J2eeDeployer and encapsulated it into the 
Installer/InstallerFactory.
  
  changed:
  - automatically prepends a slash for webContexts (if not given in application.xml 
file like in petstore)
  - adds all manifest/classpath references to the common classpath (manifests of the 
modules, not the ear manifest)
  - adds all ejb jars to the common classpath (just in case...)
  
  Revision  Changes    Path
  1.5       +51 -2     jboss/src/main/org/jboss/deployment/Deployment.java
  
  Index: Deployment.java
  ===================================================================
  RCS file: /products/cvs/ejboss/jboss/src/main/org/jboss/deployment/Deployment.java,v
  retrieving revision 1.4
  retrieving revision 1.5
  diff -u -r1.4 -r1.5
  --- Deployment.java   2000/11/06 21:10:26     1.4
  +++ Deployment.java   2000/11/24 23:28:19     1.5
  @@ -11,21 +11,28 @@
   
   import java.util.Iterator;
   import java.util.Vector;
  +import java.util.Date;
   
   /** Represents a J2EE application or module (EJB.jar, Web.war or App.ear). <br>
   *
   *  @author <a href="mailto:[EMAIL PROTECTED]">Daniel Schulze</a>
  -*  @version $Revision: 1.4 $
  +*  @version $Revision: 1.5 $
   */
   public class Deployment
      implements java.io.Serializable
   {
        /** the apploications name */
      protected String name;
  +
  +     /** the date this deployment was made */
  +     protected Date date;
      
      /** the local position of the apps root directory */
      protected URL localUrl;
      
  +   /** the position from which this deployment is installed */
  +   protected URL sourceUrl;
  +
      /** the content of the <code>commonLibs</code> directory as 
      URL Collection */
      protected Vector commonUrls;
  @@ -39,6 +46,8 @@
      /** Creates a new Deployment object.  */
      Deployment ()
      {
  +        date = new Date();
  +
         ejbModules = new Vector ();
         webModules = new Vector ();
         
  @@ -50,7 +59,47 @@
      {
        return new Module ();
      }
  -   
  +
  +     /** returns all files (URLs) that are needed to run this deployment properly */
  +     public Vector getAllFiles()
  +     {
  +             // the common libs
  +             Vector result = new Vector();
  +             Iterator it = commonUrls.iterator();
  +             while (it.hasNext())
  +             {
  +                     String s = ((URL)it.next()).getFile();
  +                     result.add(s.substring(s.lastIndexOf("/")+1));
  +             }
  +             
  +             // the ejb packages
  +         it = ejbModules.iterator();
  +             while (it.hasNext())
  +             {                       
  +                     String s = 
((URL)((Module)it.next()).localUrls.firstElement()).getFile();
  +                     result.add(s.substring(s.lastIndexOf("/")+1));
  +             }
  +                     
  +             // the web packages
  +         it = webModules.iterator();
  +             while (it.hasNext())
  +             {
  +                     String s = 
((URL)((Module)it.next()).localUrls.firstElement()).getFile();
  +                     result.add(s.substring(s.lastIndexOf("/")+1));
  +             }
  +
  +             // and the config file
  +             result.add(J2eeDeployer.CONFIG);
  +
  +             /*
  +             it = result.iterator();
  +             while (it.hasNext())
  +                     System.out.println ("contained file: "+it.next());
  +             */
  +
  +             return result;
  +     }
  +
   
      /** Represents a J2ee module. */
      class Module
  
  
  
  1.6       +17 -7     jboss/src/main/org/jboss/deployment/URLWizzard.java
  
  Index: URLWizzard.java
  ===================================================================
  RCS file: /products/cvs/ejboss/jboss/src/main/org/jboss/deployment/URLWizzard.java,v
  retrieving revision 1.5
  retrieving revision 1.6
  diff -u -r1.5 -r1.6
  --- URLWizzard.java   2000/11/06 21:10:26     1.5
  +++ URLWizzard.java   2000/11/24 23:28:19     1.6
  @@ -33,11 +33,14 @@
   * Very scratchy! Any improvements are welcome!
   *      
   *    @author Daniel Schulze <[EMAIL PROTECTED]>
  -*    @version $Revision: 1.5 $
  +*    @version $Revision: 1.6 $
   */
   public class URLWizzard
   {
      
  +     private static byte[] buffer = new byte[1024*512];
  +
  +
      // Static --------------------------------------------------------
      public static void main (String[] _args) throws Exception
      {
  @@ -217,7 +220,8 @@
            if (!f.exists ())
            {
               f.mkdirs ();
  -            return f.toURL ();
  +                     return new URL("file:"+f.getCanonicalPath());
  +            //return f.toURL ();
            }
         }
         while (true); // the endless loop should never cause trouble
  @@ -245,7 +249,7 @@
         }
         while (!file.createNewFile ());
            
  -      return file.toURL ();
  +      return new URL("file:"+file.getCanonicalPath());
      }
      
      
  @@ -280,11 +284,17 @@
      
      
      /** writes the content of the InputStream into the OutputStream */
  -   private static void write (InputStream _in, OutputStream _out) throws IOException
  +   private static synchronized void write (InputStream _in, OutputStream _out) 
throws IOException
      {
  -      int b;
  -      while ((b = _in.read ()) != -1)
  -         _out.write ((byte)b);
  +      int read;
  +       while (true)
  +       {
  +               read = _in.read(buffer);
  +               if (read == -1)
  +                       break;
  +
  +               _out.write(buffer, 0, read);
  +       }
         
         _out.flush ();
      }
  
  
  
  1.12      +146 -464  jboss/src/main/org/jboss/deployment/J2eeDeployer.java
  
  Index: J2eeDeployer.java
  ===================================================================
  RCS file: 
/products/cvs/ejboss/jboss/src/main/org/jboss/deployment/J2eeDeployer.java,v
  retrieving revision 1.11
  retrieving revision 1.12
  diff -u -r1.11 -r1.12
  --- J2eeDeployer.java 2000/11/10 23:33:30     1.11
  +++ J2eeDeployer.java 2000/11/24 23:28:19     1.12
  @@ -13,6 +13,8 @@
   import java.io.ObjectInputStream;
   import java.io.ObjectOutputStream;
   import java.io.FileInputStream;
  +import java.io.InputStream;
  +import java.io.OutputStream;
   import java.io.FileOutputStream;
   import java.io.IOException;
   import java.util.Iterator;
  @@ -20,9 +22,16 @@
   import java.util.Vector;
   import java.util.ArrayList;
   import java.util.StringTokenizer;
  +import java.util.Collection;
   import java.util.jar.JarFile;
   import java.util.jar.Manifest;
   import java.util.jar.Attributes;
  +import java.util.jar.JarFile;
  +import java.util.zip.ZipEntry;
  +import java.util.zip.ZipInputStream;
  +import java.util.zip.ZipEntry;
  +import java.util.Enumeration;
  +
   
   import javax.management.MBeanServer;
   import javax.management.MBeanException;
  @@ -54,7 +63,7 @@
   *  (ContainerFactory for jBoss and EmbededTomcatService for Tomcat).
   *
   *   @author <a href="mailto:[EMAIL PROTECTED]">Daniel Schulze</a>
  -*   @version $Revision: 1.11 $
  +*   @version $Revision: 1.12 $
   */
   public class J2eeDeployer 
   extends ServiceMBeanSupport
  @@ -62,8 +71,11 @@
   {
      // Constants -----------------------------------------------------
      public File DEPLOYMENT_DIR = null;//"/home/deployment"; // default? MUST BE 
ABSOLUTE PATH!!!
  -   public String CONFIG = "deployment.cfg";   
  +   public static String CONFIG = "deployment.cfg";   
      
  +     public static final int EASY = 0;
  +     public static final int RESTRICTIVE = 1;
  +
      // Attributes ----------------------------------------------------
      // my server to lookup for the special deployers
      MBeanServer server;
  @@ -77,6 +89,10 @@
      String jarDeployerName;
      String warDeployerName;
      
  +     int classpathPolicy = EASY;
  +
  +     InstallerFactory installer;
  +     String tmpDir;
      
      // Static --------------------------------------------------------
      /** only for testing...*/
  @@ -96,13 +112,13 @@
      public J2eeDeployer (String _name, String _deployDir, String jarDeployerName, 
String warDeployerName)
      {
          name = _name.equals("") ? "" : " "+_name;
  -      DEPLOYMENT_DIR = new File (_deployDir);
  +      tmpDir = _deployDir;
         
         this.jarDeployerName = jarDeployerName;
         this.warDeployerName = warDeployerName;
   
          this.log = new Log(getName());
  -   
  +
      }
      
      
  @@ -130,38 +146,45 @@
         // now try to deploy
         log.log ("Deploy J2EE application: " + _url);
         
  -      Deployment d = null;
  -      try
  -      {
  -         d = installApplication (url);
  -         startApplication (d);
  -         
  -         log.log ("J2EE application: " + _url + " is deployed.");
  +      Deployment d = installApplication (url);
  +
  +       try
  +       {
  +               startApplication (d);
  +               log.log ("J2EE application: " + _url + " is deployed.");
         } 
         catch (Exception _e)
         {
  -         if (_e instanceof J2eeDeploymentException)
  -         {
  -            if (d != null) // start failed...
  -               stopApplication (d);
  -            
  -            uninstallApplication (getAppName (url));
  -            throw (J2eeDeploymentException)_e;
  -         }
  -         else if (_e instanceof IOException)
  -         {
  -            // some download failed
  -            uninstallApplication (getAppName (url));
  -            throw (IOException)_e;
  -         }
  -         else
  -         {
  -            // Runtime Exception - shouldnt happen
  -            log.exception (_e);
  -            uninstallApplication (getAppName (url));
  -            throw new J2eeDeploymentException ("Fatal error: "+_e.toString ());
  -         }
  -      }
  +               try
  +               {
  +                       stopApplication (d);          
  +               }
  +               catch (Exception _e2)
  +               {
  +                       log.error("unable to stop application "+d.name+": "+_e2);
  +               }
  +               finally
  +               {
  +                       try
  +                       {
  +                               uninstallApplication (_url);
  +                       }
  +                       catch (Exception _e3)
  +                       {
  +                               log.error("unable to uninstall application 
"+d.name+": "+_e3);
  +                       }
  +               }
  +
  +               if (_e instanceof J2eeDeploymentException)
  +               {
  +                       throw (J2eeDeploymentException)_e;
  +               }
  +               else
  +               {
  +                       log.exception(_e);
  +                       throw new J2eeDeploymentException ("fatal error: "+_e);
  +               }
  +       }
      }
      
      /** Undeploys the given URL (if it is deployed).
  @@ -174,42 +197,23 @@
      */
      public void undeploy (String _app) throws IOException, J2eeDeploymentException
      {
  -      String name;
  -      try
  -      {
  -         name = getAppName (new URL (_app));
  -      }
  -      catch (MalformedURLException _e)
  -      {
  -         // must be only the name
  -         name = _app;
  -      }
  -      
  -      Deployment d = null;
  -      File f = new File (DEPLOYMENT_DIR + File.separator + name);
  -      if (f.exists())
  -      {
  -         try
  -         {
  -            d = loadConfig (name);
  -            stopApplication (d);
  -         }
  -         catch (IOException _ioe)
  -         {  // thrown by the load config
  -            throw _ioe;
  -         }
  -         catch (J2eeDeploymentException _e)
  -         {
  -            throw _e;
  -         }
  -         finally
  -         {
  -            uninstallApplication (name);
  -         }
  -      
  -      }
  -      else
  -         throw new J2eeDeploymentException ("The application \""+name+"\" has not 
been deployed.");
  +        Deployment d = installer.findDeployment (_app);
  +        
  +        if (d == null)
  +                throw new J2eeDeploymentException ("The application \""+name+"\" 
has not been deployed.");
  +
  +        try
  +        {
  +                stopApplication (d);
  +        }
  +        catch (J2eeDeploymentException _e)
  +        {
  +                throw _e;
  +        }
  +        finally
  +        {
  +                uninstallApplication (d);
  +        }     
      }
      
      /** Checks if the given URL is currently deployed or not.
  @@ -223,36 +227,16 @@
      */
      public boolean isDeployed (String _url) throws MalformedURLException, 
J2eeDeploymentException
      {
  -      // get Application name
  -      String name;
  -      try
  -      {
  -         name = getAppName (new URL (_url));
  -      }
  -      catch (MalformedURLException _e)
  -      {
  -         // must be only the name
  -         name = _url;
  -      }
  -      
  -      Deployment d = null;
  -      File f = new File (DEPLOYMENT_DIR + File.separator + name);
  -      if (f.exists())
  -      {
  -         try
  -         {
  -            return checkApplication (loadConfig (name));          
  -         } 
  -         catch (IOException e)
  -         {
  -            // no config found
  -            throw new J2eeDeploymentException ("The application \""+name+"\" seems 
to be installed, "+
  -               "but cant read "+CONFIG+" file!? Cant handle...");
  -         }
  -      }
  -      else
  -         return false;
  -   
  +        boolean result = false;
  +
  +        Deployment d = installer.findDeployment (_url);
  +
  +        if (d != null)
  +        {
  +                result = checkApplication (d);          
  +        }
  +        
  +        return result;
      }
      
      // ServiceMBeanSupport overrides ---------------------------------
  @@ -274,10 +258,13 @@
      {
         
         //check if the deployment dir was set meaningful
  -      if (!DEPLOYMENT_DIR.exists () &&
  -          !DEPLOYMENT_DIR.mkdirs ())
  -         throw new IOException ("Temporary directory 
\""+DEPLOYMENT_DIR.getCanonicalPath ()+"\" does not exist!");
  +        File dir = new File(tmpDir);
  +      if (!dir.exists () &&
  +          !dir.mkdirs ())
  +         throw new IOException ("Temporary directory \""+dir.getCanonicalPath 
()+"\" does not exist!");
         
  +       installer = new InstallerFactory(dir, log);
  +
         // Save JMX name of the deployers
         jarDeployer = new ObjectName(jarDeployerName);
         warDeployer= new ObjectName(warDeployerName);
  @@ -292,17 +279,8 @@
            
         // clean up the deployment directory since on some Windowz the file removement
         // during runtime doesnt work...
  -      log.log("Cleaning up deployment directory "+DEPLOYMENT_DIR.toURL());
  -      File[] files =  DEPLOYMENT_DIR.listFiles();
  -      for (int i = 0, l = files.length; i<l; ++i)
  -         try
  -         {
  -            URLWizzard.deleteTree(files[i].toURL());
  -         }
  -         catch (IOException _ioe)
  -         {
  -            log.log("Could not remove file tree: "+files[i].toURL().toString());
  -         }
  +      log.log("Cleaning up deployment directory "+tmpDir);
  +       installer.unclutter();
      }
      
      
  @@ -311,38 +289,29 @@
      {
         log.log ("Undeploying all applications.");
         
  -      File[] files =  DEPLOYMENT_DIR.listFiles();
  +       Deployment[] deps = installer.getDeployments();
         int count = 0;
  -      for (int i = 0, l = files.length; i<l; ++i)
  +      for (int i = 0, l = deps.length; i<l; ++i)
         {
  -         if (files[i].isDirectory ())
  -         {
  -            try
  -            {
  -               Deployment d = loadConfig (files[i].getName ());
  -               stopApplication (d);
  -            }   
  -            catch (IOException _ioe)
  -            {  // thrown by the load config
  -               //throw _ioe; 
  -               log.exception(_ioe);
  -            }
  -            catch (J2eeDeploymentException _e)
  -            {
  -               //throw _e;               
  -               log.exception(_e);
  -            }
  -            finally 
  -            {
  -               try {
  -                  uninstallApplication (files[i].getName ());
  -               } catch (IOException _ioe)
  -               {log.exception(_ioe);}
  -            }
  -            ++count;
  -         }
  -      }
  -      log.log ("Undeployed "+count+" applications.");
  +               try
  +               {
  +                       stopApplication (deps[i]);
  +               }   
  +               catch (J2eeDeploymentException _e)
  +               {
  +                       //throw _e;               
  +                       log.exception(_e);
  +               }
  +               finally 
  +               {
  +                             try {
  +                                     uninstallApplication (deps[i]);
  +                             } catch (IOException _ioe)
  +                             {log.exception(_ioe);}
  +          }
  +               ++count;
  +       }
  +       log.log ("Undeployed "+count+" applications.");
      }
      
      // Private -------------------------------------------------------
  @@ -356,264 +325,31 @@
      *   @throws J2eeDeploymentException if the given package is somehow inconsistent
      */
      Deployment installApplication (URL _downloadUrl) throws IOException, 
J2eeDeploymentException
  -   {
  -      // because of the URLClassLoader problem (doesnt notice when jar content 
changed)
  -      // we first make a local copy of the file
  -      boolean directory = false;
  -      URL localCopy = null;
  -      
  -      // determine if directory or not 
  -      // directories are only local supported
  -      if (_downloadUrl.getProtocol().equals ("file") && 
  -         new File (_downloadUrl.getFile ()).isDirectory ())
  -      {
  -         directory = true;
  -         localCopy = URLWizzard.downloadAndPackTemporary (_downloadUrl, 
DEPLOYMENT_DIR.toURL (), "copy", ".zip");
  -      }
  -      else
  -         localCopy = URLWizzard.downloadTemporary (_downloadUrl, 
DEPLOYMENT_DIR.toURL (), "copy", ".zip");
  -      
  -      // determine the file type by trying to access one of its possible descriptors
  -      Element root = null;
  -      URLClassLoader cl = new URLClassLoader (new URL[] {localCopy});
  -      String[] files = {"META-INF/ejb-jar.xml", "META-INF/application.xml", 
"WEB-INF/web.xml"};
  -      
  -      for (int i = 0; i < files.length && root == null; ++i)
  -      {
  -         try {
  -            root = XmlFileLoader.getDocument (cl.getResourceAsStream 
(files[i])).getDocumentElement ();
  -         } catch (Exception _e) {}
  -      }
  -      
  -      // dont need it anymore...
  -      cl = null;
  -      try
  -      {
  -         URLWizzard.deleteTree(localCopy);
  -      } 
  -      catch (IOException _ioe)
  -      {
  -         // dont abort just give a note...
  -         log.log ("Could not delete temporary file: "+localCopy.getFile ());
  -      }
  -      
  -      if (root == null)
  -      {
  -         // no descriptor was found...
  -         throw new J2eeDeploymentException ("No valid deployment descriptor was 
found within this URL: "+
  -            _downloadUrl.toString ()+
  -            "\nMake sure it points to a valid j2ee package 
(ejb.jar/web.war/app.ear)!");
  -      }
  -      
  -      // valid descriptor found
  -      // create a Deployment
  -      Deployment d = new Deployment ();
  -      
  -      d.name = getAppName (_downloadUrl);
  -      d.localUrl = new File (DEPLOYMENT_DIR, d.name).toURL ();
  -      log.log ("Create application " + d.name);
  -      
  -      // do the app type dependent stuff...
  -      if ("ejb-jar".equals (root.getTagName ()))
  -      {
  -         // its a EJB.jar... just take the package
  -         installEJB (d, _downloadUrl, null);
  -      } 
  -      else if ("web-app".equals (root.getTagName ()))
  -      {
  -         // its a WAR.jar... just take the package
  -         if (directory)
  -            throw new J2eeDeploymentException ("Currently are only packed web.war 
archives supported.");
  -         
  -         if (!warDeployerAvailable ())
  -            throw new J2eeDeploymentException ("No web container available!");
  -         
  -         String context = getWebContext (_downloadUrl);
  -         installWAR (d, _downloadUrl, context, null);
  -      } 
  -      else if ("application".equals (root.getTagName ()))
  -      {
  -         // its a EAR.jar... hmmm, its a little more
  -         if (directory)
  -            throw new J2eeDeploymentException ("Application .ear files are only in 
packed archive format supported.");
  -         
  -         // create a MetaData object...
  -         J2eeApplicationMetaData app = null; 
  -         try
  -         {
  -            app = new J2eeApplicationMetaData (root);
  -         }
  -         catch (DeploymentException _de)
  -         {
  -            throw new J2eeDeploymentException ("Error in parsing application.xml: 
"+_de.getMessage ());
  -         }
  -         
  -         // currently we only take care for the modules
  -         // no security stuff, no alternative DDs 
  -         // no dependency and integrity checking... !!!
  -         J2eeModuleMetaData mod;
  -         Iterator it = app.getModules ();
  -         for (int i = 0; it.hasNext (); ++i)
  -         {
  -            // iterate the ear modules
  -            mod = (J2eeModuleMetaData) it.next ();
  -            
  -            if (mod.isEjb ())
  -            {
  -               URL src = new URL ("jar:"+_downloadUrl.toString ()+ "!"+
  -                  (mod.getFileName ().startsWith ("/") ? "" : "/")+
  -                  mod.getFileName ());
  -               installEJB (d, src, null);
  -            }
  -            else if (mod.isWeb ())
  -            {
  -               if (!warDeployerAvailable ())
  -                  throw new J2eeDeploymentException ("Application contains .war 
file, but no web container available!");
  -               
  -               String context = mod.getWebContext ();
  -               if (context == null)
  -                  context = mod.getFileName ().substring (Math.max (0, 
mod.getFileName ().lastIndexOf ("/")));
  -               
  -               URL src = new URL ("jar:"+_downloadUrl.toString ()+ "!"+
  -                  (mod.getFileName ().startsWith ("/") ? "" : "/")+
  -                  mod.getFileName ());
  -               installWAR (d, src, context, null);
  -            }
  -            // other packages we dont care about (currently)
  -         } 
  -      }
  -      saveConfig (d);
  -      
  -      return d;
  -   }
  -   
  -   void installEJB (Deployment _d, URL _source, URL[] _altDD) throws IOException
      {
  -      Deployment.Module m = _d.newModule ();
  -      m.name = getAppName (_source);
  -      log.log ("Installing EJB package: " + m.name);
  -      
  -      // download the package...
  -      URL localUrl = URLWizzard.downloadTemporary(_source, _d.localUrl, "ejb", 
".jar");
  -      
  -      // download alternative Descriptors (ejb-jar.xml, jboss.xml, ...)
  -      // DOESNT WORK YET!!!
  -      if (_altDD != null && _altDD.length > 0)
  -      {
  -         ;
  -      }
  -      
  -      m.localUrls.add (localUrl);
  -      
  -      // download libraries we depend on
  -      Manifest mf = new JarFile (localUrl.getFile ()).getManifest ();
  -      if (mf != null)
  -               addCommonLibs (_d, mf, _source);
  -       else
  -               log.debug(m.name+" doesnt contain MANIFEST.MF");
  -
  -      // add module to the deployment
  -      _d.ejbModules.add (m);
  -   }
  -   
  -   
  -   void installWAR (Deployment _d, URL _source, String _context, URL[] _altDD) 
throws IOException
  -   {
  -      Deployment.Module m = _d.newModule ();
  -      m.name = getAppName (_source);
  -      log.log ("Installing web package: " + m.name);
  -      
  -      // download the package...
  -      URL localUrl = URLWizzard.downloadAndInflateTemporary (_source, _d.localUrl, 
"war");
  -      
  -      // save the contextName
  -      m.webContext = _context;
  -      
  -      // download alternative Descriptors (web.xml, ...)
  -      // DOESNT WORK YET!!!
  -      if (_altDD != null && _altDD.length > 0)
  -      {
  -         ;
  -      }
  -      
  -      m.localUrls.add (localUrl);
  -      
  -      // download libraries we depend on
  -       try
  -       {
  -               FileInputStream in = new FileInputStream (localUrl.getFile 
()+File.separator+"META-INF"+File.separator+"MANIFEST.MF");
  -               Manifest mf = new Manifest (in);
  -               in.close ();
  -               addCommonLibs (_d, mf, _source);
  -       }
  -       catch (IOException _ioe)
  -       {
  -               log.debug(m.name+" doesnt contain MANIFEST.MF");
  -       }
  -
  -      // add module to the deployment
  -      _d.webModules.add (m);
  +        return installer.install(_downloadUrl);
      }
      
  -   /** downloads all Class-Path: files of this manifest and adds the local urls 
  -   *   to the deployments commonUrls.
  -   *   @param _d the deployment
  -   *   @param _mf the manifest
  -   *   @param _base the base url to which the manifest entries are relative
  -   *   @throws IOExcepiton in case of error while downloading
  -   */
  -   private void addCommonLibs (Deployment _d, Manifest _mf, URL _base)
  -   {
  -      String cp = _mf.getMainAttributes ().getValue(Attributes.Name.CLASS_PATH);
  -      
  -      if (cp != null)
  -      {
  -         StringTokenizer cpTokens = new StringTokenizer (cp," ");
  -         while (cpTokens.hasMoreTokens ())
  -         {                     
  -            String classPath = cpTokens.nextToken();
  -            try
  -            {
  -               URL src = new URL(_base, classPath);
  -               _d.commonUrls.add (URLWizzard.downloadTemporary (src, _d.localUrl, 
"lib", ".jar"));
  -               log.error("Added " + classPath + " to common classpath");
  -            } 
  -            catch (Exception e)
  -            {
  -               log.error("Could not add " + classPath + " to common classpath");
  -            }
  -         }
  -      }
  -   }
      
      /** Deletes the file tree of  the specified application. <br>
      *   @param _name the directory (DEPLOYMENT_DIR/<_name> to remove recursivly
      *   @throws IOException if something goes wrong
      */
  -   void uninstallApplication (String _name) throws IOException
  +   void uninstallApplication (String _pattern) throws IOException
      {
  -      log.log ("Destroying application " + _name);
  -      URL url = null;
  -      try 
  -      {
  -         url = new URL (DEPLOYMENT_DIR.toURL (), _name);
  -         
  -         // because of the deletion problem in some WIndowz 
  -         // we remove the CONFIG separatly (this should always work)
  -         // so that on stopService () now exceptions were thrown when he thinks
  -         // some apps are still deployed...
  -         URLWizzard.deleteTree (new URL (url, CONFIG));      
  -         log.log (CONFIG+" file deleted.");
  -         
  -         URLWizzard.deleteTree (url);      
  -         log.log ("File tree "+url.toString ()+" deleted.");
  -      } catch (MalformedURLException _mfe) { // should never happen
  -      } catch (IOException _ioe) {
  -         log.log ("Could not remove file: "+url.toString ());
  -         // throw _ioe;
  -      }
  +        Deployment d = installer.findDeployment (_pattern);
  +
  +        if (d != null)
  +                uninstallApplication (d);
      }
      
  +     void uninstallApplication (Deployment _d) throws IOException
  +     {
  +             log.log ("Destroying application " + _d.name);
  +             installer.uninstall(_d);
  +     }
  +
  +
  +
      /** Starts the successful downloaded deployment. <br>
      *   Means the modules are deployed by the responsible container deployer
      *   @param _d the deployment to start
  @@ -633,33 +369,39 @@
         String message;
         try
         {
  -         // jBoss
  -         Iterator it = _d.ejbModules.iterator ();
  +         // Tomcat
  +         Iterator it = _d.webModules.iterator ();
  +              if (it.hasNext() && !warDeployerAvailable())
  +                      throw new J2eeDeploymentException ("application contains war 
files but no web container available");
  +                      
  +              
            while (it.hasNext ())
            {
               m = (Deployment.Module)it.next ();
               
               log.log ("Starting module " + m.name);
               
  -            // Call the ContainerFactory that is loaded in the JMX server
  -            server.invoke(jarDeployer, "deploy",
  -               new Object[] { m.localUrls.firstElement().toString () }, new 
String[] { "java.lang.String" });
  +            // Call the TomcatDeployer that is loaded in the JMX server
  +            server.invoke(warDeployer, "deploy",
  +               new Object[] { m.webContext, m.localUrls.firstElement().toString 
()}, new String[] { "java.lang.String", "java.lang.String" });
            }
  -         
  -         
  -         // Tomcat
  -         it = _d.webModules.iterator ();
  +
  +              // since tomcat changes the context classloader...
  +         Thread.currentThread().setContextClassLoader (oldCl);
  +
  +         // jBoss
  +         it = _d.ejbModules.iterator ();
            while (it.hasNext ())
            {
               m = (Deployment.Module)it.next ();
               
               log.log ("Starting module " + m.name);
               
  -            // Call the TomcatDeployer that is loaded in the JMX server
  -            server.invoke(warDeployer, "deploy",
  -               new Object[] { m.webContext, m.localUrls.firstElement().toString 
()}, new String[] { "java.lang.String", "java.lang.String" });
  -         }
  -      }
  +            // Call the ContainerFactory that is loaded in the JMX server
  +            server.invoke(jarDeployer, "deploy",
  +               new Object[] { m.localUrls.firstElement().toString () }, new 
String[] { "java.lang.String" });
  +         }       
  +       }
         catch (MBeanException _mbe) {
            log.error ("Starting "+m.name+" failed!");
            throw new J2eeDeploymentException ("Error while starting "+m.name+": " + 
_mbe.getTargetException ().getMessage ());
  @@ -800,39 +542,6 @@
      }
      
      
  -   /** Loads the serialized CONFIG file for the specified app. <br>
  -   *   loads DEPLOYMENT_DIR / _app / CONFIG
  -   *   @param _app the name of the app
  -   *   @throws IOException if an error occures
  -   */
  -   private Deployment loadConfig (String _app) throws IOException
  -   {          
  -      Deployment d = null;
  -      try
  -      {
  -         ObjectInputStream in = new ObjectInputStream (
  -            new FileInputStream (DEPLOYMENT_DIR + File.separator + _app + 
File.separator + CONFIG));
  -         d = (Deployment)in.readObject ();
  -         in.close ();
  -      }
  -      catch (ClassNotFoundException _snfe){} // should never happen...
  -      
  -      return d;
  -   }
  -   
  -   /** Serializes Deployment as CONFIG file. <br>
  -   *   saves DEPLOYMENT_DIR / _d.name / CONFIG
  -   *   @param _app the name of the app
  -   *   @throws IOException if an error occures
  -   */
  -   private void saveConfig (Deployment _d) throws IOException
  -   {          
  -      ObjectOutputStream out = new ObjectOutputStream (
  -         new FileOutputStream (DEPLOYMENT_DIR + File.separator + _d.name + 
File.separator + CONFIG));
  -      out.writeObject (_d);
  -      out.flush ();
  -      out.close ();
  -   }
      
      /** tests if the web container deployer is available */
      private boolean warDeployerAvailable ()
  @@ -840,33 +549,7 @@
         return server.isRegistered (warDeployer);
      }
      
  -   /** returns the filename this url points to */
  -   public String getAppName (URL _url)
  -   {
  -      String s = _url.toString ();
  -      
  -      if (s.endsWith ("/"))
  -         s = s.substring (0, s.length() - 1);
  -      
  -      s = s.substring (s.lastIndexOf ("/") + 1);
  -      return s;
  -   }
  -   
  -   /** composes a webContext name of the file this url points to */
  -   public String getWebContext (URL _downloadUrl)
  -   {
  -      String s = getAppName (_downloadUrl);
  -      
  -      // truncate the file extension
  -      int p = s.lastIndexOf (".");
  -      if (p != -1)
  -         s = s.substring (0, p);
  -      
  -      return "/" + s.replace ('.', '/');
  -   }   
      
  -   
  -   
      /**
      * creates an application class loader for this deployment
      * this class loader will be shared between jboss and tomcat via the 
contextclassloader
  @@ -885,6 +568,5 @@
         // set it as the context class loader for the deployment thread
         Thread.currentThread().setContextClassLoader(appCl);
      }
  -
   
   }
  
  
  
  1.1                  jboss/src/main/org/jboss/deployment/Installer.java
  
  Index: Installer.java
  ===================================================================
  /*
   * jBoss, the OpenSource EJB server
   *
   * Distributable under GPL license.
   * See terms of license at gnu.org.
   */
  package org.jboss.deployment;
  
  import java.net.URL;
  import java.net.MalformedURLException;
  import java.net.URLClassLoader;
  import java.io.File;
  import java.io.ObjectInputStream;
  import java.io.ObjectOutputStream;
  import java.io.FileInputStream;
  import java.io.InputStream;
  import java.io.OutputStream;
  import java.io.FileOutputStream;
  import java.io.IOException;
  import java.io.FileNotFoundException;
  import java.util.Iterator;
  import java.util.Hashtable;
  import java.util.Vector;
  import java.util.ArrayList;
  import java.util.StringTokenizer;
  import java.util.Collection;
  import java.util.jar.JarFile;
  import java.util.jar.Manifest;
  import java.util.jar.Attributes;
  import java.util.jar.JarFile;
  import java.util.zip.ZipEntry;
  import java.util.zip.ZipInputStream;
  import java.util.zip.ZipEntry;
  import java.util.Enumeration;
  
  
  import javax.management.MBeanServer;
  import javax.management.MBeanException;
  import javax.management.JMException;
  import javax.management.ObjectName;
  
  import org.jboss.logging.Log;
  import org.jboss.util.MBeanProxy;
  import org.jboss.util.ServiceMBeanSupport;
  
  import org.jboss.metadata.XmlFileLoader;
  
  import org.jboss.ejb.DeploymentException;
  import org.jboss.ejb.ContainerFactoryMBean;
  
  import org.w3c.dom.Document;
  import org.w3c.dom.Element;
  
  
  
  /** A class intended to encapsulate the complex task of making an URL pointed
   *  to an J2ee module an installed Deployment.
   *      
   *    @see <related>
   *    @author <a href="mailto:[EMAIL PROTECTED]">Daniel Schulze</a>
   *    @version $Revision: 1.1 $
   */
  public class Installer
  {
     // Constants -----------------------------------------------------
  
  
        // the order is the order of the type constants defined in this class 
        private static final String[] files = {"META-INF/ejb-jar.xml", 
"WEB-INF/web.xml", "META-INF/application.xml"};
      
        // Attributes ----------------------------------------------------
      
        // the basedir of this Deployment within the InstallerFactories baseDir
        File baseDir;
        // the URL to install
        URL src;
        // the resulting Deployment
        Deployment d;
  
        // the Log for output
        Log log;
  
        // to get the Log and the temprary deployment dir
        InstallerFactory factory;
  
        // flag to not run execute twice
        boolean done;
  
  
     // Static --------------------------------------------------------
  
        static int counter = 1000;
  
        /** Number generator for temporary files.
         *  @return a new number on each call
         */
        private static int nextNumber()
        {
                return ++counter;
        }
  
     
        // Constructors --------------------------------------------------
        public Installer (InstallerFactory _factory, URL _src) throws IOException
        {
                factory = _factory;
                log = _factory.log;
                src = _src;
        }
  
        // Public --------------------------------------------------------
  
        /** performes the complex task of installation
         *  @return the installed Deployment on success
         *  @throws J2eeDeploymentException 
         *  @throws IOException
         */
        public Deployment execute() throws J2eeDeploymentException, IOException
        {
                if (done)
                        throw new IllegalStateException ("this object ("+src+")is 
already executed.");
  
  
                File localCopy = null; 
                d = new Deployment();
                Deployment.Module m = null;
                d.name = getName (src.toString());
  
            baseDir = new File (factory.baseDir, d.name);
  
                d.localUrl = baseDir.toURL ();
  
                try
                {
                        localCopy = makeLocalCopy();
  
                        // determine the type...
                        int type = determineType (new JarFile(localCopy));
  
                        log.log ("Create application " + d.name);
                        switch (type)
                        {
                        case 0: // ejb package...
                  
                                // just install the package
                                m = d.newModule();
                                m.name = d.name; // module name = app name
  
                                log.log("install module "+m.name);
                                File f = install(new FileInputStream(localCopy), 
"ejb");
  
                                // check for referenced libraries
                                Manifest mf = new JarFile(f).getManifest ();
                                if (mf != null)
                                        addLibraries (mf, src);
                                
                                m.localUrls.add (f.toURL());
  
                                d.ejbModules.add(m);              
                                break;
  
                        case 1: // web package
  
                                // just inflate the package and determine the context 
name
                                m = d.newModule();
                                m.name = d.name; // module name = app name
                                m.webContext = getWebContext (src.toString());
  
                                log.log("inflate and install module "+m.name);
                                f = installInflate(new FileInputStream(localCopy), 
"web");
  
                                try
                                {
                                        InputStream mfIn = new FileInputStream (new 
File (f, "META-INF/MANIFEST.MF"));
                                        addLibraries (new Manifest(mfIn), src);
                                }
                                catch (FileNotFoundException _fnfe) {}
  
                                m.localUrls.add (f.toURL());
  
                                d.webModules.add(m);              
                                break;
  
                        case 2: // application package 
  
                                // reading the deployment descriptor...
                                JarFile jarFile = new JarFile (localCopy);
                                J2eeApplicationMetaData app = null; 
                                try
                                {
                                        InputStream in = 
jarFile.getInputStream(jarFile.getEntry(files[type]));
                                        Element root = XmlFileLoader.getDocument 
(in).getDocumentElement ();
                                        app = new J2eeApplicationMetaData (root);
                                        in.close();               
                                }
                                catch (IOException _ioe)
                                {
                                        throw new J2eeDeploymentException ("Error in 
accessing application metadata: "+_ioe.getMessage ());               
                                }
                                catch (DeploymentException _de)
                                {
                                        throw new J2eeDeploymentException ("Error in 
parsing application.xml: "+_de.getMessage ());
                                }
                                catch (NullPointerException _npe)
                                {
                                        throw new J2eeDeploymentException ("unexpected 
error: application.xml was found once but not a second time?!");
                                }
  
                                // iterating the ejb and web modules and install them
                                J2eeModuleMetaData mod;
                                Iterator it = app.getModules ();
                                while (it.hasNext ())
                                {
                                        // iterate the ear modules
                                        mod = (J2eeModuleMetaData) it.next ();
              
                                        if (mod.isEjb ())
                                        {
                                                m = d.newModule();
                                                m.name = mod.getFileName();
  
                                                log.log("install module "+m.name);
                                                try
                                                {
                                                        InputStream in = 
jarFile.getInputStream(jarFile.getEntry(mod.getFileName()));
                                                        f = install(in, "ejb");
  
                                                        // check for referenced 
libraries
                                                        mf = new 
JarFile(f).getManifest ();
                                                        if (mf != null)
                                                                addLibraries (mf, new 
URL("jar:file:"+localCopy.getAbsolutePath()+"!/"));
                                                        
                                                        m.localUrls.add(f.toURL());
                                                }
                                                catch (IOException _ioe)
                                                {
                                                        throw _ioe;
                                                }
                                                catch (NullPointerException _npe)
                                                {
                                                        log.log("module "+m.name+" not 
found in "+d.name);
                                                        throw new 
J2eeDeploymentException ("module "+m.name+" not found in "+d.name);
                                                }
  
                                                d.ejbModules.add(m);              
  
                                        }
                                        else if (mod.isWeb ())
                                        {
                                                m = d.newModule();
                                                m.name = mod.getFileName();
  
                                                m.webContext = mod.getWebContext();
                                                if (m.webContext == null)
                                                        // this line here is not smart 
yet!!!
                                                        m.webContext = mod.getFileName 
().substring (Math.max (0, mod.getFileName ().lastIndexOf ("/")));
  
                                                // make sure the context starts with a 
slash
                                                if (!m.webContext.startsWith ("/"))
                                                        m.webContext = 
"/"+m.webContext;
  
                                                log.log("inflate and install module 
"+m.name);
                                                try
                                                {
                                                        InputStream in = 
jarFile.getInputStream(jarFile.getEntry(mod.getFileName()));
                                                        f = installInflate(in, "web");
  
                                                        // check for referenced 
libraries
                                                        try
                                                        {
                                                                InputStream mfIn = new 
FileInputStream (new File (f, "META-INF/MANIFEST.MF"));
                                                                addLibraries (new 
Manifest(mfIn), new URL("jar:file:"+localCopy.getAbsolutePath()+"!/"));
                                                        }
                                                        catch (FileNotFoundException 
_fnfe) {}
                                                        m.localUrls.add(f.toURL());
                                                }
                                                catch (IOException _ioe)
                                                {
                                                        throw _ioe;
                                                }
                                                catch (NullPointerException _npe)
                                                {
                                                        log.log("module "+m.name+" not 
found in "+d.name);
                                                        throw new 
J2eeDeploymentException ("module "+m.name+" not found in "+d.name);
                                                }
  
                                                d.webModules.add(m);              
                                        }
                                        // other packages we dont care about 
(currently)
                                } 
  
  /*
                                // walk throgh the .ear file and download all jar 
files that are included 
                                // (and not yet downloaded) and put them into the 
common classpath
                                Enumeration enum = jarFile.entries();
                                while (enum.hasMoreElements())
                                {
                                        ZipEntry entry = (ZipEntry)enum.nextElement();
                                        if (entry.getName().endsWith(".jar") && 
!installedJars.contains(entry.getName()))
                                        {
                                                log.log("add "+entry.getName()+" to 
common classpath");
                                                d.commonUrls.add 
(install(jarFile.getInputStream(entry), "lib").toURL());
                                        }
                                }
  */
  
                                // put all ejb jars to the common classpath too
                                it = d.ejbModules.iterator();
                                if (it.hasNext())
                                        log.log("add all ejb jar files to the common 
classpath");
                                while (it.hasNext())
                                        d.commonUrls.add 
(((Deployment.Module)it.next()).localUrls.firstElement());
  
                                break;
                        }
                        saveConfig ();
  
                }
                catch (Exception _ex)
                {
                        // ooops something went wrong - clean up unfinished 
installation...
                        try
                        {
                                deleteRecursive (baseDir);
                        }
                        catch (Exception _e)
                        {
                                log.debug("couldnt remove unused files in 
"+baseDir.getAbsolutePath()+": "+_e.getMessage());
                        }
  
                        if (_ex instanceof J2eeDeploymentException)
                                throw (J2eeDeploymentException) _ex;
  
                        if (_ex instanceof IOException)
                                throw (IOException) _ex;
  
                        log.exception (_ex);
                        throw new J2eeDeploymentException ("unexpected exception 
occured (see server trace)");
                }
                finally
                {
                        // mark as done
                        done = true;
  
                        // finally try to remove the localCopy
                        // must be changed to make really sure it is finally done!!!
                        try
                        {
                                if (localCopy != null)
                                        localCopy.delete();
                        }
                        catch (Exception _e)
                        {
                                log.debug("couldnt remove temporary copy 
"+localCopy+": "+_e.getMessage());
                        }
                }
      
                return d;
        }
  
      
     // Private -------------------------------------------------------
  
        /** Determines the type (ejb/war/ear) of the given JarFile by trying to access
         *  the deployment descriptor.
         *  @param _file the JarFile to test
         *  @return the number (0-2) of the matched deployment descriptor taken from 
the
         *          <strong>file</strong> class member.
         *  @throws J2eeDeploymentException in case not descriptor was found.
         */
        private int determineType (JarFile _file) throws J2eeDeploymentException
        {
                int result = -1;
  
                // trying to access the possible descriptor files
                ZipEntry dd = null;
                for (int i = 0; i < files.length && dd == null; ++i)
            {
                        dd = _file.getEntry(files[i]);
                        result = i;
                }
  
                // nothing found...
                if (dd == null)
                {
                        // no descriptor found ...
                        // lets seek if the app assembler is a little ???
                        Enumeration e = _file.entries();
                        while (e.hasMoreElements())
                        {
                                dd = (ZipEntry)e.nextElement();
                                String name = dd.getName();
                                for (int i = 0; i < files.length; ++i)
                                        if (name.equalsIgnoreCase(files[i]))
                                                throw new J2eeDeploymentException("no 
deployment descriptor found but file that could be ment as: "+name+" <-> "+files[i]);
                        }
  
                        // really nothing found
                        throw new J2eeDeploymentException ("no deployment descriptor 
("+files[0]+", "+files[1]+", "+files[2]+") found");
                }
  
                return result;
        }
  
  
        /** Downloads the jar file or directory the src URL points to.
         *  In case of directory it becomes packed to a jar file.
         *  @return a File object representing the downloaded module
         *  @throws IOException 
         */
        private File makeLocalCopy () throws IOException
        {
                URL dest = null;
                if (src.getProtocol().equals ("file") && 
                                new File (src.getFile ()).isDirectory ())
                {
                        dest = URLWizzard.downloadAndPackTemporary (src, 
factory.baseDir.toURL (), "copy", ".zip");
                }
                else
                {
                        dest = URLWizzard.downloadTemporary (src, 
factory.baseDir.toURL (), "copy", ".zip");
                }
                
                return new File (dest.getFile());
        }
  
        /** Adds all <strong>Class-Path:</strong> entries from the Manifest to the
         *  Deployments commonUrls member.
         *  @param _mf the Manifest to process
         *  @param _anchestor the URL to which the Class-Path entries will be relative
         *  @throws IOException 
         */
        private void addLibraries (Manifest _mf, URL _anchestor) throws IOException
        {
                String attr = _mf.getMainAttributes().getValue 
(Attributes.Name.CLASS_PATH);
                if (attr != null)
                {
                        StringTokenizer st = new StringTokenizer (attr);
                        while (st.hasMoreTokens())
                        {
                                String tk = st.nextToken ();
                                try
                                {
                                        URL lib = new URL (_anchestor, tk);
                                        d.commonUrls.add (URLWizzard.downloadTemporary 
(lib, factory.baseDir.toURL (), "lib", ".jar"));
                                        log.log("added "+lib+" to common classpath");
                                }
                                catch (IOException _ioe)
                                {
                                        log.log("couldnt add "+tk+" to common 
classpath: "+_ioe.getMessage());
                                }
                        }
                }
        }
  
  
        /** Creates a temporary jar file from the InputStream with the given _prefix 
in its name.
         *  @param _in an InputStream of a jar/zip file
         *  @param _prefix name prefix for the temporary file 
(prefix&lt;number&gt;.jar)
         *  @return a File representing the newly created jar file
         *  @throws IOException
         */
        private File install (InputStream _in, String _prefix) throws IOException
        {
                File result = createTmpFile(baseDir, _prefix, ".jar");
                copy (_in, new FileOutputStream(result), true);
  
                return result;
        }
                
        /** Same as <code>install()</code> but inflates the jar file.
         *  @param _in the Inputstream of an jar/zip file
         *  @param _prefix the name prefix for the temporary directory that will 
become created
         *  @return a File representing the newly created directory
         *  throws IOException
         */
        private File installInflate (InputStream _in, String _prefix) throws 
IOException
        {
                File result = createTmpDir(baseDir, _prefix);
                inflate (new ZipInputStream(_in), result);
  
                return result;
        }
                                                                                       
                                           
  
        /** Serializes the Deployment object.
         *  @throws IOException
         */
        private void saveConfig () throws IOException
        {          
                ObjectOutputStream out = new ObjectOutputStream (new FileOutputStream 
(new File (baseDir, J2eeDeployer.CONFIG)));
  
                out.writeObject (d);
                out.flush ();
                out.close ();
        }
  
        /** Truncates the the name (the last cluster of letters after the last slash.
         *  @param _url an URL or something like that
         */
        private String getName (String _url)
        {
                String result = _url;
                
                if (result.endsWith ("/"))
                        result = result.substring (0, result.length() - 1);
        
                result = result.substring (result.lastIndexOf ("/") + 1);
  
                return result;
      }
  
  
        /** Generates a webcontex for the given url
         *  @param _url an URL or something like that
         */
        public String getWebContext (String _url)
        {
                String s = getName (_url);
        
                // truncate the file extension
                int p = s.lastIndexOf (".");
                if (p != -1)
                        s = s.substring (0, p);
        
                return "/" + s.replace ('.', '/');
        }         
  
  
        /** Writes all from one stream into the other.
         *  @param _in the source
         *  @param _out the destination
         *  @param _closeInput indicates if the source stream shall be closed when 
finished
         *         (the dest stream gets closed anyway)
         *  @throws IOException
         */
        private void copy (InputStream _in, OutputStream _out, boolean _closeInput) 
throws IOException
        {
                byte[] buffer = new byte[1024*1024];
                int read;
                while (true)
                {
                        read = _in.read(buffer);
                        if (read == -1)
                                break;
  
                        _out.write(buffer, 0, read);
                }
        
                _out.flush();
                _out.close();
                if (_closeInput)
                        _in.close();
        }
  
        /** Infaltes a jar/zip file represented by the given stream into the given 
directory.
         *  @param _in the jar/zip file to extract
         *  @param _destDir the root dir for the extracted jar/zip
         *  @throws IOException
         */
        private void inflate (ZipInputStream _in, File _destDir) throws IOException
        {
                if (_destDir.exists ())
                        deleteRecursive (_destDir);
        
                _destDir.mkdirs ();
                
                OutputStream out;
                ZipEntry entry;
                while ((entry = _in.getNextEntry ()) != null)
          {
           String name = entry.getName ();
           if (!entry.isDirectory ()) // there are not all directories listed (?!)- so 
this way...
           {
              // create directory structure if necessary
              // System.out.println ("entry: "+name);
              int x = name.lastIndexOf ("/");
              if (x != -1)
              {
                 File dir = new File (_destDir.getCanonicalPath () + File.separator + 
name.substring (0, x));
                 if (!dir.exists ())
                    dir.mkdirs ();
              }
              // and extract...
              out = new FileOutputStream (_destDir.getCanonicalPath () + 
File.separator + name);
              copy (_in, out, false);
           }
        }
        _in.close ();
        }
  
        /** Creates  a temporary (unique) file.
         *  @param _parent the directory in which to create the file
         *  @param _prefix the file name prefix
         *  @param _suffix the file names suffix
         *  @throws IOException 
         */
        private File createTmpFile(File _parent, String _prefix, String _suffix) 
throws IOException
        {
                if (_parent.exists())
                {
                        if (!_parent.isDirectory())
                                throw new IOException ("parent file 
"+_parent.getCanonicalPath()+" is not a directory");
                }
                else
                {
                        if (!_parent.mkdirs())
                                throw new IOException ("couldnt create parent 
directory: "+_parent.getCanonicalPath());
                }
  
                File result = null;
                do
                {
                        result = new File (_parent, _prefix+nextNumber()+_suffix);
                } 
                while (result.exists());
  
                return result;
        }
  
        /** Creates  a temporary (unique) directory.
         *  @param _parent the directory in which to create the file
         *  @param _prefix the file name prefix
         *  @throws IOException 
         */
        private File createTmpDir(File _parent, String _prefix) throws IOException
        {
                File result = null;
                do
                {
                        result = new File (_parent, _prefix+nextNumber());
                }
                while (result.exists());
  
                if (!result.mkdirs())
                        throw new IOException ("couldnt create directory: 
"+result.getCanonicalPath());
  
                return result;
        }
  
        /** deletes a File recursive
         *  @throws IOException
         */
        private void deleteRecursive (File _file) throws IOException
        {
                if (_file.exists())
          {
                        if (_file.isDirectory ())
              {
                                File[] files = _file.listFiles ();
                                for (int i = 0, l = files.length; i < l; ++i)
                                        deleteRecursive(files[i]);
                        }
                        _file.delete ();
                }
        }
  
  }
  
  
  
  1.1                  jboss/src/main/org/jboss/deployment/InstallerFactory.java
  
  Index: InstallerFactory.java
  ===================================================================
  /*
   * jBoss, the OpenSource EJB server
   *
   * Distributable under GPL license.
   * See terms of license at gnu.org.
   */
  package org.jboss.deployment;
  
  import java.net.URL;
  import java.net.MalformedURLException;
  import java.net.URLClassLoader;
  import java.io.File;
  import java.io.ObjectInputStream;
  import java.io.ObjectOutputStream;
  import java.io.FileInputStream;
  import java.io.InputStream;
  import java.io.OutputStream;
  import java.io.FileOutputStream;
  import java.io.IOException;
  import java.util.Iterator;
  import java.util.Hashtable;
  import java.util.Vector;
  import java.util.ArrayList;
  import java.util.StringTokenizer;
  import java.util.Collection;
  import java.util.jar.JarFile;
  import java.util.jar.Manifest;
  import java.util.jar.Attributes;
  import java.util.jar.JarFile;
  import java.util.zip.ZipEntry;
  import java.util.zip.ZipInputStream;
  import java.util.zip.ZipEntry;
  import java.util.Enumeration;
  
  
  import javax.management.MBeanServer;
  import javax.management.MBeanException;
  import javax.management.JMException;
  import javax.management.ObjectName;
  
  import org.jboss.logging.Log;
  import org.jboss.util.MBeanProxy;
  import org.jboss.util.ServiceMBeanSupport;
  
  import org.jboss.metadata.XmlFileLoader;
  
  import org.jboss.ejb.DeploymentException;
  import org.jboss.ejb.ContainerFactoryMBean;
  
  import org.w3c.dom.Document;
  import org.w3c.dom.Element;
  
  
  
  /** This class is used by the J2eeDeployer to create, remove or find a particular 
   *  Deployment. It uses the Installer class to create a Deployment.
   *      
   *    @see <related>
   *    @author <a href="mailto:[EMAIL PROTECTED]">Daniel Schulze</a>
   *    @version $Revision: 1.1 $
   */
  public class InstallerFactory
  {
     // Constants -----------------------------------------------------
  
     
        // Attributes ----------------------------------------------------
        // the deployment base directory (for the temporary files)
      protected File baseDir;
        // the logger if there is something to say
        protected Log log;
  
    
        // Constructors --------------------------------------------------
  
        /** Constructs a new InstallerFactory, only one is needed per J2eeDeployer
         * @param _tmpDir the temporary deployment directory
         * @param _log the Log for output
         */        
        public InstallerFactory (File _tmpDir, Log _log) throws IOException
  
        {
                baseDir = _tmpDir.getCanonicalFile();
                log = _log;
        }
  
        // Public --------------------------------------------------------
  
        /** installs the J2ee component the URL points to and returns a Deployment 
object as its
         *  representation.
         *  @param _src J2ee module (ejb/war/ear) to deploy
         *  @return a Deployment object representing the deployment
         *  @throws J2eeDeploymentException if the module is not installable for some 
reasons 
         *  (syntactical errors, ...?)
         *  @throws IOException if a file operation (_src download jar file 
extraction) fails
         */
        public Deployment install(URL _src) throws J2eeDeploymentException, IOException
        {
  
                return new Installer (this, _src).execute();
  
        }
  
        /** uninstalls the files represented by the given Deployment.
         *  @param _d Deployment to remove
         *  @throws IOException if file deletion fails
         */
        public void uninstall (Deployment _d) throws IOException
        {
                File appDir = new File(_d.localUrl.getFile());
                
                deleteRecursive (appDir);
        }
  
        /** Finds all Deployments currently installed.
         *  @return array of all found deployments
         */
        public Deployment[] getDeployments()
        {
                Vector found = new Vector();
  
                File[] files =  baseDir.listFiles();
                for (int i = 0, l = files.length; i<l; ++i)
                {
                        File deployment = new File (files[i], J2eeDeployer.CONFIG);
                        if (deployment.exists())
                        {
                                try
                                {
                                        found.add(loadConfig(deployment));
                                }
                                catch (IOException _ioe)
                                {
                                        log.error("exception while searching 
deployments: "+_ioe.getMessage());
                                }
                        }
                }
  
                Deployment[] result = new Deployment[found.size()];
                Iterator it = found.iterator();
                for (int i = 0; it.hasNext(); ++i)
                        result[i] = (Deployment)it.next();
  
                return result;
        }
  
        /** Finds a particular Deployment.
         *  @param _pattern wether the name of the application or the src URL of the 
application 
         *         (the one that was given on install (URL))
         *  @return the Deployment object for this app or null if not found
         */
        public Deployment findDeployment (String _pattern)
        {
                if (_pattern == null)
                        return null;
  
                Deployment result = null;
  
                File[] files =  baseDir.listFiles();
                for (int i = 0, l = files.length; i<l; ++i)
                {
                        if (_pattern.endsWith (files[i].getName()))
                        {
                                try
                                {
                                        result = loadConfig(new File (files[i], 
J2eeDeployer.CONFIG));
                                        break;
                                }
                                catch (IOException _ioe)
                                {
                                        log.error("exception while searching 
deployment: "+_ioe.getMessage());
                                }
                        }
                }
                return result;
        }
  
  
        /** Does some cleanup in the deployments. Intended to remove files that didnt 
become removed
         *  in previous sessions because of the Win2k removal problems.
         *  @throws IOException since file deletions can fail
         */
        public void unclutter () throws IOException
        {
                File[] files =  baseDir.listFiles();
                for (int i = 0, l = files.length; i<l; ++i)
                {
                        File dep = new File (files[i], J2eeDeployer.CONFIG);
                        if (dep.exists())
                        {
                                // is a deployment... clean up its directory
                                try
                                {
                                        Deployment d = loadConfig(dep);
                                        Collection needed = d.getAllFiles();
                                        File[] parts = files[i].listFiles();
                                        for (int j = 0; j < parts.length; ++j)
                                        {
                                                if 
(!needed.contains(parts[j].getName()))
                                                {
                                                        // not needed -> delete
                                                        deleteRecursive(parts[j]);
                                                }
                                        }
                                }
                                catch (IOException _ioe)
                                {
                                        log.error("exception while uncluttering 
deployment "+files[i]+": "+_ioe.getMessage());
                                }
                        }
                        else
                        {
                                // is something we dont know -> we dont care about 
it...
                                deleteRecursive(files[i]);
                        }
                }
        }
  
  
     // Private -------------------------------------------------------
  
        /** Deserializes the Deployments pointed to by the given File.
         *  @param _file a serialized Deployment
         *  @return the deserialized Deployment
         *  @throws IOException when something went wrong
         */   
        private Deployment loadConfig (File _file) throws IOException
        {          
                Deployment d = null;
                try
                {
                        ObjectInputStream in = new ObjectInputStream (new 
FileInputStream (_file));
                        d = (Deployment)in.readObject ();
                        in.close ();
                }
                catch (ClassNotFoundException _snfe){} // should never happen...
                
                return d;
        }
  
        /** Truncates the the name (the last cluster of letters after the last slash.
         *  @param _url an URL or something like that
         */
        private String getName (String _url)
        {
                String result = _url;
                
                if (result.endsWith ("/"))
                        result = result.substring (0, result.length() - 1);
        
                result = result.substring (result.lastIndexOf ("/") + 1);
  
                return result;
      }
  
        /** deletes the given File recursive.
         *  @param _file to delete
         *  @throws IOException when something goes wrong
         */
        private void deleteRecursive (File _file) throws IOException
        {
                if (_file.exists())
          {
                        if (_file.isDirectory ())
              {
                                File[] files = _file.listFiles ();
                                for (int i = 0, l = files.length; i < l; ++i)
                                        deleteRecursive(files[i]);
                        }
                        _file.delete ();
                }
        }
  
  }
  
  
  

Reply via email to