dion        02/05/15 08:02:01

  Modified:    src/java/org/apache/maven/j2ee WarValidator.java
  Added:       src/java/org/apache/maven/j2ee WarClassLoader.java
                        WarFile.java
  Log:
  no message
  
  Revision  Changes    Path
  1.11      +89 -80    
jakarta-turbine-maven/src/java/org/apache/maven/j2ee/WarValidator.java
  
  Index: WarValidator.java
  ===================================================================
  RCS file: 
/home/cvs/jakarta-turbine-maven/src/java/org/apache/maven/j2ee/WarValidator.java,v
  retrieving revision 1.10
  retrieving revision 1.11
  diff -u -r1.10 -r1.11
  --- WarValidator.java 15 May 2002 05:50:57 -0000      1.10
  +++ WarValidator.java 15 May 2002 15:02:01 -0000      1.11
  @@ -55,11 +55,18 @@
    */
   
   import java.io.File;
  +import java.io.BufferedInputStream;
  +import java.io.BufferedOutputStream;
  +import java.io.FileOutputStream;
   import java.io.InputStream;
   import java.io.IOException;
  +import java.net.MalformedURLException;
  +import java.net.URL;
  +import java.net.URLClassLoader;
   import java.util.jar.JarEntry;
   import java.util.jar.JarFile;
   import java.util.zip.ZipException;
  +import java.util.ArrayList;
   import java.util.Enumeration;
   import java.util.HashMap;
   import java.util.Iterator;
  @@ -69,11 +76,6 @@
   import org.apache.tools.ant.BuildException;
   import org.apache.maven.executor.AbstractExecutor;
   
  -import org.dom4j.Document;
  -import org.dom4j.DocumentException;
  -import org.dom4j.Node;
  -import org.dom4j.io.SAXReader;
  -
   /**
    * A task to validate a war file. The following is checked:
    * <ol>
  @@ -149,45 +151,15 @@
        */
       public void validate()
       {
  -        File warFile = null;
           try
           {
               getBroadcaster().fireStartedEvent( new ValidationEvent(this, 
                   getWarFileName(), "war validation started"));
  -        
  -            warFile = new File(getWarFileName());
  -
  -            if (!warFile.exists())
  -            {
  -                getBroadcaster().fireErrorEvent(new ValidationEvent(this, 
  -                    getWarFileName(), "File does not exist"));
  -                return;
  -            }
  -            if (!warFile.canRead())
  -            {
  -                getBroadcaster().fireErrorEvent(new ValidationEvent(this, 
  -                    getWarFileName(), "File does not exist"));
  -                return;
  -            }
  -
  -            JarFile jarFile = new JarFile(warFile);
  -            // validate structure - at the moment just web.xml
  -            JarEntry webxmlEntry = jarFile.getJarEntry("WEB-INF/web.xml");
  -            if (webxmlEntry == null)
  +            validateFile();
  +            if (!getStatus().isError())
               {
  -                getBroadcaster().fireWarningEvent(new ValidationEvent(this,
  -                    getWarFileName(), "WEB-INF/web.xml entry not found"));
  +                validateWebXml();
               }
  -            else
  -            {
  -                validateWebXml(jarFile);
  -            }
  -            
  -        }
  -        catch (IOException ioe)
  -        {
  -            getBroadcaster().fireErrorEvent(new ValidationEvent(this, 
  -                getWarFileName(), "Error opening war file"));
           }
           finally
           {
  @@ -196,41 +168,73 @@
           }
       }
       
  +    /** validate the war file can be read and exists
  +     */
  +    private void validateFile()
  +    {
  +        File warFile = new File(getWarFileName());
  +
  +        if (!warFile.exists())
  +        {
  +            getBroadcaster().fireErrorEvent(new ValidationEvent(this, 
  +                getWarFileName(), "File does not exist"));
  +            return;
  +        }
  +        if (!warFile.canRead())
  +        {
  +            getBroadcaster().fireErrorEvent(new ValidationEvent(this, 
  +                getWarFileName(), "File can't be read"));
  +            return;
  +        }
  +    }
  +    
       /** Validate the web.xml entry in the provided jar file.
        * @param jarFile - a jar file with a known WEB-INF/web.xml
        */
  -    private void validateWebXml(JarFile jarFile)
  +    private void validateWebXml()
       {
  -        try
  +        WarFile war = null;
  +        try 
           {
  -            JarEntry webXmlEntry = jarFile.getJarEntry("WEB-INF/web.xml");
  -            InputStream webXmlStream = jarFile.getInputStream(webXmlEntry);
  -            SAXReader xmlReader = new SAXReader(false);
  -            Document webXmlDoc = xmlReader.read(webXmlStream);
  -            // collect list of servlets
  -            Map servlets = getServlets(webXmlDoc);
  -            // check that there are servlets
  -            if (servlets.size() != 0) 
  +            war = new WarFile(getWarFileName());
  +            if (war.getWebXmlEntry() == null)
               {
  -                // expand jar file WEB-INF/lib/*.jar to temp files
  -                
  -                // create a URL classloader from temp files + WEB-INF/classes
  -                // check each servlet by loadClass
  -                // make sure class.classLoader == url classloader
  +                getBroadcaster().fireWarningEvent(new ValidationEvent(this,
  +                    getWarFileName(), "web.xml entry not found"));
  +                return;
               }
  +            validateServlets(war);
           }
  -        catch (DocumentException de)
  +        catch (IOException ioe)
           {
  -            de.printStackTrace();
               getBroadcaster().fireErrorEvent(new ValidationEvent(this, 
  -                getWarFileName(), "Error producing XML from WEB-INF/web.xml"));
  -            
  +                getWarFileName(), "Error opening war file for web.xml - " + 
  +                    "possibly missing manifest"));
           }
  -        catch (ZipException ze)
  +    }
  +
  +    /**
  +     */
  +    private void validateServlets(WarFile war)
  +    {
  +        try
           {
  -            ze.printStackTrace();
  -            getBroadcaster().fireErrorEvent(new ValidationEvent(this, 
  -                getWarFileName(), "Error retrieving WEB-INF/web.xml from the jar"));
  +            Map servlets = war.getServlets();
  +            if (servlets.size() != 0) 
  +            {
  +                // create a URL classloader from temp files + WEB-INF/classes
  +                ClassLoader classLoader = new WarClassLoader(war);
  +                String className = null;
  +                Map.Entry entry = null;
  +                for (Iterator entries = servlets.entrySet().iterator();
  +                    entries.hasNext();)
  +                {
  +                    entry = (Map.Entry) entries.next();
  +                    className = (String) entry.getValue();
  +                    // check each servlet by loadClass
  +                    validateClass(className, classLoader);
  +                }
  +            }
           }
           catch (IOException ioe)
           {
  @@ -240,26 +244,31 @@
           }
       }
       
  -    /**
  -     * Get the servlets from web.xml.
  -     *
  -     * @param webXml a web.xml as a dom4j document
  -     * @return a map containing servlet name -> servlet class for all servlets
  -     *         in the web.xml provided
  -     */
  -    private Map getServlets(Document webXml)
  -    {
  -        List servletNodes = webXml.selectNodes("//servlet");
  -        Node node = null;
  -        Map servlets = new HashMap();
  -        for (Iterator nodes = servletNodes.iterator(); nodes.hasNext();)
  -        {
  -            node = (Node) nodes.next();
  -            String servletName = node.selectSingleNode("./servlet-name").getText();
  -            String servletClass = 
node.selectSingleNode("./servlet-class").getText();
  -            servlets.put(servletName, servletClass);
  +    /** Validate that the given className can be loaded by the given
  +     * {@link ClasssLoader}
  +     * @param className the name of a class to attempt loading
  +     * @param loader a {@link ClassLoader class loader}
  +     */
  +    private void validateClass(String className, ClassLoader loader)
  +    {
  +        try 
  +        {
  +            Class clazz = loader.loadClass(className);
  +            if (clazz.getClassLoader() != loader)
  +            {
  +                // loaded from classpath - a no no.
  +                getBroadcaster().fireErrorEvent( new 
  +                    ValidationEvent(this, getWarFileName(),
  +                    "class (" + className + ") loaded from system" +
  +                    "classpath rather than war file"));
  +            }
           }
  -        return servlets;
  +        catch (ClassNotFoundException e)
  +        {
  +            getBroadcaster().fireErrorEvent( new ValidationEvent(this, 
  +                getWarFileName(), "class (" + className + ") not found "));
  +        }
  +
       }
       
       /**
  
  
  
  1.1                  
jakarta-turbine-maven/src/java/org/apache/maven/j2ee/WarClassLoader.java
  
  Index: WarClassLoader.java
  ===================================================================
  package org.apache.maven.j2ee;
  
  /* ====================================================================
   * The Apache Software License, Version 1.1
   *
   * Copyright (c) 2002 The Apache Software Foundation.  All rights
   * reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   *
   * 1. Redistributions of source code must retain the above copyright
   *    notice, this list of conditions and the following disclaimer.
   *
   * 2. Redistributions in binary form must reproduce the above copyright
   *    notice, this list of conditions and the following disclaimer in
   *    the documentation and/or other materials provided with the
   *    distribution.
   *
   * 3. The end-user documentation included with the redistribution,
   *    if any, must include the following acknowledgment:
   *       "This product includes software developed by the
   *        Apache Software Foundation (http://www.apache.org/)."
   *    Alternately, this acknowledgment may appear in the software itself,
   *    if and wherever such third-party acknowledgments normally appear.
   *
   * 4. The names "Apache" and "Apache Software Foundation" and
   *    "Apache Maven" must not be used to endorse or promote products
   *    derived from this software without prior written permission. For
   *    written permission, please contact [EMAIL PROTECTED]
   *
   * 5. Products derived from this software may not be called "Apache",
   *    "Apache Maven", nor may "Apache" appear in their name, without
   *    prior written permission of the Apache Software Foundation.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   * ====================================================================
   *
   * This software consists of voluntary contributions made by many
   * individuals on behalf of the Apache Software Foundation.  For more
   * information on the Apache Software Foundation, please see
   * <http://www.apache.org/>.
   */
  
  import java.io.File;
  import java.io.IOException;
  import java.net.MalformedURLException;
  import java.net.URL;
  import java.net.URLClassLoader;
  import java.util.ArrayList;
  import java.util.Iterator;
  import java.util.List;
  import java.util.Set;
  import java.util.jar.JarEntry;
  
  /**
   * A {@link ClassLoader} that loads classes from a {@link WarFile}
   *
   * @author <a href="mailto:[EMAIL PROTECTED]";>dIon Gillard</a>
   * @version $Id: WarClassLoader.java,v 1.1 2002/05/15 15:02:01 dion Exp $
   */
  public class WarClassLoader extends URLClassLoader
  {
      /** temp files created by classloader */
      private List tempFiles = new ArrayList();
      
      /** Creates a new instance of WarClassLoader
       * @param war a {@link WarFile}
       */
      public WarClassLoader(WarFile war) throws MalformedURLException, IOException
      {
          super (new URL[0]);
          File warFile = new File(war.getName());
          URL webInfClasses = new URL("jar:" + warFile.toURL() + "!/" +
              "WEB-INF/classes/");
          addURL(webInfClasses);
          Set jars = war.getLibEntries();
          JarEntry entry = null;
          for (Iterator jarEntries = jars.iterator(); jarEntries.hasNext();)
          {
              entry = (JarEntry) jarEntries.next();
              File jar = war.extract(entry);
              tempFiles.add(jar);
              jar.deleteOnExit();
              addURL(new URL("jar:" + jar.toURL() + "!/"));
          }
      }
  }
  
  
  
  1.1                  
jakarta-turbine-maven/src/java/org/apache/maven/j2ee/WarFile.java
  
  Index: WarFile.java
  ===================================================================
  package org.apache.maven.j2ee;
  
  /* ====================================================================
   * The Apache Software License, Version 1.1
   *
   * Copyright (c) 2002 The Apache Software Foundation.  All rights
   * reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   *
   * 1. Redistributions of source code must retain the above copyright
   *    notice, this list of conditions and the following disclaimer.
   *
   * 2. Redistributions in binary form must reproduce the above copyright
   *    notice, this list of conditions and the following disclaimer in
   *    the documentation and/or other materials provided with the
   *    distribution.
   *
   * 3. The end-user documentation included with the redistribution,
   *    if any, must include the following acknowledgment:
   *       "This product includes software developed by the
   *        Apache Software Foundation (http://www.apache.org/)."
   *    Alternately, this acknowledgment may appear in the software itself,
   *    if and wherever such third-party acknowledgments normally appear.
   *
   * 4. The names "Apache" and "Apache Software Foundation" and
   *    "Apache Maven" must not be used to endorse or promote products
   *    derived from this software without prior written permission. For
   *    written permission, please contact [EMAIL PROTECTED]
   *
   * 5. Products derived from this software may not be called "Apache",
   *    "Apache Maven", nor may "Apache" appear in their name, without
   *    prior written permission of the Apache Software Foundation.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   * ====================================================================
   *
   * This software consists of voluntary contributions made by many
   * individuals on behalf of the Apache Software Foundation.  For more
   * information on the Apache Software Foundation, please see
   * <http://www.apache.org/>.
   */
  
  import java.io.BufferedInputStream;
  import java.io.BufferedOutputStream;
  import java.io.File;
  import java.io.FileOutputStream;
  import java.io.IOException;
  import java.io.InputStream;
  import java.util.Enumeration;
  import java.util.HashMap;
  import java.util.HashSet;
  import java.util.Iterator;
  import java.util.List;
  import java.util.Map;
  import java.util.Set;
  import java.util.jar.JarEntry;
  import java.util.jar.JarFile;
  
  import org.dom4j.Document;
  import org.dom4j.DocumentException;
  import org.dom4j.Node;
  import org.dom4j.io.SAXReader;
  
  /**
   * Represents a J2EE War File
   *
   * @author <a href="mailto:[EMAIL PROTECTED]";>dIon Gillard</a>
   * @version $Id: WarFile.java,v 1.1 2002/05/15 15:02:01 dion Exp $
   */
  public class WarFile extends JarFile
  {
  
      /** web.xml entry in the war */
      public static final String WEB_XML = "WEB-INF/web.xml";
      /** lib entry in the war for jar files */
      public static final String LIB = "WEB-INF/lib/";
      /** 
       * Creates a new instance of WarFile
       * @param name the {@link File file} name of a war file
       * @throws IOException when 
       */
      public WarFile(String name) throws IOException
      {
          super(name);
      }
      
      /** 
       * Creates a new instance of WarFile
       * @param name the {@link File file} name of a war file
       * @param verify whether or not to verify the war file if it is signed
       * @throws IOException when 
       */
      public WarFile(String name, boolean verify) throws IOException
      {
          super(name, verify);
      }
      
      /** 
       * Creates a new instance of WarFile
       * @param warFile a J2EE .war {@link File file}
       * @throws IOException when 
       */
      public WarFile(File warFile) throws IOException
      {
          super(warFile);
      }
  
      /** 
       * Creates a new instance of WarFile
       * @param warFile a J2EE .war {@link File file}
       * @param verify whether or not to verify the war file if it is signed
       * @throws IOException when 
       */
      public WarFile(File warFile, boolean verify) throws IOException
      {
          super(warFile, verify);
      }
  
      /** 
       * Creates a new instance of WarFile
       * @param warFile a J2EE .war {@link File file}
       * @param verify whether or not to verify the war file if it is signed
       * @param mode the mode in which the file is to be opened
       * @throws IOException when 
       */
      public WarFile(File warFile, boolean verify, int mode) throws IOException
      {
          super(warFile, verify, mode);
      }
  
      /**
       * Retrieves the WEB-INF/web.xml entry if it exists.
       * @return a {@link JarEntry} for web.xml
       */
      public JarEntry getWebXmlEntry()
      {
          return getJarEntry(WarFile.WEB_XML);
      }
      
      /**
       * Get a map of servlet name -> servlet class. The map has a size of zero
       * if there are no servlets or no web.xml in the war.
       * @return a map of servlets held in the war.
       * @throws IOException if there are problems reading from the war
       */
      public Map getServlets() throws IOException
      {
          Map servlets = new HashMap();
          if (getWebXmlEntry() != null)
          {
              try 
              {
                  SAXReader xmlReader = new SAXReader(false);
                  InputStream webXmlStream = getInputStream(getWebXmlEntry());
                  Document webXml = xmlReader.read(webXmlStream);
                  List servletNodes = webXml.selectNodes("//servlet");
                  Node node = null;
                  for (Iterator nodes = servletNodes.iterator(); nodes.hasNext();)
                  {
                      node = (Node) nodes.next();
                      String servletName = node.selectSingleNode("./servlet-name")
                          .getText();
                      String servletClass = 
                          node.selectSingleNode("./servlet-class").getText();
                      servlets.put(servletName, servletClass);
                  }
              }
              catch (DocumentException de)
              {
                  de.printStackTrace();
                  throw new IOException(de.getMessage());
              }
          }
          return servlets;
      }
      
      /** Provide a set of jar files as found in WEB-INF/lib
       * @return a set of jar files as {@link JarEntry entries} from WEB-INF/lib
       */
      public Set getLibEntries()
      {
          Set libs = new HashSet();
          Enumeration entries = entries();
          JarEntry entry = null;
          while (entries.hasMoreElements())
          {
              entry = (JarEntry) entries.nextElement();
              if (entry.getName().startsWith("WEB-INF/lib/") &&
                  entry.getName().toLowerCase().endsWith(".jar"))
              { 
                  libs.add(entry);
              }
          }
          return libs;
      }
      
      /** Extract the given {@link JarEntry entry} to a temporary file
       * @return the {@link File} created 
       */
      public File extract(JarEntry entry) throws IOException
      {
          // expand to temp dir and add to list
          File tempFile = File.createTempFile("maven", null);
          // read from jar and write to the tempJar file
          BufferedInputStream inStream = new BufferedInputStream(getInputStream(
              entry));
          BufferedOutputStream outStream = new BufferedOutputStream(
              new FileOutputStream(tempFile));
          int status = -1;
          while ((status = inStream.read()) != -1)
          {
              outStream.write(status);
          }
          outStream.close();
          inStream.close();
          
          return tempFile;
      }
  }
  
  
  

--
To unsubscribe, e-mail:   <mailto:[EMAIL PROTECTED]>
For additional commands, e-mail: <mailto:[EMAIL PROTECTED]>

Reply via email to