diff --git a/org.springframework.core/src/main/java/org/springframework/core/io/AbstractFileResolvingResource.java b/org.springframework.core/src/main/java/org/springframework/core/io/AbstractFileResolvingResource.java new file mode 100644 index 00000000000..0281c641281 --- /dev/null +++ b/org.springframework.core/src/main/java/org/springframework/core/io/AbstractFileResolvingResource.java @@ -0,0 +1,100 @@ +/* + * Copyright 2002-2009 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.core.io; + +import java.io.File; +import java.io.IOException; +import java.net.URI; +import java.net.URL; + +import org.jboss.virtual.VFS; + +import org.springframework.util.ResourceUtils; + +/** + * Abstract base class for resources which resolve URLs into File references, + * such as {@link UrlResource} or {@link ClassPathResource}. + * + *
Detects the "file" protocol as well as the JBoss "vfs" protocol in URLs,
+ * resolving file system references accordingly.
+ *
+ * @author Juergen Hoeller
+ * @since 3.0
+ */
+public abstract class AbstractFileResolvingResource extends AbstractResource {
+
+ /**
+ * This implementation returns a File reference for the underlying class path
+ * resource, provided that it refers to a file in the file system.
+ * @see org.springframework.util.ResourceUtils#getFile(java.net.URL, String)
+ */
+ @Override
+ public File getFile() throws IOException {
+ URL url = getURL();
+ if (url.getProtocol().startsWith(ResourceUtils.URL_PROTOCOL_VFS)) {
+ return VfsResourceDelegate.getResource(url).getFile();
+ }
+ return ResourceUtils.getFile(url, getDescription());
+ }
+
+ /**
+ * This implementation determines the underlying File
+ * (or jar file, in case of a resource in a jar/zip).
+ */
+ @Override
+ protected File getFileForLastModifiedCheck() throws IOException {
+ URL url = getURL();
+ if (ResourceUtils.isJarURL(url)) {
+ URL actualUrl = ResourceUtils.extractJarFileURL(url);
+ if (actualUrl.getProtocol().startsWith(ResourceUtils.URL_PROTOCOL_VFS)) {
+ return VfsResourceDelegate.getResource(actualUrl).getFile();
+ }
+ return ResourceUtils.getFile(actualUrl, "Jar URL");
+ }
+ else {
+ return getFile();
+ }
+ }
+
+ /**
+ * This implementation returns a File reference for the underlying class path
+ * resource, provided that it refers to a file in the file system.
+ * @see org.springframework.util.ResourceUtils#getFile(java.net.URI, String)
+ */
+ protected File getFile(URI uri) throws IOException {
+ if (uri.getScheme().startsWith(ResourceUtils.URL_PROTOCOL_VFS)) {
+ return VfsResourceDelegate.getResource(uri).getFile();
+ }
+ return ResourceUtils.getFile(uri, getDescription());
+ }
+
+
+ /**
+ * Inner delegate class, avoiding a hard JBoss VFS API dependency at runtime.
+ */
+ private static class VfsResourceDelegate {
+
+ public static Resource getResource(URL url) throws IOException {
+ return new VfsResource(VFS.getRoot(url));
+ }
+
+ public static Resource getResource(URI uri) throws IOException {
+ return new VfsResource(VFS.getRoot(uri));
+ }
+ }
+
+}
diff --git a/org.springframework.core/src/main/java/org/springframework/core/io/ClassPathResource.java b/org.springframework.core/src/main/java/org/springframework/core/io/ClassPathResource.java
index 9fffc28f584..b8cce91c877 100644
--- a/org.springframework.core/src/main/java/org/springframework/core/io/ClassPathResource.java
+++ b/org.springframework.core/src/main/java/org/springframework/core/io/ClassPathResource.java
@@ -16,7 +16,6 @@
package org.springframework.core.io;
-import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
@@ -25,9 +24,7 @@ import java.net.URL;
import org.springframework.util.Assert;
import org.springframework.util.ClassUtils;
import org.springframework.util.ObjectUtils;
-import org.springframework.util.ResourceUtils;
import org.springframework.util.StringUtils;
-import org.springframework.core.io.support.ResourceHandlingUtils;
/**
* {@link Resource} implementation for class path resources.
@@ -42,7 +39,7 @@ import org.springframework.core.io.support.ResourceHandlingUtils;
* @see java.lang.ClassLoader#getResourceAsStream(String)
* @see java.lang.Class#getResourceAsStream(String)
*/
-public class ClassPathResource extends AbstractResource {
+public class ClassPathResource extends AbstractFileResolvingResource {
private final String path;
@@ -50,6 +47,7 @@ public class ClassPathResource extends AbstractResource {
private Class clazz;
+
/**
* Create a new ClassPathResource for ClassLoader usage.
* A leading slash will be removed, as the ClassLoader
@@ -167,32 +165,6 @@ public class ClassPathResource extends AbstractResource {
return url;
}
- /**
- * This implementation returns a File reference for the underlying class path
- * resource, provided that it refers to a file in the file system.
- * @see org.springframework.util.ResourceUtils#getFile(java.net.URL, String)
- */
- @Override
- public File getFile() throws IOException {
- return ResourceHandlingUtils.getFile(getURL(), getDescription());
- }
-
- /**
- * This implementation determines the underlying File
- * (or jar file, in case of a resource in a jar/zip).
- */
- @Override
- protected File getFileForLastModifiedCheck() throws IOException {
- URL url = getURL();
- if (ResourceUtils.isJarURL(url)) {
- URL actualUrl = ResourceUtils.extractJarFileURL(url);
- return ResourceHandlingUtils.getFile(actualUrl);
- }
- else {
- return ResourceHandlingUtils.getFile(url, getDescription());
- }
- }
-
/**
* This implementation creates a ClassPathResource, applying the given path
* relative to the path of the underlying resource of this descriptor.
diff --git a/org.springframework.core/src/main/java/org/springframework/core/io/UrlResource.java b/org.springframework.core/src/main/java/org/springframework/core/io/UrlResource.java
index 2e02b20e592..a68e919c66a 100644
--- a/org.springframework.core/src/main/java/org/springframework/core/io/UrlResource.java
+++ b/org.springframework.core/src/main/java/org/springframework/core/io/UrlResource.java
@@ -26,9 +26,7 @@ import java.net.URL;
import java.net.URLConnection;
import org.springframework.util.Assert;
-import org.springframework.util.ResourceUtils;
import org.springframework.util.StringUtils;
-import org.springframework.core.io.support.ResourceHandlingUtils;
/**
* {@link Resource} implementation for java.net.URL locators.
@@ -39,7 +37,7 @@ import org.springframework.core.io.support.ResourceHandlingUtils;
* @since 28.12.2003
* @see java.net.URL
*/
-public class UrlResource extends AbstractResource {
+public class UrlResource extends AbstractFileResolvingResource {
/**
* Original URL, used for actual access.
@@ -164,25 +162,10 @@ public class UrlResource extends AbstractResource {
@Override
public File getFile() throws IOException {
if (this.uri != null) {
- return ResourceHandlingUtils.getFile(this.uri, getDescription());
+ return super.getFile(this.uri);
}
else {
- return ResourceHandlingUtils.getFile(this.url, getDescription());
- }
- }
-
- /**
- * This implementation determines the underlying File
- * (or jar file, in case of a resource in a jar/zip).
- */
- @Override
- protected File getFileForLastModifiedCheck() throws IOException {
- if (ResourceUtils.isJarURL(this.url)) {
- URL actualUrl = ResourceUtils.extractJarFileURL(this.url);
- return ResourceHandlingUtils.getFile(actualUrl);
- }
- else {
- return getFile();
+ return super.getFile();
}
}
diff --git a/org.springframework.core/src/main/java/org/springframework/core/io/support/jboss/VfsResource.java b/org.springframework.core/src/main/java/org/springframework/core/io/VfsResource.java
similarity index 55%
rename from org.springframework.core/src/main/java/org/springframework/core/io/support/jboss/VfsResource.java
rename to org.springframework.core/src/main/java/org/springframework/core/io/VfsResource.java
index 6d9cae5b38b..8f542397989 100644
--- a/org.springframework.core/src/main/java/org/springframework/core/io/support/jboss/VfsResource.java
+++ b/org.springframework.core/src/main/java/org/springframework/core/io/VfsResource.java
@@ -14,105 +14,93 @@
* limitations under the License.
*/
-package org.springframework.core.io.support.jboss;
+package org.springframework.core.io;
-import java.io.IOException;
import java.io.File;
+import java.io.IOException;
import java.io.InputStream;
-import java.net.URL;
-import java.net.URISyntaxException;
import java.net.URI;
+import java.net.URL;
-import org.jboss.virtual.VirtualFile;
-import org.jboss.virtual.VFSUtils;
import org.jboss.virtual.VFS;
+import org.jboss.virtual.VFSUtils;
+import org.jboss.virtual.VirtualFile;
-import org.springframework.core.io.Resource;
-import org.springframework.core.io.AbstractResource;
+import org.springframework.core.NestedIOException;
import org.springframework.util.Assert;
/**
- * VFS based Resource.
+ * VFS based {@link Resource} implementation.
*
* @author Ales Justin
+ * @author Juergen Hoeller
+ * @since 3.0
+ * @see org.jboss.virtual.VirtualFile
*/
-class VfsResource extends AbstractResource {
+public class VfsResource extends AbstractResource {
+
+ private final VirtualFile file;
- private VirtualFile file;
public VfsResource(VirtualFile file) {
- Assert.notNull(file, "The file cannot be null.");
+ Assert.notNull(file, "VirtualFile must not be null");
this.file = file;
}
+
public boolean exists() {
try {
- return file.exists();
+ return this.file.exists();
}
- catch (IOException e) {
- throw new RuntimeException(e);
+ catch (IOException ex) {
+ return false;
}
}
- public boolean isOpen() {
- return false;
- }
-
public boolean isReadable() {
try {
- return file.getSize() > 0;
+ return (this.file.getSize() > 0);
}
catch (IOException e) {
- throw new RuntimeException(e);
+ return false;
}
}
- public long lastModified() {
- try {
- return file.getLastModified();
- }
- catch (IOException e) {
- throw new RuntimeException(e);
- }
+ public long lastModified() throws IOException {
+ return this.file.getLastModified();
+ }
+
+ public InputStream getInputStream() throws IOException {
+ return this.file.openStream();
}
public URL getURL() throws IOException {
try {
- return file.toURL();
+ return this.file.toURL();
}
- catch (URISyntaxException e) {
- IOException ioe = new IOException(e.getMessage());
- ioe.initCause(e);
- throw ioe;
+ catch (Exception ex) {
+ throw new NestedIOException("Failed to obtain URL for file " + this.file, ex);
}
}
public URI getURI() throws IOException {
try {
- return file.toURI();
+ return this.file.toURI();
}
- catch (URISyntaxException e) {
- IOException ioe = new IOException(e.getMessage());
- ioe.initCause(e);
- throw ioe;
+ catch (Exception ex) {
+ throw new NestedIOException("Failed to obtain URI for " + this.file, ex);
}
}
public File getFile() throws IOException {
- if (VFSUtils.isNestedFile(file)) {
- throw new IOException("This resource is a nested resource: " + file);
+ if (VFSUtils.isNestedFile(this.file)) {
+ throw new IOException("File resolution not supported for nested resource: " + this.file);
}
-
try {
return new File(VFSUtils.getCompatibleURI(file));
}
- catch (IOException e) {
- throw e;
- }
- catch (Exception e) {
- IOException ioe = new IOException(e.getMessage());
- ioe.initCause(e);
- throw ioe;
+ catch (Exception ex) {
+ throw new NestedIOException("Failed to obtain File reference for " + this.file, ex);
}
}
@@ -121,33 +109,22 @@ class VfsResource extends AbstractResource {
}
public String getFilename() {
- return file.getName();
+ return this.file.getName();
}
public String getDescription() {
- return file.toString();
+ return this.file.toString();
}
- public InputStream getInputStream() throws IOException {
- return file.openStream();
- }
-
- public String toString() {
- return getDescription();
- }
@Override
public boolean equals(Object obj) {
- if (obj instanceof VfsResource) {
- return file.equals(((VfsResource)obj).file);
- }
- else {
- return false;
- }
+ return (obj == this || (obj instanceof VfsResource && this.file.equals(((VfsResource) obj).file)));
}
@Override
public int hashCode() {
return this.file.hashCode();
}
+
}
diff --git a/org.springframework.core/src/main/java/org/springframework/core/io/support/PathMatchingResourcePatternResolver.java b/org.springframework.core/src/main/java/org/springframework/core/io/support/PathMatchingResourcePatternResolver.java
index d53233a1e13..642c3317d7b 100644
--- a/org.springframework.core/src/main/java/org/springframework/core/io/support/PathMatchingResourcePatternResolver.java
+++ b/org.springframework.core/src/main/java/org/springframework/core/io/support/PathMatchingResourcePatternResolver.java
@@ -32,12 +32,17 @@ import java.util.jar.JarFile;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
+import org.jboss.virtual.VFS;
+import org.jboss.virtual.VirtualFile;
+import org.jboss.virtual.VirtualFileVisitor;
+import org.jboss.virtual.VisitorAttributes;
import org.springframework.core.io.DefaultResourceLoader;
import org.springframework.core.io.FileSystemResource;
import org.springframework.core.io.Resource;
import org.springframework.core.io.ResourceLoader;
import org.springframework.core.io.UrlResource;
+import org.springframework.core.io.VfsResource;
import org.springframework.util.AntPathMatcher;
import org.springframework.util.Assert;
import org.springframework.util.PathMatcher;
@@ -335,11 +340,12 @@ public class PathMatchingResourcePatternResolver implements ResourcePatternResol
Resource[] rootDirResources = getResources(rootDirPath);
Set