Author: fhanik
Date: Mon Aug 20 07:25:14 2007
New Revision: 567714

URL: http://svn.apache.org/viewvc?rev=567714&view=rev
Log:
improved upon the existing virtualwebapploader,
new feature: can configure the path separator
new feature: can create a local repository for runtime
new feature: jar files are added as addJar to prevent locking of files


Modified:
    tomcat/trunk/java/org/apache/catalina/loader/VirtualWebappLoader.java

Modified: tomcat/trunk/java/org/apache/catalina/loader/VirtualWebappLoader.java
URL: 
http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/catalina/loader/VirtualWebappLoader.java?rev=567714&r1=567713&r2=567714&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/catalina/loader/VirtualWebappLoader.java 
(original)
+++ tomcat/trunk/java/org/apache/catalina/loader/VirtualWebappLoader.java Mon 
Aug 20 07:25:14 2007
@@ -17,9 +17,14 @@
 package org.apache.catalina.loader;
 
 import java.io.File;
+import java.util.ArrayList;
 import java.util.StringTokenizer;
+import java.util.jar.JarFile;
 
 import org.apache.catalina.LifecycleException;
+import org.apache.catalina.startup.ExpandWar;
+import org.apache.juli.logging.Log;
+import org.apache.juli.logging.LogFactory;
 
 /**
  * Simple webapp classloader that allows a customized classpath to be added
@@ -27,11 +32,22 @@
  * added to the default webapp classpath, making easy to emulate a standard
  * webapp without the need for assembly all the webapp dependencies as jars in
  * WEB-INF/lib.
+ * 
+ * The VirtualWebappLoader will add directories and regular files as 
org.apache.catalina.Loader.addRepository
+ * Jar files, or files ending with .jar, file be added as 
org.apache.catalina.loader.WebappClassLoader.addJar
+ * 
+ * If the attribute makeLocalCopy is set to true, the VirtualWebappLoader will 
make a local copy of the 
+ * virtual class path into the java.io.tmpdir directory, so that webapps can 
point to the same master repository,
+ * but be kept separate during runtime.
+ * 
+ * The separator for the virtualClasspath defaulted to ; but can be configured 
using the separator attribute
  *
  * <code>
  * &lt;Context docBase="\webapps\mydocbase">
  *   &lt;Loader className="org.apache.catalina.loader.VirtualWebappLoader"
- *              virtualClasspath="\dir\classes;\somedir\somejar.jar"/>
+ *              virtualClasspath="\dir\classes:\somedir\somejar.jar"
+ *              makeLocalCopy="true"
+ *              separator=":"/>
  * &lt;/Context>
  * </code>
  *
@@ -42,17 +58,33 @@
  *
  *
  *
+ * @author Filip Hanik
  * @author Fabrizio Giustina
  * @version $Id: $
  */
 public class VirtualWebappLoader extends WebappLoader {
 
+    public static final Log log = LogFactory.getLog(VirtualWebappLoader.class);
     /**
      * <code>;</code> separated list of additional path elements.
      */
     private String virtualClasspath = "";
 
     /**
+     * Should we make a copy of the libraries upon startup
+     */
+    protected boolean makeLocalCopy = false;
+    
+    /**
+     * The location of the libraries.
+     */
+    protected File tempDir = null;
+    
+    /**
+     * The path seperator
+     */
+    protected String separator = ";";
+    /**
      * Construct a new WebappLoader with no defined parent class loader (so 
that
      * the actual parent will be the system class loader).
      */
@@ -80,11 +112,36 @@
         virtualClasspath = path;
     }
 
+    public void setMakeLocalCopy(boolean makeLocalCopy) {
+        this.makeLocalCopy = makeLocalCopy;
+    }
+
+    public void setSeparator(String separator) {
+        this.separator = separator;
+    }
+
     @Override
     public void start() throws LifecycleException {
+        if (log.isInfoEnabled()) log.info("Starting VirtualWebappLoader 
for:"+getContainer().getName());
+        ArrayList<String> jarFiles = new ArrayList<String>();
+        
         // just add any jar/directory set in virtual classpath to the
         // repositories list before calling start on the standard WebappLoader
-        StringTokenizer tkn = new StringTokenizer(virtualClasspath, ";");
+        if (makeLocalCopy) {
+            tempDir = new File(System.getProperty("java.io.tmpdir"), 
"VirtualWebappLoader-"+System.identityHashCode(this));
+            if (log.isDebugEnabled()) log.debug("Creating temporary directory 
for virtual classpath:"+tempDir.getAbsolutePath());
+            if (tempDir.exists()) {
+                if (log.isDebugEnabled()) log.debug("Temporary directory 
exists, will clean out the old one.");
+                boolean result = false;
+                if (tempDir.isDirectory())
+                    result = ExpandWar.deleteDir(tempDir);
+                else
+                    result = ExpandWar.delete(tempDir);
+                if (!result) throw new LifecycleException("Unable to create 
temp dir for virtual app loader:"+tempDir.getAbsolutePath());
+            }
+            tempDir.mkdirs();
+        }
+        StringTokenizer tkn = new StringTokenizer(virtualClasspath, separator);
         while (tkn!=null && tkn.hasMoreTokens()) {
             String ftkn = tkn.nextToken();
             if (ftkn==null) continue;
@@ -92,14 +149,60 @@
             if (!file.exists()) {
                 continue;
             }
-            if (file.isDirectory()) {
-                addRepository("file:/" + file.getAbsolutePath() + "/");
+            File tmpFile = file;
+            if (makeLocalCopy) {
+                tmpFile = new File(tempDir, file.getName());
+                if (log.isDebugEnabled()) log.debug("Creating local 
copy:"+tmpFile.getAbsolutePath());
+                if (!ExpandWar.copy(file, tmpFile)) throw new 
LifecycleException("Unable to copy resources:"+file.getAbsolutePath());
+            }
+            if (tmpFile.isDirectory()) {
+                if (log.isDebugEnabled()) log.debug("Adding directory to 
virtual repo:"+tmpFile.getAbsolutePath());
+                addRepository("file:/" + tmpFile.getAbsolutePath() + "/");
+            } else if (tmpFile.getAbsolutePath().endsWith(".jar")) {
+                //addRepository("file:/" + tmpFile.getAbsolutePath());
+                jarFiles.add(tmpFile.getAbsolutePath());
             } else {
-                addRepository("file:/" + file.getAbsolutePath());
+                if (log.isDebugEnabled()) log.debug("Adding file to virtual 
repo:"+tmpFile.getAbsolutePath());
+                addRepository("file:/" + tmpFile.getAbsolutePath());
             }
         }
-
+        
+        if (log.isDebugEnabled()) log.debug("Starting parent WebappLoader");
         super.start();
+        
+        
+        //add JarFiles to the classloader, we can't do that before we start
+        //since there is no classloader during that time
+        ClassLoader loader = super.getClassLoader();
+        if ( loader instanceof WebappClassLoader) {
+            WebappClassLoader wloader = (WebappClassLoader)loader;
+            for (int i = 0; i < jarFiles.size(); i++) {
+                String filename = jarFiles.get(i);
+                File file = new File(filename);
+                try {
+                    JarFile jfile = new JarFile(file);
+                    if (log.isDebugEnabled()) log.debug("Adding virtual jar 
file to classloader:"+filename);
+                    wloader.addJar(filename,jfile,file);
+                }catch ( Exception iox) {
+                    if (log.isDebugEnabled()) log.debug("",iox);
+                }
+            }
+        }        
+    }
+    
+    @Override
+    public void stop() throws LifecycleException {
+        super.stop();
+        boolean result = true;
+        if ( tempDir!=null ) result = ExpandWar.deleteDir(tempDir);
+        if (!result) log.info("Unable to delete temporary 
directory:"+tempDir.getAbsolutePath());
     }
 
+    public boolean getMakeLocalCopy() {
+        return makeLocalCopy;
+    }
+
+    public String getSeparator() {
+        return separator;
+    }
 }



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

Reply via email to