From 8913557e8817c4c8b039a4908b4aff30f557db86 Mon Sep 17 00:00:00 2001 From: Greg Wilkins Date: Thu, 6 Aug 2009 12:30:24 +0000 Subject: [PATCH] Improved handling of overlays and resourceCollections git-svn-id: svn+ssh://dev.eclipse.org/svnroot/rt/org.eclipse.jetty/jetty/trunk@652 7e9141cc-0065-0410-87d8-b60c137991c4 --- .../jetty/util/resource/BadResource.java | 8 +++++ .../jetty/util/resource/FileResource.java | 19 ++++++++++ .../jetty/util/resource/JarResource.java | 36 +++++++++++-------- .../eclipse/jetty/util/resource/Resource.java | 10 +++++- .../util/resource/ResourceCollection.java | 14 +++++++- .../util/resource/ResourceCollectionTest.java | 31 ++++++++++++++-- .../jetty/webapp/WebInfConfiguration.java | 33 +++++++++-------- 7 files changed, 119 insertions(+), 32 deletions(-) diff --git a/jetty-util/src/main/java/org/eclipse/jetty/util/resource/BadResource.java b/jetty-util/src/main/java/org/eclipse/jetty/util/resource/BadResource.java index cc36d7ebaf3..be88e931663 100644 --- a/jetty-util/src/main/java/org/eclipse/jetty/util/resource/BadResource.java +++ b/jetty-util/src/main/java/org/eclipse/jetty/util/resource/BadResource.java @@ -105,6 +105,14 @@ class BadResource extends URLResource return null; } + /* ------------------------------------------------------------ */ + @Override + public void copyTo(File destination) + throws IOException + { + throw new SecurityException(_message); + } + /* ------------------------------------------------------------ */ public String toString() { diff --git a/jetty-util/src/main/java/org/eclipse/jetty/util/resource/FileResource.java b/jetty-util/src/main/java/org/eclipse/jetty/util/resource/FileResource.java index 5a225d8bb7b..b0afb0507d8 100644 --- a/jetty-util/src/main/java/org/eclipse/jetty/util/resource/FileResource.java +++ b/jetty-util/src/main/java/org/eclipse/jetty/util/resource/FileResource.java @@ -25,6 +25,7 @@ import java.net.URL; import java.net.URLConnection; import java.security.Permission; +import org.eclipse.jetty.util.IO; import org.eclipse.jetty.util.URIUtil; import org.eclipse.jetty.util.log.Log; @@ -347,8 +348,26 @@ public class FileResource extends URLResource /** * @return the hashcode. */ + @Override public int hashCode() { return null == _file ? super.hashCode() : _file.hashCode(); } + + /* ------------------------------------------------------------ */ + @Override + public void copyTo(File destination) + throws IOException + { + if (isDirectory()) + { + IO.copyDir(getFile(),destination); + } + else + { + if (destination.exists()) + throw new IllegalArgumentException(destination+" exists"); + IO.copy(getFile(),destination); + } + } } diff --git a/jetty-util/src/main/java/org/eclipse/jetty/util/resource/JarResource.java b/jetty-util/src/main/java/org/eclipse/jetty/util/resource/JarResource.java index 21b664cae35..b8802c2e2e7 100644 --- a/jetty-util/src/main/java/org/eclipse/jetty/util/resource/JarResource.java +++ b/jetty-util/src/main/java/org/eclipse/jetty/util/resource/JarResource.java @@ -113,15 +113,25 @@ public class JarResource extends URLResource InputStream is = url.openStream(); return is; } - + /* ------------------------------------------------------------ */ - public static void extract(Resource resource, File directory, boolean deleteOnExit) + @Deprecated + public void extract(File dest, boolean deleteOnExit) throws IOException { - if(Log.isDebugEnabled())Log.debug("Extract "+resource+" to "+directory); + if (deleteOnExit) + dest.deleteOnExit(); + copyTo(dest); + } + + /* ------------------------------------------------------------ */ + @Override + public void copyTo(File directory) + throws IOException + { + if(Log.isDebugEnabled())Log.debug("Extract "+this+" to "+directory); - - String urlString = resource.getURL().toExternalForm().trim(); + String urlString = this.getURL().toExternalForm().trim(); int endOfJarUrl = urlString.indexOf("!/"); int startOfJarUrl = (endOfJarUrl >= 0?4:0); @@ -213,8 +223,6 @@ public class JarResource extends URLResource if (entry.getTime()>=0) file.setLastModified(entry.getTime()); } - if (deleteOnExit) - file.deleteOnExit(); } if ((subEntryName == null) || (subEntryName != null && subEntryName.equalsIgnoreCase("META-INF/MANIFEST.MF"))) @@ -231,12 +239,12 @@ public class JarResource extends URLResource } } IO.close(jin); - } - - /* ------------------------------------------------------------ */ - public void extract(File directory, boolean deleteOnExit) - throws IOException - { - extract(this,directory,deleteOnExit); } + + public static Resource newJarResource(Resource resource) throws IOException + { + if (resource instanceof JarResource) + return resource; + return Resource.newResource("jar:" + resource + "!/"); + } } diff --git a/jetty-util/src/main/java/org/eclipse/jetty/util/resource/Resource.java b/jetty-util/src/main/java/org/eclipse/jetty/util/resource/Resource.java index 3573a29b623..74d5e427ab9 100644 --- a/jetty-util/src/main/java/org/eclipse/jetty/util/resource/Resource.java +++ b/jetty-util/src/main/java/org/eclipse/jetty/util/resource/Resource.java @@ -13,6 +13,7 @@ package org.eclipse.jetty.util.resource; import java.io.File; +import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; @@ -609,6 +610,13 @@ public abstract class Resource implements Serializable } } - + /* ------------------------------------------------------------ */ + public void copyTo(File destination) + throws IOException + { + if (destination.exists()) + throw new IllegalArgumentException(destination+" exists"); + writeTo(new FileOutputStream(destination),0,-1); + } } diff --git a/jetty-util/src/main/java/org/eclipse/jetty/util/resource/ResourceCollection.java b/jetty-util/src/main/java/org/eclipse/jetty/util/resource/ResourceCollection.java index 7f5a6bb072a..27d9bdb27c6 100644 --- a/jetty-util/src/main/java/org/eclipse/jetty/util/resource/ResourceCollection.java +++ b/jetty-util/src/main/java/org/eclipse/jetty/util/resource/ResourceCollection.java @@ -422,15 +422,26 @@ public class ResourceCollection extends Resource } /* ------------------------------------------------------------ */ + @Override public boolean renameTo(Resource dest) throws SecurityException { throw new UnsupportedOperationException(); } + + /* ------------------------------------------------------------ */ + @Override + public void copyTo(File destination) + throws IOException + { + for (int r=_resources.length;r-->0;) + _resources[r].copyTo(destination); + } /* ------------------------------------------------------------ */ /** * @return the list of resources separated by a path separator */ + @Override public String toString() { if(_resources==null) @@ -442,7 +453,8 @@ public class ResourceCollection extends Resource return buffer.toString(); } - + /* ------------------------------------------------------------ */ + @Override public boolean isContainedIn(Resource r) throws MalformedURLException { // TODO could look at implementing the semantic of is this collection a subset of the Resource r? diff --git a/jetty-util/src/test/java/org/eclipse/jetty/util/resource/ResourceCollectionTest.java b/jetty-util/src/test/java/org/eclipse/jetty/util/resource/ResourceCollectionTest.java index be6fb1c32bb..9317e51c39a 100644 --- a/jetty-util/src/test/java/org/eclipse/jetty/util/resource/ResourceCollectionTest.java +++ b/jetty-util/src/test/java/org/eclipse/jetty/util/resource/ResourceCollectionTest.java @@ -14,6 +14,7 @@ package org.eclipse.jetty.util.resource; import java.io.BufferedReader; +import java.io.File; import java.io.InputStreamReader; import junit.framework.TestCase; @@ -62,11 +63,37 @@ public class ResourceCollectionTest extends TestCase assertEquals("3 - three", getContent(rc, "3.txt")); } - static String getContent(ResourceCollection rc, String path) throws Exception + public void testCopyTo() throws Exception + { + ResourceCollection rc = new ResourceCollection(new String[]{ + "src/test/resources/org/eclipse/jetty/util/resource/one/", + "src/test/resources/org/eclipse/jetty/util/resource/two/", + "src/test/resources/org/eclipse/jetty/util/resource/three/" + }); + + File dest = File.createTempFile("copyto",null); + if (dest.exists()) + dest.delete(); + dest.mkdir(); + dest.deleteOnExit(); + rc.copyTo(dest); + + Resource r = Resource.newResource(dest.toURI()); + assertEquals("1 - one", getContent(r, "1.txt")); + assertEquals("2 - two", getContent(r, "2.txt")); + assertEquals("3 - three", getContent(r, "3.txt")); + r = r.addPath("dir"); + assertEquals("1 - one", getContent(r, "1.txt")); + assertEquals("2 - two", getContent(r, "2.txt")); + assertEquals("3 - three", getContent(r, "3.txt")); + + } + + static String getContent(Resource r, String path) throws Exception { StringBuilder buffer = new StringBuilder(); String line = null; - BufferedReader br = new BufferedReader(new InputStreamReader(rc.addPath(path).getURL().openStream())); + BufferedReader br = new BufferedReader(new InputStreamReader(r.addPath(path).getURL().openStream())); while((line=br.readLine())!=null) buffer.append(line); br.close(); diff --git a/jetty-webapp/src/main/java/org/eclipse/jetty/webapp/WebInfConfiguration.java b/jetty-webapp/src/main/java/org/eclipse/jetty/webapp/WebInfConfiguration.java index 2148b5c9d67..19e54bd22bc 100644 --- a/jetty-webapp/src/main/java/org/eclipse/jetty/webapp/WebInfConfiguration.java +++ b/jetty-webapp/src/main/java/org/eclipse/jetty/webapp/WebInfConfiguration.java @@ -357,14 +357,14 @@ public class WebInfConfiguration implements Configuration public void unpack (WebAppContext context) throws IOException { Resource web_app = context.getBaseResource(); + if (web_app == null) { String war = context.getWar(); - if (war==null || war.length()==0) - war=context.getResourceBase(); - - // Set dir or WAR - web_app = context.newResource(war); + if (war!=null && war.length()>0) + web_app = context.newResource(war); + else + web_app=context.getBaseResource(); // Accept aliases for WAR files if (web_app.getAlias() != null) @@ -380,7 +380,7 @@ public class WebInfConfiguration implements Configuration if (web_app.exists() && !web_app.isDirectory() && !web_app.toString().startsWith("jar:")) { // No - then lets see if it can be turned into a jar URL. - Resource jarWebApp = context.newResource("jar:" + web_app + "!/"); + Resource jarWebApp = JarResource.newJarResource(web_app); if (jarWebApp.exists() && jarWebApp.isDirectory()) web_app= jarWebApp; } @@ -399,8 +399,8 @@ public class WebInfConfiguration implements Configuration if (web_app.getFile()!=null && web_app.getFile().isDirectory()) { // Copy directory - Log.info("Copy " + web_app.getFile() + " to " + extractedWebAppDir); - IO.copyDir(web_app.getFile(),extractedWebAppDir); + Log.info("Copy " + web_app + " to " + extractedWebAppDir); + web_app.copyTo(extractedWebAppDir); } else { @@ -408,8 +408,9 @@ public class WebInfConfiguration implements Configuration { //it hasn't been extracted before so extract it extractedWebAppDir.mkdir(); - Log.info("Extract " + war + " to " + extractedWebAppDir); - JarResource.extract(web_app, extractedWebAppDir, false); + Log.info("Extract " + web_app + " to " + extractedWebAppDir); + Resource jar_web_app = JarResource.newJarResource(web_app); + jar_web_app.copyTo(extractedWebAppDir); } else { @@ -418,8 +419,9 @@ public class WebInfConfiguration implements Configuration { extractedWebAppDir.delete(); extractedWebAppDir.mkdir(); - Log.info("Extract " + war + " to " + extractedWebAppDir); - JarResource.extract(web_app, extractedWebAppDir, false); + Log.info("Extract " + web_app + " to " + extractedWebAppDir); + Resource jar_web_app = JarResource.newJarResource(web_app); + jar_web_app.copyTo(extractedWebAppDir); } } } @@ -442,7 +444,10 @@ public class WebInfConfiguration implements Configuration // Do we need to extract WEB-INF/lib? Resource web_inf= web_app.addPath("WEB-INF/"); - if (web_inf.exists() && web_inf.isDirectory() && (web_inf.getFile()==null || !web_inf.getFile().isDirectory())) + if (web_inf instanceof ResourceCollection || + web_inf.exists() && + web_inf.isDirectory() && + (web_inf.getFile()==null || !web_inf.getFile().isDirectory())) { File extractedWebInfDir= new File(context.getTempDirectory(), "webinf"); if (extractedWebInfDir.exists()) @@ -451,7 +456,7 @@ public class WebInfConfiguration implements Configuration File webInfDir=new File(extractedWebInfDir,"WEB-INF"); webInfDir.mkdir(); Log.info("Extract " + web_inf + " to " + webInfDir); - JarResource.extract(web_inf, webInfDir, false); + web_inf.copyTo(webInfDir); web_inf=Resource.newResource(extractedWebInfDir.toURL()); ResourceCollection rc = new ResourceCollection(new Resource[]{web_inf,web_app}); context.setBaseResource(rc);