User: schulze 
  Date: 00/10/02 17:08:17

  Added:       src/main/org/jboss/deployment Deployment.java
                        J2eeApplicationMetaData.java J2eeDeployer.java
                        J2eeDeployerMBean.java J2eeDeploymentException.java
                        J2eeModuleMetaData.java README.html URLWizzard.java
  Log:
  the first version of a j2ee compliant deployer mbean (see README for details)
  
  Revision  Changes    Path
  1.1                  jboss/src/main/org/jboss/deployment/Deployment.java
  
  Index: Deployment.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.util.Iterator;
  import java.util.Vector;
  
  /** Represents a J2EE application or module (EJB.jar, Web.war or App.ear). <br>
  */
  public class Deployment
     implements java.io.Serializable
  {
        // the applications name
     protected String name;
     // the url from which this app is downloaded and under which it is deployed 
     protected URL downloadUrl;
     // the local position of the apps root directory
     protected URL localUrl;
     
     // the Modules for jBoss and Tomcat
     protected Vector ejbModules;
     protected Vector webModules;
     
  
     /** Creates a new Deployment object.
     */
     Deployment ()
     {
        ejbModules = new Vector ();
        webModules = new Vector ();
  
     }
  
     public Module newModule ()
     {
        return new Module ();
     }
     
        
  
  
     /** Returns the admin context of this url.
     *   @param the download URL
     *   @return the administrator context as path fragment
     */      
     public static String getAdminCtx (URL _url)
     {
        StringBuffer sb = new StringBuffer ();
        if (_url.getProtocol ().equals ("file"))
        {
                String s = _url.getFile ();
                sb.append (s.substring (1, Math.max (0, s.lastIndexOf ("/"))));
        }
        else
        {
                sb.append (_url.getHost ());
                if (_url.getPort () != -1)
                {
                sb.append ("/");
                sb.append (_url.getPort ());
           }
        }
        return sb.toString ();
     }
  
     /** the name of the application.
     *   @param the download URL
     *   @return the app context as filename
     */      
     public static String getAppName (URL _url)
     {
        String s = _url.getFile ();
        // if it is a jar:<something>!/path/file url
        if (_url.getProtocol ().equals ("jar"))
        {
                int p = s.lastIndexOf ("!");
                if (p != -1)
                        s = s.substring (0, p);
        }
        
        return s.substring (Math.max (0, Math.min (s.length (), s.lastIndexOf ("/") + 
1))); 
     }
  
     /** returns app name with relative path in case of url is jar url. 
jar:<something>!/
     *   @param the download URL
     *   @return  wether file:|http:<bla>/<RETURNVALUE> or 
jar:<something>!/<RETURNVALUE>
     */      
     public static String getFileName (URL _url)
     {
        String s = _url.getFile ();
                int p = s.lastIndexOf ("!");
                if (p != -1)
                        // jar url...
                s = s.substring (Math.min (p + 2, s.length ()));
        else
                s = s.substring (Math.max (0, Math.min (s.length (), s.lastIndexOf 
("/") + 1))); 
        
        return s;
     }
  
     /** tries to compose a webcontext for WAR files from the given war file url */
     public static String getWebContext (URL _downloadUrl)
     {
        String s = getFileName (_downloadUrl);
        
        // truncate the file extension
        int p = s.lastIndexOf (".");
        if (p != -1)
           s = s.substring (0, p);
  
        return "/" + s.replace ('.', '/');
     }    
  
     /** Represents a J2ee module.
     *   the downloadURL (in case of ear something like: 
jar:applicationURL!/packagename)
     *   the localURL where the downloaded file is placed
     *   the downloadURL for an alternative dd
     *   in case of a web package the optional web root context
     */
     class Module
        implements java.io.Serializable
     {
        // a short name for the module
        String name;
        // the url from which it is downloaded
        // (in case of ear module like: jar:<app.downloadUrl>!/<module>
        URL downloadUrl;
        // the local url under which it is deployed by the special deployer
        URL localUrl;
        // the web root context in case of war file
        String webContext; 
     }
  }
  
  
  
  1.1                  jboss/src/main/org/jboss/deployment/J2eeApplicationMetaData.java
  
  Index: J2eeApplicationMetaData.java
  ===================================================================
  /*
   * jBoss, the OpenSource EJB server
   *
   * Distributable under GPL license.
   * See terms of license at gnu.org.
   */
  package org.jboss.deployment;
  
  import java.util.Vector;
  import java.util.Iterator;
  
  
  import org.jboss.ejb.DeploymentException;
  import org.jboss.metadata.MetaData;
  
  import org.w3c.dom.Element;
  
  /**
   *    <description> 
   *      
   *    @see <related>
   *    @author <firstname> <lastname> (<email>)
   *    @version $Revision: 1.1 $
   */
  public class J2eeApplicationMetaData
     extends MetaData
  {
     // Constants -----------------------------------------------------
      
     // Attributes ----------------------------------------------------
        String displayName;
     String description;
     String smallIcon;
        String largeIcon;
        
        Vector modules;
        
     // Static --------------------------------------------------------
     
     // Constructors --------------------------------------------------
     public J2eeApplicationMetaData (Element rootElement) throws DeploymentException
        {
                importXml (rootElement);
        }
        
     // Public --------------------------------------------------------
  
     public String getDisplayName ()
     {
        return displayName;
     }
     
     public String getDescription ()
     {
        return description;
     }
     
     public String getSmallIcon ()
     {
        return smallIcon;
     }
     
     public String getLargeIcon ()
     {
        return largeIcon;
     }
     
     public Iterator getModules ()
     {
        return modules.iterator ();
     }
     
  
  
  
      public void importXml (Element element) throws DeploymentException {
                String rootTag = 
element.getOwnerDocument().getDocumentElement().getTagName();
                
                if (rootTag.equals("application")) {
                        
                        // get some general info
           displayName = getElementContent (getUniqueChild (element, "display-name"));
           Element e = getOptionalChild (element, "description");
                        description = e != null ? getElementContent (e) : "";
  
           e = getOptionalChild (element, "icon");
                        if (e != null)
                        {
              Element e2 = getOptionalChild (element, "small-icon");
                                smallIcon = e2 != null ? getElementContent (e2) : "";
                                
              e2 = getOptionalChild (element, "large-icon");
                                largeIcon = e2 != null ? getElementContent (e2) : "";
                   } else
                   {
                                smallIcon = "";
                                largeIcon = "";
                        }
                        
                        // extract modules...
                        modules = new Vector ();
                        Iterator it = getChildrenByTagName (element, "module");
                        while (it.hasNext ())
                        {
                                modules.add (new J2eeModuleMetaData ((Element)it.next 
()));
                        }
                
                } else 
                        throw new DeploymentException("Unrecognized root tag in EAR 
deployment descriptor: "+ element);
        }
     
      
     // Y overrides ---------------------------------------------------
     
     // Package protected ---------------------------------------------
      
     // Protected -----------------------------------------------------
      
     // Private -------------------------------------------------------
  
     // Inner classes -------------------------------------------------
  }
  
  
  
  1.1                  jboss/src/main/org/jboss/deployment/J2eeDeployer.java
  
  Index: J2eeDeployer.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.io.File;
  import java.io.ObjectInputStream;
  import java.io.ObjectOutputStream;
  import java.io.FileInputStream;
  import java.io.FileOutputStream;
  import java.io.IOException;
  import java.util.Iterator;
  import java.util.Hashtable;
  import java.util.Vector;
  
  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.jboss.tomcat.EmbededTomcatServiceMBean;
  
  import org.w3c.dom.Document;
  import org.w3c.dom.Element;
  
  
  /** J2eeDeployer allows to deploy single EJB.jars as well as Web.wars
   *  (if Tomcat runs within the same VM as jBoss) or even Application.ears. <br>
   *  The deployment is done by determining the file type of the given url.
   *  The file must be a valid zip file and must contain either a META-INF/ejb-jar.xml
   *  or META-INF/application.xml or a WEB-INF/web.xml file.
   *  Depending on the file type, the whole file (EJBs, WARs)
   *  or only the relevant packages (EAR) becoming downloaded. <br>
   *  <i> replacing alternative DDs and validation is not yet implementet! </i>
   *  The uploaded files are getting passed through to the responsible deployer
   *  (ContainerFactory for jBoss and EmbededTomcatService for Tomcat).
   *  The state of deployments is persistent and becomes recovered after shutdown
   *  or crash.
   *
   *   @author Daniel Schulze ([EMAIL PROTECTED])
   *   @version $Revision: 1.1 $
   */
  public class J2eeDeployer 
     extends ServiceMBeanSupport
     implements J2eeDeployerMBean
  {
     // Constants -----------------------------------------------------
     public String DEPLOYMENT_DIR = "/home/deployment"; // default?
     public String CONFIG = "deployments.conf";   
  
     // Attributes ----------------------------------------------------
     // my server to lookup for the special deployers
     MBeanServer server;
  
     // names of the specials deployers
     ObjectName jBossDeployer;
     ObjectName tomcatDeployer;
  
     // The logger for this service
     Log log = new Log(getName());
  
     // the deployments
     Hashtable deployments = new Hashtable ();
     
     
     // Static --------------------------------------------------------
     /** only for testing...*/
     public static void main (String[] _args) throws Exception
     {
        new J2eeDeployer ("").deploy (_args[0]);
     }
     
     // Constructors --------------------------------------------------
     /** */
     public J2eeDeployer (String _deployDir)
     {
        DEPLOYMENT_DIR = _deployDir;
     }
     
     
     // Public --------------------------------------------------------
     /** Deploys the given URL independent if it is a EJB.jar, Web.war
     *   or Application.ear. In case of already deployed, it performes a
     *   redeploy.
     *   @param _url the url (file or http) to the archiv to deploy
     *   @throws MalformedURLException in case of a malformed url
     *   @throws J2eeDeploymentException if something went wrong...
     */
     public void deploy (String _url) throws MalformedURLException, 
J2eeDeploymentException
     {
        URL url = new URL (_url);
        
        // undeploy first if it is a redeploy
        if (deployments.containsKey (url))
           undeploy (_url);
        
        // now try to deploy
        log.log ("deploy j2ee application: " + _url);
  
        Deployment d = installApplication (url);
           
        deployments.put (d.downloadUrl, d);
        storeConfig ();
        log.log ("j2ee application: " + _url + " is deployed.");
     }
     
     /** Undeploys the given URL (if it is deployed).
     *   @param _url the url to to undeploy 
     *   @throws MalformedURLException in case of a malformed url
     *   @throws J2eeDeploymentException if something went wrong (but should have 
removed all files)
     */
     public void undeploy (String _url) throws MalformedURLException, 
J2eeDeploymentException
     {
        URL url = new URL (_url);
        
        log.log ("undeploy j2ee application: " + _url);
        Deployment d = (Deployment)deployments.get (url);
        if (d != null)
        {
           try 
           {      
              uninstallApplication (d);
                } 
                catch (J2eeDeploymentException e)
                {
                        throw e;
                } 
                finally
                {
                deployments.remove (url);
              storeConfig ();
              log.log ("j2ee application: " + _url + " is undeployed.");
           }
        } else
          log.warning (_url + " is NOT deployed!");
     }
     
     /** Checks if the given URL is currently deployed or not.
     *   @param _url the url to to check
     *   @return true if _url is deployed
     *   @throws MalformedURLException in case of a malformed url
     *   @throws J2eeDeploymentException if the app seems to be deployed, but some of 
its modules
     *   are not.
     */
     public boolean isDeployed (String _url) throws MalformedURLException, 
J2eeDeploymentException
     {
        URL url = new URL (_url);
  
           boolean deployed = deployments.containsKey (url);
           if (deployed)
           {
           try 
           {
                // check all modules ...
                Deployment d = (Deployment)deployments.get (url);
     
                // jBoss
                Iterator i = d.ejbModules.iterator ();
                while (i.hasNext () && deployed)
                {
                        Deployment.Module m = (Deployment.Module)i.next ();
                        // Call the ContainerFactory that is loaded in the JMX server
                 Object result = server.invoke(jBossDeployer, "isDeployed",
                                               new Object[] { m.localUrl.toString () 
}, new String[] { "java.lang.String" });
                 deployed = ((Boolean)result).booleanValue ();
              }
     
                // Tomcat
                i = d.webModules.iterator ();
                if (i.hasNext () && !withTomcat ())
                   throw new J2eeDeploymentException ("the application containes web 
modules but the tomcat service isn't running?!");
                
                while (i.hasNext () && deployed)
                {
                        Deployment.Module m = (Deployment.Module)i.next ();
                 Object result = server.invoke(tomcatDeployer, "isDeployed",
                                               new Object[] { m.localUrl.toString () 
}, new String[] { "java.lang.String" });
                 deployed = ((Boolean)result).booleanValue ();
              }
                   
                   if (!deployed)       
                      throw new J2eeDeploymentException ("The application is not 
correct deployed!");
  
           } 
           catch (MBeanException _mbe) {
                throw new J2eeDeploymentException ("error while interacting with 
deployer MBeans... " + _mbe.getTargetException ().getMessage ());
           } catch (JMException _jme){
                throw new J2eeDeploymentException ("fatal error while interacting with 
deployer MBeans... " + _jme.getMessage ());
           }
           }
           return deployed;
     }
     
     // ServiceMBeanSupport overrides ---------------------------------
     public String getName()
     {
        return "J2ee deployer";
     }
  
     protected ObjectName getObjectName(MBeanServer server, ObjectName name)
        throws javax.management.MalformedObjectNameException
     {
        this.server = server;
        return new ObjectName(OBJECT_NAME);
     }
  
     /** */
     protected void initService()
        throws Exception
     {
        // Save JMX name of the deployers
        jBossDeployer = new ObjectName(ContainerFactoryMBean.OBJECT_NAME);
        tomcatDeployer= new ObjectName(EmbededTomcatServiceMBean.OBJECT_NAME);
  
        //set the deployment directory
        DEPLOYMENT_DIR = new File (DEPLOYMENT_DIR).getCanonicalPath ();
        
        // load the configuration
        loadConfig ();
  
     }
  
     /** tries to redeploy all deployments before shutdown.*/
     protected void startService()
        throws Exception
     {
        if (!withTomcat ())
           log.log ("No EmbededTomcat found - only EJB deployment available...");
  
  
        log.log ("trying to redeploy all applications that were running before 
shutdown...");
        Iterator it = deployments.values ().iterator ();
        while (it.hasNext ())
        {
                Deployment d = (Deployment) it.next ();
                try
           {
                        deploy (d.downloadUrl.toString ());
           }
           catch (J2eeDeploymentException _e)
           {
                log.warning ("unable to redeploy application "+d.name+" -> delete 
it.");
           }
        }
        log.log ("deployment state recovered.");
     }
  
  
     /** */
     protected void stopService()
     {
  /*      // Uncomment method body to get redeploy only on server crash
        log.log ("undeploy all applications...");
        Iterator it = deployments.values ().iterator ();
        while (it.hasNext ())
        {
                Deployment d = (Deployment) it.next ();
                try
           {
                        undeploy (d.downloadUrl.toString ());
           }
           catch (J2eeDeploymentException _e)
           {
                log.warning ("hmmm... "+d.name+" dont wants to become undeployed?!");
           }
        }
        storeConfig ();
        log.log ("all applications undeployed.");
  */   }
      
     // Private -------------------------------------------------------
  
     /** Deploys all packages of the given deployment. <br>
     *   This means download the needed packages do some validation and/or
     *   other things and pass the references to the special deployers.
     *   <i> Validation and do some other things is not yet implemented </i>
     *   @param _d the deployment (= a J2ee application or module)
     */
     Deployment installApplication (URL _downloadUrl) throws J2eeDeploymentException
     {
        // determine the file type by trying to access one of the possible
        // deployment descriptors...
        Element root = null;
        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 (new URL ("jar:" + 
_downloadUrl.toString () + "!/" + files[i])).getDocumentElement ();
                } catch (Exception _e) {}
        }
  
        // create a Deployment
        Deployment d = new Deployment ();
        try {
           // if we found a deployment descriptor
           if (root != null)
           {         
              d.name = d.getAppName (_downloadUrl);
              d.downloadUrl = _downloadUrl;
              StringBuffer sb = new StringBuffer ("file:");
              sb.append (DEPLOYMENT_DIR);
              sb.append ("/");
              // sb.append (d.getAdminCtx (d.downloadUrl));
              // sb.append ("/");
              sb.append (d.name);
              d.localUrl = new URL (sb.toString ()); // should never throw an URLEx
  
                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
                        Deployment.Module m = d.newModule ();
                 // localUrl: file:<download_dir> / <adminCtx> / <appName> / <appName>
                 m.downloadUrl = d.downloadUrl;
                 m.name = d.getFileName (m.downloadUrl);
                 m.localUrl = new URL (d.localUrl.toString () + "/" + m.name);// 
should never throw an URLEx
  
                log.log ("downloading module " + m.name);
                 URLWizzard.download (m.downloadUrl, m.localUrl);
                 d.ejbModules.add (m);                  
                } 
                else if ("web-app".equals (root.getTagName ()))
                {
                        // its a WAR.jar... just take the package
                        if (!withTomcat ())
                           throw new J2eeDeploymentException ("Tomcat is not 
available!");
                        
                        Deployment.Module m = d.newModule ();
                 m.downloadUrl = d.downloadUrl;
                 m.name = d.getFileName (m.downloadUrl);
                 m.localUrl = new URL (d.localUrl.toString () + "/" + m.name);// 
should never throw an URLEx
                 m.webContext = d.getWebContext (m.downloadUrl);
  
                log.log ("downloading module " + m.name);
                 URLWizzard.downloadAndInflate (m.downloadUrl, m.localUrl);
                 d.webModules.add (m);                  
                } 
                else if ("application".equals (root.getTagName ()))
              {
                        // its a EAR.jar... hmmm, its a little more
                        // create a MetaData object...
                 J2eeApplicationMetaData app;
                        app = new J2eeApplicationMetaData (root);
        
                 // 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 ();
                        while (it.hasNext ())
                   {
                                mod = (J2eeModuleMetaData) it.next ();
                                // iterate the ear modules
                    if (mod.isEjb () || mod.isWeb ())
                    {
                        // a EJB or WEB package...
                       Deployment.Module m = d.newModule ();
                       try 
                       {
                          m.downloadUrl = new URL ("jar:" + _downloadUrl.toString () + 
"!/" + mod.getFileName ());// chould throw an URLEx
                          m.name = d.getFileName (m.downloadUrl);
                          m.localUrl = new URL (d.localUrl.toString () + "/" + 
m.name);// chould throw an URLEx
                       } catch (MalformedURLException _mue) { 
                          throw new J2eeDeploymentException ("syntax error in module 
section in application DD : " + _mue.getMessage ());
                       }
                       
                       if (mod.isWeb ())
                       {
                                if (!withTomcat ())
                                   throw new J2eeDeploymentException ("Tomcat is not 
available!");
  
                          m.webContext = mod.getWebContext ();
                          if (m.webContext == null)
                             m.webContext = d.getWebContext (m.downloadUrl);
           
                        log.log ("downloading and inflating module " + m.name);
                          URLWizzard.downloadAndInflate (m.downloadUrl, m.localUrl);
                          d.webModules.add (m);                 
                       }
                       else
                       {
                        log.log ("downloading module " + m.name);
                          URLWizzard.download (m.downloadUrl, m.localUrl);
                          d.ejbModules.add (m);
                       }
  
                       // here the code for checking and DD replacment...
                       // ...
                       } 
                 }
                    // other packages we dont care about (currently)
                }
                
                // redirict all modules to the responsible deployer
                Deployment.Module m = null;
              try
              {
                        // jBoss
                 Iterator it = d.ejbModules.iterator ();
                 while (it.hasNext ())
                 {
                        m = (Deployment.Module)it.next ();
                        log.log ("deploying module " + m.name);
                        // Call the ContainerFactory that is loaded in the JMX server
                    server.invoke(jBossDeployer, "deploy",
                                    new Object[] { m.localUrl.toString () }, new 
String[] { "java.lang.String" });
                 }
        
                        
                        // Tomcat
                 it = d.webModules.iterator ();
                 while (it.hasNext ())
                 {
                        m = (Deployment.Module)it.next ();
                        log.log ("deploying module " + m.name);
                        // Call the TomcatDeployer that is loaded in the JMX server
                    server.invoke(tomcatDeployer, "deploy",
                                    new Object[] { m.webContext, m.localUrl.toString 
()}, new String[] { "java.lang.String", "java.lang.String" });
                        
                }
              }
              catch (MBeanException _mbe) {
                        log.log ("deploying failed!");
                           uninstallApplication (d);
                throw new J2eeDeploymentException ("error while interacting with 
deployer MBeans... " + _mbe.getTargetException ().getMessage ());
              } catch (JMException _jme){
                        log.log ("deploying failed!");
                           uninstallApplication (d);
                throw new J2eeDeploymentException ("fatal error while interacting with 
deployer MBeans... " + _jme.getMessage ());
              }                         
              
  
              return d;
           }
           else
              throw new J2eeDeploymentException (_downloadUrl.toString ()+" points not 
to a valid j2ee application (app.ear/ejb.jar/web.war)!");
  
                } catch (IOException _ioe) {
                   uninstallApplication (d);
                   throw new J2eeDeploymentException ("Error in downloading module: " 
+ _ioe.getMessage ());
                } catch (DeploymentException _de) { 
                   uninstallApplication (d);
                   throw new J2eeDeploymentException ("Unable scan .ear file: " + 
_de.getMessage ());
                } catch (Exception _e) { 
                   _e.printStackTrace ();
                   uninstallApplication (d);
                   throw new J2eeDeploymentException ("FATAL ERROR!");
        }                       
        
     }
  
     void uninstallApplication (Deployment _d) throws J2eeDeploymentException
     {
        log.log ("destroying application " + _d.name);
        String error = "";
        Iterator it = _d.ejbModules.iterator ();
        while (it.hasNext ())
        {
                Deployment.Module m = (Deployment.Module)it.next ();
                log.log ("uninstalling module " + m.name);
                
                //jBoss
           try
           {
                        // Call the ContainerFactory that is loaded in the JMX server
              server.invoke(jBossDeployer, "undeploy",
                              new Object[] { m.localUrl.toString () }, new String[] { 
"java.lang.String" });
           }
           catch (MBeanException _mbe) {
                log.warning ("unable to undeploy module " + m.name + ": " + 
_mbe.getTargetException ().getMessage ());
           } catch (JMException _jme){
                error += "[fatal error while interacting with deployer MBeans... " + 
_jme.getMessage () + "]";
                }
        }
        it = _d.webModules.iterator ();
        while (it.hasNext ())
        {
                Deployment.Module m = (Deployment.Module)it.next ();
                log.log ("uninstalling module " + m.name);
  
                // tomcat
                if (withTomcat ())
                {
              try
              {
                 server.invoke(tomcatDeployer, "undeploy",
                                 new Object[] { m.localUrl.toString () }, new String[] 
{ "java.lang.String" });
              }
              catch (MBeanException _mbe) {
                log.warning ("unable to undeploy module " + m.name + ": " + 
_mbe.getTargetException ().getMessage ());
              } catch (JMException _jme){
                error += "[fatal error while interacting with deployer MBeans... " + 
_jme.getMessage () + "]";
                        }
           }
        }       
        
        try 
        {
           URLWizzard.deleteTree (_d.localUrl);      
                log.log ("file tree "+_d.localUrl.toString ()+" deleted.");
        } catch (IOException _ioe) {
                   throw new J2eeDeploymentException ("Error in removing local 
application files ("+_d.localUrl+"): " + _ioe.getMessage ());
        }
  
        if (!error.equals (""))
                   throw new J2eeDeploymentException (error);
     }
  
  
  
     private void loadConfig ()
     {
        try {
        ObjectInputStream in = new ObjectInputStream (new FileInputStream 
(DEPLOYMENT_DIR + File.separator + CONFIG));
        deployments = (Hashtable)in.readObject ();
        in.close ();
        } catch (Exception e)
        {
                log.log ("no config file found...");
        }
     }
  
     private void storeConfig ()
     {
        try {
        ObjectOutputStream out = new ObjectOutputStream (new FileOutputStream 
(DEPLOYMENT_DIR + File.separator + CONFIG));
        out.writeObject (deployments);
        out.close ();
        } catch (IOException e)
        {
                log.warning ("storing config failed...");
        }
     }
  
     private boolean withTomcat ()
     {
        return server.isRegistered (tomcatDeployer);
     }
  
  }
  
  
  
  1.1                  jboss/src/main/org/jboss/deployment/J2eeDeployerMBean.java
  
  Index: J2eeDeployerMBean.java
  ===================================================================
  /*
   * jBoss, the OpenSource EJB server
   *
   * Distributable under GPL license.
   * See terms of license at gnu.org.
   */
  package org.jboss.deployment;
  
  import java.net.MalformedURLException;
  import org.jboss.util.ServiceMBean;
  
  /**
   *   @see 
   *   @author Daniel Schulze ([EMAIL PROTECTED])
   *   @version $Revision: 1.1 $
   */
  public interface J2eeDeployerMBean
        extends ServiceMBean
  {
     // Constants -----------------------------------------------------
     public static final String OBJECT_NAME = "J2EE:service=J2eeDeployer";
      
     // Public --------------------------------------------------------
     public void deploy (String url) throws MalformedURLException, 
J2eeDeploymentException;
  
     public void undeploy (String url) throws MalformedURLException, 
J2eeDeploymentException;
  
     public boolean isDeployed (String url) throws MalformedURLException, 
J2eeDeploymentException;
  }
  
  
  
  1.1                  jboss/src/main/org/jboss/deployment/J2eeDeploymentException.java
  
  Index: J2eeDeploymentException.java
  ===================================================================
  /*
   * jBoss, the OpenSource EJB server
   *
   * Distributable under GPL license.
   * See terms of license at gnu.org.
   */
  package org.jboss.deployment;
  
  /**
   *    <description> 
   *      
   *    @author Daniel Schulze [EMAIL PROTECTED]
   *    @version $Revision: 1.1 $
   */
  public class J2eeDeploymentException 
        extends Exception
  {
  
     // Constructors --------------------------------------------------
        public J2eeDeploymentException (String message)
     {
                super (message);
        }
        
  }
  
  
  
  
  
  1.1                  jboss/src/main/org/jboss/deployment/J2eeModuleMetaData.java
  
  Index: J2eeModuleMetaData.java
  ===================================================================
  /*
   * jBoss, the OpenSource EJB server
   *
   * Distributable under GPL license.
   * See terms of license at gnu.org.
   */
  package org.jboss.deployment;
  
  import org.jboss.ejb.DeploymentException;
  import org.jboss.metadata.MetaData;
  
  import org.w3c.dom.Element;
  
  /**
   *    <description> 
   *      
   *    @see <related>
   *    @author Daniel Schulze [EMAIL PROTECTED]
   *    @version $Revision: 1.1 $
   */
  public class J2eeModuleMetaData
     extends MetaData
  {
     // Constants -----------------------------------------------------
     public static final int EJB = 0; 
     public static final int WEB = 1; 
     public static final int CLIENT = 2; 
     public static final int CONNECTOR = 3; 
        private static final String[] tags = {"ejb", "web", "java", "connector"}; 
         
     // Attributes ----------------------------------------------------
        int type;
     
        String fileName;
     String alternativeDD;
        String webContext;
  
     // Static --------------------------------------------------------
     
     // Constructors --------------------------------------------------
     public J2eeModuleMetaData (Element moduleElement)  throws DeploymentException
        {
                importXml (moduleElement);
        }
        
     // Public --------------------------------------------------------
  
        public boolean isEjb ()
        {
                return (type == EJB);
        }
  
        public boolean isWeb ()
        {
                return (type == WEB);
        }
        
        public boolean isJava ()
        {
                return (type == CLIENT);
        }
        
        public boolean isConnector ()
        {
                return (type == CONNECTOR);
        }
        
        
        
        public String getFileName ()
        {
                return fileName;
        }
        
        public String getAlternativeDD ()
        {
                return alternativeDD;
        }
        
        public String getWebContext ()
        {
                if (type == WEB)
                        return webContext;
                else
                        return null;
        }
  
  
      public void importXml (Element element) throws DeploymentException 
         {
                if (element.getTagName ().equals("module")) 
                {
                 boolean done = false; // only one of the tags can hit! 
           for (int i = 0; i < tags.length; ++i)
                        {
                                Element child = getOptionalChild (element, tags[i]);
                                if (child == null)
                                        continue;
                                
              if (done)
                                        throw new DeploymentException ("malformed 
module definition in application dd: "+ element);
  
              type = i;
                                switch (type)
                                {
                                        case EJB:
                                        case CLIENT:
                                        case CONNECTOR:
                                                fileName = getElementContent (child);
                                           alternativeDD = getElementContent 
(getOptionalChild (element, "alt-dd"));
                                                break;
                                        case WEB:
                                                fileName = getElementContent 
(getUniqueChild (child, "web-uri"));
                                                webContext = getElementContent 
(getOptionalChild (child, "context-root"));
                                            alternativeDD = getElementContent 
(getOptionalChild (element, "alt-dd"));
                                }
                                done = true;
                        }
                 } else 
                        throw new DeploymentException ("unrecognized module tag in 
application dd: "+ element);
        }
     
      
     // Y overrides ---------------------------------------------------
     
     // Package protected ---------------------------------------------
      
     // Protected -----------------------------------------------------
      
     // Private -------------------------------------------------------
  
     // Inner classes -------------------------------------------------
  }
  
  
  
  1.1                  jboss/src/main/org/jboss/deployment/README.html
  
  Index: README.html
  ===================================================================
  <html>
  <head>
  <title>J2EE Deployer read me</title>
  </head>
  <body bgcolor="#ffffff">
     <h1>J2EE Deployer</h1>
     <div align="right"><font size="-3" color="#555555"> by <A 
href="mailto:[EMAIL PROTECTED]"> Daniel Schulze </A> </font></div>
     <hr>
  
     <h3>The idea</h3>
     <p> The j2ee deployer is made to delpoy j2ee compilant applications which means 
.ear,
         ejb.jar and web.war files as well.
     </p>
  
     <p> This MBean references the 
<code><b>org.jboss.ejb.ContainerFactoryBMBean</b></code> and
         <code><b>org.jboss.tomcat.EmbededTomcatServiceMBean</b></code>. Both beans 
have to run
         in the same server and since the deployer in his start service method tries 
to deploy
         all apps that were deployed before shutdown, these both services must be 
started before
         the j2ee deployer! To make this sure, there must be a service entry for the 
j2ee deployer
         in the jboss.dependencies file.
     </p>
  
     <hr>
  
     <h3>How it works</h3>
     <p> <dl>
         <dt><b>deploy ()</b></dt>
         <dd> The deployer takes the given url and tries to determine the type of the 
given file
         (this is done by seeking one of the possible deployment descriptors in this 
file
         (application.xml, ejb-jar.xml, web.xml)). If a valid file type was 
determined, all
         for the deployment needed files (modules, libs, alternative DDs, ...) are 
downloaded
         to a local directory of the app server. Once this is done the ejb and war 
deployers
         (ContainerFactory and EmbeddedTomcat) are called to deploy the single 
modules. <br>
         If this was successful, the current url is stored to the deployments 
collection. If
         one of the ejb/war deployer calls fails, the deployment becomes canceled and 
all
         downloaded files are deleted.</dd>
         <dt><b>isDeployed ()</b></dt>
         <dd> Looks in the collection of deployments for the given url. If the url is 
found, the
         ejb/war deployer for each module of this app is asked for isDeployed () and 
only
         if all modules are correct deployed, the method returns true. If there is an
         inconsistence in the deployments an exception is thrown.</dd>
         <dt><b>undeploy ()</b></dt>
         <dd>Undeployes all modules of this application,removes all server local files 
of this
         app and removes this url from the collection of deployed urls. (This method 
should
         always succeed).</dd>
         </dl>
     </p>
  
     <hr>
  
     <h3>What is done</h3>
     <p><ul>
        <li> download of ejb.jar and web.war modules</li>
        <li> deployment of these modules </li>
        <li> <code>isDeployed ()</code> - method added to ContainerFactory
        </ul>
     </p>
  
     <hr>
  
     <h3>What is to do</h3>
     <p><ul>
        <li> extracting web.wars on download </li>
        <li> replacing module DDs with alternative DDs </li>
        <li> integrity check in case of ear files
             <ul>
             <li> unify security roles </li>
             <li> <i>things I ve missed ... </i></li>
             </ul>
        </li>
        <li> find common libraries, download them and add them to the classpath(s)
             of the modules </li>
        <li> move the verification stuff from the ContainerFactory to here?
        </ul>
     </p>
  
  
  
  </body>
  </html>
  
  
  1.1                  jboss/src/main/org/jboss/deployment/URLWizzard.java
  
  Index: URLWizzard.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.URLConnection;
  
  import java.io.File;
  import java.io.FileOutputStream;
  import java.io.InputStream;
  import java.io.InputStreamReader;
  import java.io.BufferedReader;
  import java.io.OutputStream;
  import java.io.OutputStreamWriter;
  import java.io.BufferedWriter;
  import java.io.IOException;
  
  import java.util.zip.ZipEntry;
  import java.util.zip.ZipInputStream;
  
  
  /**
   *    Encapsulates URL bases copy and jar file operations.
   * Very scratchy! Any improvements are welcome!
   *      
   *    @author Daniel Schulze <[EMAIL PROTECTED]>
   *    @version $Revision: 1.1 $
   */
  public class URLWizzard
  {
      
     // Static --------------------------------------------------------
     public static void main (String[] _args) throws Exception
     {
        downloadAndInflate (new URL (_args[0]), new URL (_args[1]));
     }
     
     
     
     
     /** copies the source to the destination url. As destination
         are currently only file:/... urls supported */
     public static void download (URL _src, URL _dest) throws IOException
     {
        InputStream in;
        OutputStream out;
  /*
        URLConnection urlCon = _src.openConnection ();
        urlCon.setDoInput (true);
        in = urlCon.getInputStream ();
  */
        in = _src.openStream ();
  
        
        boolean jar = false;
        String jarPath = "";
        String filePath;
        String fileName;
        String s = _dest.toString ();
        
        if (_dest.getProtocol ().equals ("jar"))
        {
                // get the path in the jar
           int pos = s.indexOf ("!");
                jarPath = s.substring (pos + 1);
                s = s.substring (0, pos);
        }
        
        // get the FileName
        int pos = s.lastIndexOf ("/");
        fileName = s.substring (pos + 1);
        s = s.substring (0, pos);
  
        // get the FilePath
        pos = Math.max (0, s.lastIndexOf (":"));
        filePath = s.substring (pos + 1);
        filePath = filePath.replace ('/', File.separatorChar);
        
        if (jar)
        {
           // open jarFile
           throw new IOException ("write into a jar file NOT yet implemented!");       
         
        }
        else
        {
                File dir = new File (filePath);
                if (!dir.exists ())
                   dir.mkdirs ();
                
                out = new FileOutputStream (filePath + File.separator + fileName); 
        }
        
        write (in, out);
  
        out.close ();
        in.close ();
     }
  
     /** inflates the given zip file into the given directory */
     public static void downloadAndInflate (URL _src, URL _dest) throws IOException
     {
        InputStream in;
        OutputStream out;
  
        in = _src.openStream ();
  
        boolean jar = false;
        String jarPath = "";
        String filePath;
        String fileName;
        String s = _dest.toString ();
  
        if (!_dest.getProtocol ().equals ("file"))
           throw new IOException ("only file:/ is as destination allowed!");           
 
                
        File base = new File (_dest.getFile ());
        if (base.exists ())
           deleteTree (_dest);
        
           base.mkdirs ();
  
        ZipInputStream zin = new ZipInputStream (in);
        ZipEntry entry;
        while ((entry = zin.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 (base.getCanonicalPath () + File.separator + 
name.substring (0, x));
                 if (!dir.exists ())
                    dir.mkdirs ();
              }
              // and extract...
              out = new FileOutputStream (base.getCanonicalPath () + File.separator + 
name);
              write (zin, out);
              out.close ();
           }
        }
        zin.close ();
     }
     
  
  
     /** deletes the given file:/... url recursively */    
     public static void deleteTree (URL _dir) throws IOException
     {
        if (!_dir.getProtocol ().equals ("file"))
           throw new IOException ("Protocol not supported");
  
        File f = new File (_dir.getFile ());
        if (!delete (f))
           throw new IOException ("deleting " + _dir.toString () + "recursively 
failed!");
     }
  
     /** deletes a file recursively */    
     private static boolean delete (File _f) throws IOException
     {
        if (_f.exists ())
        {
                if (_f.isDirectory ())
                {
                        File[] files = _f.listFiles ();
                        for (int i = 0, l = files.length; i < l; ++i)
                           if (!delete (files[i]))
                               return false;
           }
           return _f.delete ();
        }
        return true;
     }
  
  
     /** writes the content of the InputStream into the OutputStream */
     private static void write (InputStream _in, OutputStream _out) throws IOException
     {
        int b;
        while ((b = _in.read ()) != -1)
           _out.write ((byte)b);
                
        _out.flush ();
     }
  
  
  }
  
  
  

Reply via email to