http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/b56817f7/dormant/core/src/main/java/org/apache/tamaya/core/internal/resources/io/DefaultResourceLoader.java ---------------------------------------------------------------------- diff --git a/dormant/core/src/main/java/org/apache/tamaya/core/internal/resources/io/DefaultResourceLoader.java b/dormant/core/src/main/java/org/apache/tamaya/core/internal/resources/io/DefaultResourceLoader.java deleted file mode 100644 index d8fa274..0000000 --- a/dormant/core/src/main/java/org/apache/tamaya/core/internal/resources/io/DefaultResourceLoader.java +++ /dev/null @@ -1,138 +0,0 @@ -/* - * Copyright 2002-2014 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.apache.tamaya.core.internal.resources.io; - -import org.apache.tamaya.core.resource.Resource; - -import java.net.MalformedURLException; -import java.net.URL; -import java.util.Objects; - -/** - * <p>Will return a {@code UrlResource} if the location keys is a URL, - * and a {@code ClassPathResource} if it is a non-URL path or a - * "classpath:" pseudo-URL. - * - * @author Juergen Hoeller - * @since 10.03.2004 - */ -class DefaultResourceLoader { - - /** Pseudo URL prefix for loading from the class path: "classpath:" */ - public static final String CLASSPATH_URL_PREFIX = "classpath:"; - - private ClassLoader classLoader; - - - /** - * Create a new DefaultResourceLoader. - * <p>ClassLoader access will happen using the thread context class loader - * at the time current this ResourceLoader's initialization. - * @see java.lang.Thread#getContextClassLoader() - */ - public DefaultResourceLoader() { - this.classLoader = ClassUtils.getDefaultClassLoader(); - } - - /** - * Create a new DefaultResourceLoader. - * @param classLoader the ClassLoader to load class path resources with, or {@code null} - * for using the thread context class loader at the time current actual resource access - */ - public DefaultResourceLoader(ClassLoader classLoader) { - this.classLoader = classLoader; - } - - - /** - * Specify the ClassLoader to load class path resources with, or {@code null} - * for using the thread context class loader at the time current actual resource access. - * <p>The default is that ClassLoader access will happen using the thread context - * class loader at the time current this ResourceLoader's initialization. - */ - void setClassLoader(ClassLoader classLoader) { - this.classLoader = classLoader; - } - - /** - * Return the ClassLoader to load class path resources with. - * <p>Will get passed to ClassPathResource's constructor for all - * ClassPathResource objects created by this resource loader. - * @see ClassPathResource - */ - public ClassLoader getClassLoader() { - return (this.classLoader != null ? this.classLoader : ClassUtils.getDefaultClassLoader()); - } - - - public Resource getResource(String location) { - Objects.requireNonNull(location, "Location must not be null"); - if (location.startsWith("/")) { - return getResourceByPath(location); - } - else if (location.startsWith(CLASSPATH_URL_PREFIX)) { - return new ClassPathResource(location.substring(CLASSPATH_URL_PREFIX.length()), getClassLoader()); - } - else { - try { - // Try to parse the location as a URL... - URL url = new URL(location); - return new UrlResource(url); - } - catch (MalformedURLException ex) { - // No URL -> resolve as resource path. - return getResourceByPath(location); - } - } - } - - /** - * Return a Resource handle for the resource at the given path. - * <p>The default implementation supports class path locations. This should - * be appropriate for standalone implementations but can be overridden, - * e.g. for implementations targeted at a Servlet container. - * @param path the path to the resource - * @return the corresponding Resource handle - * @see ClassPathResource - */ - protected Resource getResourceByPath(String path) { - return new ClassPathContextResource(path, getClassLoader()); - } - - - /** - * ClassPathResource that explicitly expresses a context-relative path - * through implementing the ContextResource interface. - */ - protected static class ClassPathContextResource extends ClassPathResource { - - public ClassPathContextResource(String path, ClassLoader classLoader) { - super(path, classLoader); - } - - public String getPathWithinContext() { - return getPath(); - } - - @Override - public Resource createRelative(String relativePath) { - String pathToUse = StringUtils.applyRelativePath(getPath(), relativePath); - return new ClassPathContextResource(pathToUse, getClassLoader()); - } - } - -}
http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/b56817f7/dormant/core/src/main/java/org/apache/tamaya/core/internal/resources/io/FileSystemResource.java ---------------------------------------------------------------------- diff --git a/dormant/core/src/main/java/org/apache/tamaya/core/internal/resources/io/FileSystemResource.java b/dormant/core/src/main/java/org/apache/tamaya/core/internal/resources/io/FileSystemResource.java deleted file mode 100644 index dd466f4..0000000 --- a/dormant/core/src/main/java/org/apache/tamaya/core/internal/resources/io/FileSystemResource.java +++ /dev/null @@ -1,220 +0,0 @@ -/* - * Copyright 2002-2014 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.apache.tamaya.core.internal.resources.io; - -import org.apache.tamaya.core.resource.Resource; - -import java.io.File; -import java.io.FileInputStream; -import java.io.FileOutputStream; -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; -import java.net.URI; -import java.net.URL; -import java.util.Objects; - -/** - * {@link org.apache.tamaya.core.resource.Resource} implementation for {@code java.io.File} handles. - * Obviously supports resolution as File, and also as URL. - * - * @author Juergen Hoeller - * @since 28.12.2003 - * @see java.io.File - */ -public class FileSystemResource extends AbstractResource { - - private final File file; - - private final String path; - - - /** - * Create a new {@code FileSystemResource} from a {@link File} handle. - * <p>Note: When building relative resources via {@link #createRelative}, - * the relative path will applyChanges <i>at the same directory level</i>: - * e.g. new File("C:/dir1"), relative path "dir2" -> "C:/dir2"! - * If you prefer to have relative paths built underneath the given root - * directory, use the {@link #FileSystemResource(String) constructor with a file path} - * to append a trailing slash to the root path: "C:/dir1/", which - * indicates this directory as root for all relative paths. - * @param file a File handle - */ - public FileSystemResource(File file) { - Objects.requireNonNull(file, "File must not be null"); - this.file = file; - this.path = StringUtils.cleanPath(file.getPath()); - } - - /** - * Create a new {@code FileSystemResource} from a file path. - * <p>Note: When building relative resources via {@link #createRelative}, - * it makes a difference whether the specified resource base path here - * ends with a slash or not. In the case current "C:/dir1/", relative paths - * will be built underneath that root: e.g. relative path "dir2" -> - * "C:/dir1/dir2". In the case current "C:/dir1", relative paths will applyChanges - * at the same directory level: relative path "dir2" -> "C:/dir2". - * @param path a file path - */ - public FileSystemResource(String path) { - Objects.requireNonNull(path, "Path must not be null"); - this.file = new File(path); - this.path = StringUtils.cleanPath(path); - } - - - /** - * Return the file path for this resource. - */ - public final String getPath() { - return this.path; - } - - - /** - * This implementation returns whether the underlying file exists. - * @see java.io.File#exists() - */ - @Override - public boolean exists() { - return this.file.exists(); - } - - /** - * This implementation checks whether the underlying file is marked as readable - * (and corresponds to an actual file with content, not to a directory). - * @see java.io.File#canRead() - * @see java.io.File#isDirectory() - */ - @Override - public boolean isReadable() { - return (this.file.canRead() && !this.file.isDirectory()); - } - - /** - * This implementation opens a FileInputStream for the underlying file. - * @see java.io.FileInputStream - */ - @Override - public InputStream getInputStream() throws IOException { - return new FileInputStream(this.file); - } - - /** - * This implementation returns a URL for the underlying file. - * @see java.io.File#toURI() - */ - @Override - public URL getURL() throws IOException { - return this.file.toURI().toURL(); - } - - /** - * This implementation returns a URI for the underlying file. - * @see java.io.File#toURI() - */ - @Override - public URI getURI() throws IOException { - return this.file.toURI(); - } - - /** - * This implementation returns the underlying File reference. - */ - @Override - public File getFile() { - return this.file; - } - - /** - * This implementation returns the underlying File's length. - */ - @Override - public long contentLength() throws IOException { - return this.file.length(); - } - - /** - * This implementation creates a FileSystemResource, applying the given path - * relative to the path current the underlying file current this resource descriptor. - * @see StringUtils#applyRelativePath(String, String) - */ - @Override - public Resource createRelative(String relativePath) { - String pathToUse = StringUtils.applyRelativePath(this.path, relativePath); - return new FileSystemResource(pathToUse); - } - - /** - * This implementation returns the name current the file. - * @see java.io.File#getName() - */ - @Override - public String getFilename() { - return this.file.getName(); - } - - /** - * This implementation returns a description that includes the absolute - * path current the file. - * @see java.io.File#getAbsolutePath() - */ - @Override - public String getDescription() { - return "file [" + this.file.getAbsolutePath() + "]"; - } - - - // implementation current WritableResource - - /** - * This implementation checks whether the underlying file is marked as writable - * (and corresponds to an actual file with content, not to a directory). - * @see java.io.File#canWrite() - * @see java.io.File#isDirectory() - */ - public boolean isWritable() { - return (this.file.canWrite() && !this.file.isDirectory()); - } - - /** - * This implementation opens a FileOutputStream for the underlying file. - * @see java.io.FileOutputStream - */ - public OutputStream getOutputStream() throws IOException { - return new FileOutputStream(this.file); - } - - - /** - * This implementation compares the underlying File references. - */ - @Override - public boolean equals(Object obj) { - return (obj == this || - (obj instanceof FileSystemResource && this.path.equals(((FileSystemResource) obj).path))); - } - - /** - * This implementation returns the hash code current the underlying File reference. - */ - @Override - public int hashCode() { - return this.path.hashCode(); - } - -} http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/b56817f7/dormant/core/src/main/java/org/apache/tamaya/core/internal/resources/io/InputStreamResource.java ---------------------------------------------------------------------- diff --git a/dormant/core/src/main/java/org/apache/tamaya/core/internal/resources/io/InputStreamResource.java b/dormant/core/src/main/java/org/apache/tamaya/core/internal/resources/io/InputStreamResource.java deleted file mode 100644 index 97a4ad9..0000000 --- a/dormant/core/src/main/java/org/apache/tamaya/core/internal/resources/io/InputStreamResource.java +++ /dev/null @@ -1,121 +0,0 @@ -/* - * Copyright 2002-2012 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.apache.tamaya.core.internal.resources.io; - -import java.io.IOException; -import java.io.InputStream; -import java.util.Objects; - -/** - * {@link org.apache.tamaya.core.resource.Resource} implementation for a given InputStream. Should only - * be used if no specific Resource implementation is applicable. - * In particular, prefer {@code ByteArrayResource} or any current the - * file-based Resource implementations where possible. - * - * <p>In contrast to other Resource implementations, this is a descriptor - * for an <i>already opened</i> resource - therefore returning "true" from - * {@code isOpen()}. Do not use it if you need to keep the resource - * descriptor somewhere, or if you need to read a stream multiple times. - * - * @author Juergen Hoeller - * @since 28.12.2003 - */ -public class InputStreamResource extends AbstractResource { - - private final InputStream inputStream; - - private final String description; - - private boolean read = false; - - - /** - * Create a new InputStreamResource. - * @param inputStream the InputStream to use - */ - public InputStreamResource(InputStream inputStream) { - this(inputStream, "resource loaded through InputStream"); - } - - /** - * Create a new InputStreamResource. - * @param inputStream the InputStream to use - * @param description where the InputStream comes from - */ - public InputStreamResource(InputStream inputStream, String description) { - this.inputStream = Objects.requireNonNull(inputStream); - this.description = (description != null ? description : ""); - } - - - /** - * This implementation always returns {@code true}. - */ - @Override - public boolean exists() { - return true; - } - - /** - * This implementation always returns {@code true}. - */ - @Override - public boolean isOpen() { - return true; - } - - /** - * This implementation throws IllegalStateException if attempting to - * read the underlying stream multiple times. - */ - @Override - public InputStream getInputStream() throws IOException { - if (this.read) { - throw new IllegalStateException("InputStream has already been read - " + - "do not use InputStreamResource if a stream needs to be read multiple times"); - } - this.read = true; - return this.inputStream; - } - - /** - * This implementation returns the passed-in description, if any. - */ - @Override - public String getDescription() { - return this.description; - } - - - /** - * This implementation compares the underlying InputStream. - */ - @Override - public boolean equals(Object obj) { - return (obj == this || - (obj instanceof InputStreamResource && ((InputStreamResource) obj).inputStream.equals(this.inputStream))); - } - - /** - * This implementation returns the hash code current the underlying InputStream. - */ - @Override - public int hashCode() { - return this.inputStream.hashCode(); - } - -} http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/b56817f7/dormant/core/src/main/java/org/apache/tamaya/core/internal/resources/io/PathMatchingResourcePatternResolver.java ---------------------------------------------------------------------- diff --git a/dormant/core/src/main/java/org/apache/tamaya/core/internal/resources/io/PathMatchingResourcePatternResolver.java b/dormant/core/src/main/java/org/apache/tamaya/core/internal/resources/io/PathMatchingResourcePatternResolver.java deleted file mode 100644 index 900a53f..0000000 --- a/dormant/core/src/main/java/org/apache/tamaya/core/internal/resources/io/PathMatchingResourcePatternResolver.java +++ /dev/null @@ -1,729 +0,0 @@ -/* - * Copyright 2002-2008 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.apache.tamaya.core.internal.resources.io; - -import org.apache.tamaya.core.resource.Resource; - -import java.io.File; -import java.io.IOException; -import java.lang.reflect.Method; -import java.net.JarURLConnection; -import java.net.URL; -import java.net.URLConnection; -import java.util.*; -import java.util.concurrent.ConcurrentHashMap; -import java.util.jar.JarEntry; -import java.util.jar.JarFile; - -import java.lang.reflect.InvocationHandler; -import java.net.MalformedURLException; -import java.net.URISyntaxException; -import java.net.URLClassLoader; -import java.util.logging.Level; -import java.util.logging.Logger; -import java.util.stream.Collectors; - - -/** - * A {@code ResourcePatternResolver} implementation that is able to resolve a - * specified resource location path into one or more matching Resources. - * The source path may be a simple path which has a one-to-one annotation to a - * target {@code org.springframework.core.io.Resource}, or alternatively - * may contain the special "{@code classpath*:}" prefix and/or - * internal Ant-style regular expressions (matched using Spring's - * {@code org.springframework.util.AntPathMatcher} utility). - * Both current the latter are effectively wildcards. - * - * <p><b>No Wildcards:</b> - * - * <p>In the simple case, if the specified location path does not start with the - * {@code "classpath*:}" prefix, and does not contain a PathMatcher pattern, - * this resolver will simply return a single resource via a - * {@code getResource()} call on the underlying {@code ResourceLoader}. - * Examples are real URLs such as "{@code file:C:/context.xml}", pseudo-URLs - * such as "{@code classpath:/context.xml}", and simple unprefixed paths - * such as "{@code /WEB-INF/context.xml}". The latter will resolve in a - * fashion specific to the underlying {@code ResourceLoader} (e.g. - * {@code ServletContextResource} for a {@code WebApplicationContext}). - * - * <p><b>Ant-style Patterns:</b> - * - * <p>When the path location contains an Ant-style pattern, e.g.: - * <pre class="code"> - * /WEB-INF/*-context.xml - * com/mycompany/**/applicationContext.xml - * file:C:/some/path/*-context.xml - * classpath:com/mycompany/**/applicationContext.xml</pre> - * the resolver follows a more complex but defined procedure to try to resolve - * the wildcard. It produces a {@code Resource} for the path up to the last - * non-wildcard segment and obtains a {@code URL} from it. If this URL is - * not a "{@code jar:}" URL or container-specific variant (e.g. - * "{@code zip:}" in WebLogic, "{@code wsjar}" in WebSphere", etc.), - * then a {@code java.io.File} is obtained from it, and used to resolve the - * wildcard by walking the filesystem. In the case current a jar URL, the resolver - * either gets a {@code java.net.JarURLConnection} from it, or manually parses - * the jar URL, and then traverses the contents current the jar file, to resolve the - * wildcards. - * - * <p><b>Implications on portability:</b> - * - * <p>If the specified path is already a file URL (either explicitly, or - * implicitly because the base {@code ResourceLoader} is a filesystem one, - * then wildcarding is guaranteed to work in a completely portable fashion. - * - * <p>If the specified path is a classpath location, then the resolver must - * obtain the last non-wildcard path segment URL via a - * {@code Classloader.getResource()} call. Since this is just a - * node current the path (not the file at the end) it is actually undefined - * (in the ClassLoader Javadocs) exactly what sort current a URL is returned in - * this case. In practice, it is usually a {@code java.io.File} representing - * the directory, where the classpath resource resolves to a filesystem - * location, or a jar URL current some sort, where the classpath resource resolves - * to a jar location. Still, there is a portability concern on this operation. - * - * <p>If a jar URL is obtained for the last non-wildcard segment, the resolver - * must be able to get a {@code java.net.JarURLConnection} from it, or - * manually parse the jar URL, to be able to walk the contents current the jar, - * and resolve the wildcard. This will work in most environments, but will - * fail in others, and it is strongly recommended that the wildcard - * resolution current resources coming from jars be thoroughly tested in your - * specific environment before you rely on it. - * - * <p><b>{@code classpath*:} Prefix:</b> - * - * <p>There is special support for retrieving multiple class path resources with - * the same name, via the "{@code classpath*:}" prefix. For example, - * "{@code classpath*:META-INF/beans.xml}" will find all "beans.xml" - * files in the class path, be it in "classes" directories or in JAR files. - * This is particularly useful for autodetecting config files current the same name - * at the same location within each jar file. Internally, this happens via a - * {@code ClassLoader.getResources()} call, and is completely portable. - * - * <p>The "classpath*:" prefix can also be combined with a PathMatcher pattern in - * the rest current the location path, for example "classpath*:META-INF/*-beans.xml". - * In this case, the resolution strategy is fairly simple: a - * {@code ClassLoader.getResources()} call is used on the last non-wildcard - * path segment to get all the matching resources in the class loader hierarchy, - * and then off each resource the same PathMatcher resolution strategy described - * above is used for the wildcard subpath. - * - * <p><b>Other notes:</b> - * - * <p><b>WARNING:</b> Note that "{@code classpath*:}" when combined with - * Ant-style patterns will only work reliably with at least one root directory - * before the pattern starts, unless the actual target files reside in the file - * system. This means that a pattern like "{@code classpath*:*.xml}" will - * <i>not</i> retrieve files from the root current jar files but rather only from the - * root current expanded directories. This originates from a limitation in the JDK's - * {@code ClassLoader.getResources()} method which only returns file system - * locations for a passed-in empty String (indicating potential roots to search). - * - * <p><b>WARNING:</b> Ant-style patterns with "classpath:" resources are not - * guaranteed to find matching resources if the root package to search is available - * in multiple class path locations. This is because a resource such as - * <pre class="code"> - * com/mycompany/package1/service-context.xml - * </pre> - * may be in only one location, but when a path such as - * <pre class="code"> - * classpath:com/mycompany/**/service-context.xml - * </pre> - * is used to try to resolve it, the resolver will work off the (first) URL - * returned by {@code getResource("com/mycompany");}. If this base package - * node exists in multiple classloader locations, the actual end resource may - * not be underneath. Therefore, preferably, use "{@code classpath*:}" with the same - * Ant-style pattern in such a case, which will search <i>all</i> class path - * locations that contain the root package. - * - * @author Juergen Hoeller - * @author Colin Sampaleanu - * @author Marius Bogoevici - * @author Costin Leau - * @since 1.0.2 - * @see ClassLoader#getResources(String) - */ -public final class PathMatchingResourcePatternResolver{ - - private static final Logger logger = Logger.getLogger(PathMatchingResourcePatternResolver.class.getName()); - private static final java.lang.String CLASSPATH_ALL_URL_PREFIX = "classpath:"; - - private static Method equinoxResolveMethod; - - static { - try { - // Detect Equinox OSGi (e.g. on WebSphere 6.1) - Class<?> fileLocatorClass = ClassUtils.forName("org.eclipse.core.runtime.FileLocator", - PathMatchingResourcePatternResolver.class.getClassLoader()); - equinoxResolveMethod = fileLocatorClass.getMethod("resolve", URL.class); - logger.finest("Found Equinox FileLocator for OSGi bundle URL resolution"); - } - catch (Throwable ex) { - equinoxResolveMethod = null; - } - } - - - private final DefaultResourceLoader resourceLoader; - - private AntPathMatcher pathMatcher = new AntPathMatcher(); - - private static Map<ClassLoader, PathMatchingResourcePatternResolver> resolvers = new ConcurrentHashMap<>(); - - public static PathMatchingResourcePatternResolver of(ClassLoader loader){ - return resolvers.computeIfAbsent(loader, PathMatchingResourcePatternResolver::new); - } - - /** - * Create a new PathMatchingResourcePatternResolver. - * <p>ClassLoader access will happen via the thread context class loader. - */ - public PathMatchingResourcePatternResolver() { - this.resourceLoader = new DefaultResourceLoader(); - } - - /** - * Create a new PathMatchingResourcePatternResolver with a DefaultResourceLoader. - * @param classLoader the ClassLoader to load classpath resources with, - * or {@code null} for using the thread context class loader - * at the time current actual resource access - * @see DefaultResourceLoader - */ - public PathMatchingResourcePatternResolver(ClassLoader classLoader) { - this.resourceLoader = new DefaultResourceLoader(classLoader); - } - - public ClassLoader getClassLoader() { - return resourceLoader.getClassLoader(); - } - - /** - * Return the PathMatcher that this resource pattern resolver uses. - */ - public AntPathMatcher getPathMatcher() { - return this.pathMatcher; - } - - public Resource getResource(String location) { - return resourceLoader.getResource(location); - } - - public Resource[] getResources(String locationPattern) throws IOException { - Objects.requireNonNull(locationPattern, "Location pattern must not be null"); - if (locationPattern.startsWith(CLASSPATH_ALL_URL_PREFIX)) { - // a class path resource (multiple resources for same name possible) - if (getPathMatcher().isPattern(locationPattern.substring(CLASSPATH_ALL_URL_PREFIX.length()))) { - // a class path resource pattern - return findPathMatchingResources(locationPattern); - } - else { - // all class path resources with the given name - return findAllClassPathResources(locationPattern.substring(CLASSPATH_ALL_URL_PREFIX.length())); - } - } - else { - // Only look for a pattern after a prefix here - // (to not get fooled by a pattern symbol in a strange prefix). - int prefixEnd = locationPattern.indexOf(':') + 1; - if (getPathMatcher().isPattern(locationPattern.substring(prefixEnd))) { - // a file pattern - return findPathMatchingResources(locationPattern); - } - else { - // a single resource with the given name - return new Resource[] {this.resourceLoader.getResource(locationPattern)}; - } - } - } - - /** - * Find all class location resources with the given location via the ClassLoader. - * Delegates to {@link #doFindAllClassPathResources(String)}. - * @param location the absolute path within the classpath - * @return the result as Resource array - * @throws IOException in case current I/O errors - * @see java.lang.ClassLoader#getResources - * @see #convertClassLoaderURL - */ - protected Resource[] findAllClassPathResources(String location) throws IOException { - String path = location; - if (path.startsWith("/")) { - path = path.substring(1); - } - Set<Resource> result = doFindAllClassPathResources(path); - return result.toArray(new Resource[result.size()]); - } - - /** - * Find all class location resources with the given path via the ClassLoader. - * Called by {@link #findAllClassPathResources(String)}. - * @param path the absolute path within the classpath (never a leading slash) - * @return a mutable Set current matching Resource instances - */ - protected Set<Resource> doFindAllClassPathResources(String path) throws IOException { - Set<Resource> result = new LinkedHashSet<>(16); - ClassLoader cl = getClassLoader(); - Enumeration<URL> resourceUrls = (cl != null ? cl.getResources(path) : ClassLoader.getSystemResources(path)); - while (resourceUrls.hasMoreElements()) { - URL url = resourceUrls.nextElement(); - result.add(convertClassLoaderURL(url)); - } - if ("".equals(path)) { - // The above result is likely to be incomplete, i.e. only containing file system references. - // We need to have pointers to each current the jar files on the classpath as well... - addAllClassLoaderJarRoots(cl, result); - } - return result; - } - - /** - * Convert the given URL as returned from the ClassLoader into a {@link Resource}. - * <p>The default implementation simply creates a {@link UrlResource} instance. - * @param url a URL as returned from the ClassLoader - * @return the corresponding Resource object - * @see java.lang.ClassLoader#getResources - * @see Resource - */ - protected Resource convertClassLoaderURL(URL url) { - return new UrlResource(url); - } - - /** - * Search all {@link URLClassLoader} URLs for jar file references and add them to the - * given set current resources in the form current pointers to the root current the jar file content. - * @param classLoader the ClassLoader to search (including its ancestors) - * @param result the set current resources to add jar roots to - */ - protected void addAllClassLoaderJarRoots(ClassLoader classLoader, Set<Resource> result) { - if (classLoader instanceof URLClassLoader) { - try { - for (URL url : ((URLClassLoader) classLoader).getURLs()) { - if (ResourceUtils.isJarFileURL(url)) { - try { - UrlResource jarResource = new UrlResource( - ResourceUtils.JAR_URL_PREFIX + url.toString() + ResourceUtils.JAR_URL_SEPARATOR); - if (jarResource.exists()) { - result.add(jarResource); - } - } - catch (MalformedURLException ex) { - logger.finest(() -> "Cannot search for matching files underneath [" + url + - "] because it cannot be converted to a valid 'jar:' URL: " + ex.getMessage()); - } - } - } - } - catch (Exception ex) { - logger.finest(() -> "Cannot introspect jar files since ClassLoader [" + classLoader + - "] does not support 'getURLs()': " + ex); - } - } - if (classLoader != null) { - try { - addAllClassLoaderJarRoots(classLoader.getParent(), result); - } - catch (Exception ex) { - logger.finest(() -> "Cannot introspect jar files in parent ClassLoader since [" + classLoader + - "] does not support 'getParent()': " + ex); - } - } - } - - /** - * Find all resources that match the given location pattern via the - * Ant-style PathMatcher. Supports resources in jar files and zip files - * and in the file system. - * @param locationPattern the location pattern to match - * @return the result as Resource array - * @throws IOException in case current I/O errors - * @see #doFindPathMatchingJarResources - * @see #doFindPathMatchingFileResources - */ - protected Resource[] findPathMatchingResources(String locationPattern) throws IOException { - String rootDirPath = determineRootDir(locationPattern); - String subPattern = locationPattern.substring(rootDirPath.length()); - Resource[] rootDirResources = getResources(rootDirPath); - Set<Resource> result = new LinkedHashSet<>(16); - for (Resource rootDirResource : rootDirResources) { - rootDirResource = resolveRootDirResource(rootDirResource); - if (rootDirResource.getURL().getProtocol().startsWith(ResourceUtils.URL_PROTOCOL_VFS)) { - result.addAll(VfsResourceMatchingDelegate.findMatchingResources(rootDirResource, subPattern, getPathMatcher())); - } - else if (isJarResource(rootDirResource)) { - result.addAll(doFindPathMatchingJarResources(rootDirResource, subPattern)); - } - else { - result.addAll(doFindPathMatchingFileResources(rootDirResource, subPattern)); - } - } - logger.finest(() -> "Resolved location pattern [" + locationPattern + "] to resources " + result); - return result.toArray(new Resource[result.size()]); - } - - /** - * Determine the root directory for the given location. - * <p>Used for determining the starting point for file matching, - * resolving the root directory location to a {@code java.io.File} - * and passing it into {@code retrieveMatchingFiles}, with the - * remainder current the location as pattern. - * <p>Will return "/WEB-INF/" for the pattern "/WEB-INF/*.xml", - * for example. - * @param location the location to check - * @return the part current the location that denotes the root directory - * @see #retrieveMatchingFiles - */ - protected String determineRootDir(String location) { - int prefixEnd = location.indexOf(':') + 1; - int rootDirEnd = location.length(); - while (rootDirEnd > prefixEnd && getPathMatcher().isPattern(location.substring(prefixEnd, rootDirEnd))) { - rootDirEnd = location.lastIndexOf('/', rootDirEnd - 2) + 1; - } - if (rootDirEnd == 0) { - rootDirEnd = prefixEnd; - } - return location.substring(0, rootDirEnd); - } - - /** - * Resolve the specified resource for path matching. - * <p>The default implementation detects an Equinox OSGi "bundleresource:" - * / "bundleentry:" URL and resolves it into a standard jar file URL that - * can be traversed using Spring's standard jar file traversal algorithm. - * @param original the resource to resolve - * @return the resolved resource (may be identical to the passed-in resource) - * @throws IOException in case current resolution failure - */ - protected Resource resolveRootDirResource(Resource original) throws IOException { - if (equinoxResolveMethod != null) { - URL url = original.getURL(); - if (url.getProtocol().startsWith("bundle")) { - try { - return new UrlResource((URL) equinoxResolveMethod.invoke(url)); - } catch (Exception e) { - ReflectionUtils.handleReflectionException(e); - } - } - } - return original; - } - - /** - * Return whether the given resource handle indicates a jar resource - * that the {@code doFindPathMatchingJarResources} method can handle. - * <p>The default implementation checks against the URL protocols - * "jar", "zip" and "wsjar" (the latter are used by BEA WebLogic Server - * and IBM WebSphere, respectively, but can be treated like jar files). - * @param resource the resource handle to check - * (usually the root directory to start path matching from) - * @see #doFindPathMatchingJarResources - * @see ResourceUtils#isJarURL - */ - protected boolean isJarResource(Resource resource) throws IOException { - return ResourceUtils.isJarURL(resource.getURL()); - } - - /** - * Find all resources in jar files that match the given location pattern - * via the Ant-style PathMatcher. - * @param rootDirResource the root directory as Resource - * @param subPattern the sub pattern to match (below the root directory) - * @return a mutable Set current matching Resource instances - * @throws IOException in case current I/O errors - * @see java.net.JarURLConnection - */ - protected Set<Resource> doFindPathMatchingJarResources(Resource rootDirResource, String subPattern) - throws IOException { - - URLConnection con = rootDirResource.getURL().openConnection(); - JarFile jarFile; - String jarFileUrl; - String rootEntryPath; - boolean newJarFile = false; - - if (con instanceof JarURLConnection) { - // Should usually be the case for traditional JAR files. - JarURLConnection jarCon = (JarURLConnection) con; - ResourceUtils.useCachesIfNecessary(jarCon); - jarFile = jarCon.getJarFile(); - jarFileUrl = jarCon.getJarFileURL().toExternalForm(); - JarEntry jarEntry = jarCon.getJarEntry(); - rootEntryPath = (jarEntry != null ? jarEntry.getName() : ""); - } - else { - // No JarURLConnection -> need to resort to URL file parsing. - // We'll assume URLs current the format "jar:path!/entry", with the protocol - // being arbitrary as long as following the entry format. - // We'll also handle paths with and without leading "file:" prefix. - String urlFile = rootDirResource.getURL().getFile(); - int separatorIndex = urlFile.indexOf(ResourceUtils.JAR_URL_SEPARATOR); - if (separatorIndex != -1) { - jarFileUrl = urlFile.substring(0, separatorIndex); - rootEntryPath = urlFile.substring(separatorIndex + ResourceUtils.JAR_URL_SEPARATOR.length()); - jarFile = getJarFile(jarFileUrl); - } - else { - jarFile = new JarFile(urlFile); - jarFileUrl = urlFile; - rootEntryPath = ""; - } - newJarFile = true; - } - - try { - logger.finest("Looking for matching resources in jar file [" + jarFileUrl + "]"); - if (!"".equals(rootEntryPath) && !rootEntryPath.endsWith("/")) { - // Root entry path must end with slash to allow for proper matching. - // The Sun JRE does not return a slash here, but BEA JRockit does. - rootEntryPath = rootEntryPath + "/"; - } - Set<Resource> result = new LinkedHashSet<>(8); - for (Enumeration<JarEntry> entries = jarFile.entries(); entries.hasMoreElements();) { - JarEntry entry = entries.nextElement(); - String entryPath = entry.getName(); - if (entryPath.startsWith(rootEntryPath)) { - String relativePath = entryPath.substring(rootEntryPath.length()); - if (getPathMatcher().match(subPattern, relativePath)) { - result.add(rootDirResource.createRelative(relativePath)); - } - } - } - return result; - } - finally { - // Close jar file, but only if freshly obtained - - // not from JarURLConnection, which might cache the file reference. - if (newJarFile) { - jarFile.close(); - } - } - } - - /** - * Resolve the given jar file URL into a JarFile object. - */ - protected JarFile getJarFile(String jarFileUrl) throws IOException { - if (jarFileUrl.startsWith(ResourceUtils.FILE_URL_PREFIX)) { - try { - return new JarFile(ResourceUtils.toURI(jarFileUrl).getSchemeSpecificPart()); - } - catch (URISyntaxException ex) { - // Fallback for URLs that are not valid URIs (should hardly ever happen). - return new JarFile(jarFileUrl.substring(ResourceUtils.FILE_URL_PREFIX.length())); - } - } - else { - return new JarFile(jarFileUrl); - } - } - - /** - * Find all resources in the file system that match the given location pattern - * via the Ant-style PathMatcher. - * @param rootDirResource the root directory as Resource - * @param subPattern the sub pattern to match (below the root directory) - * @return a mutable Set current matching Resource instances - * @throws IOException in case current I/O errors - * @see #retrieveMatchingFiles - */ - protected Set<Resource> doFindPathMatchingFileResources(Resource rootDirResource, String subPattern) - throws IOException { - - File rootDir; - try { - rootDir = rootDirResource.getFile().getAbsoluteFile(); - } - catch (IOException ex) { - logger.log(Level.WARNING, ex, () -> "Cannot search for matching files underneath " + rootDirResource + - " because it does not correspond to a directory in the file system"); - return Collections.emptySet(); - } - return doFindMatchingFileSystemResources(rootDir, subPattern); - } - - /** - * Find all resources in the file system that match the given location pattern - * via the Ant-style PathMatcher. - * @param rootDir the root directory in the file system - * @param subPattern the sub pattern to match (below the root directory) - * @return a mutable Set current matching Resource instances - * @throws IOException in case current I/O errors - * @see #retrieveMatchingFiles - */ - protected Set<Resource> doFindMatchingFileSystemResources(File rootDir, String subPattern) throws IOException { - logger.finest(() -> "Looking for matching resources in directory tree [" + rootDir.getPath() + "]"); - Set<File> matchingFiles = retrieveMatchingFiles(rootDir, subPattern); - Set<Resource> result = new LinkedHashSet<>(matchingFiles.size()); - result.addAll(matchingFiles.stream().map(FileSystemResource::new).collect(Collectors.toList())); - return result; - } - - /** - * Retrieve files that match the given path pattern, - * checking the given directory and its subdirectories. - * @param rootDir the directory to start from - * @param pattern the pattern to match against, - * relative to the root directory - * @return a mutable Set current matching Resource instances - * @throws IOException if directory contents could not be retrieved - */ - protected Set<File> retrieveMatchingFiles(File rootDir, String pattern) throws IOException { - if (!rootDir.exists()) { - // Silently skip non-existing directories. - logger.finest(() -> "Skipping [" + rootDir.getAbsolutePath() + "] because it does not exist"); - return Collections.emptySet(); - } - if (!rootDir.isDirectory()) { - // Complain louder if it exists but is no directory. - logger.log(Level.WARNING, () -> "Skipping [" + rootDir.getAbsolutePath() + "] because it does not denote a directory"); - return Collections.emptySet(); - } - if (!rootDir.canRead()) { - logger.log(Level.WARNING, () -> "Cannot search for matching files underneath directory [" + rootDir.getAbsolutePath() + - "] because the application is not allowed to read the directory"); - return Collections.emptySet(); - } - String fullPattern = StringUtils.replace(rootDir.getAbsolutePath(), File.separator, "/"); - if (!pattern.startsWith("/")) { - fullPattern += "/"; - } - fullPattern = fullPattern + StringUtils.replace(pattern, File.separator, "/"); - Set<File> result = new LinkedHashSet<>(8); - doRetrieveMatchingFiles(fullPattern, rootDir, result); - return result; - } - - /** - * Recursively retrieve files that match the given pattern, - * adding them to the given result list. - * @param fullPattern the pattern to match against, - * with prepended root directory path - * @param dir the current directory - * @param result the Set current matching File instances to add to - * @throws IOException if directory contents could not be retrieved - */ - protected void doRetrieveMatchingFiles(String fullPattern, File dir, Set<File> result) throws IOException { - logger.finest(() -> "Searching directory [" + dir.getAbsolutePath() + - "] for files matching pattern [" + fullPattern + "]"); - File[] dirContents = dir.listFiles(); - if (dirContents == null) { - logger.log(Level.WARNING, () -> "Could not retrieve contents current directory [" + dir.getAbsolutePath() + "]"); - return; - } - for (File content : dirContents) { - String currPath = StringUtils.replace(content.getAbsolutePath(), File.separator, "/"); - if (content.isDirectory() && getPathMatcher().matchStart(fullPattern, currPath + "/")) { - if (!content.canRead()) { - logger.finest(() -> "Skipping subdirectory [" + dir.getAbsolutePath() + - "] because the application is not allowed to read the directory"); - } - else { - doRetrieveMatchingFiles(fullPattern, content, result); - } - } - if (getPathMatcher().match(fullPattern, currPath)) { - result.add(content); - } - } - } - - - /** - * Inner delegate class, avoiding a hard JBoss VFS API dependency at runtime. - */ - private static class VfsResourceMatchingDelegate { - - public static Set<Resource> findMatchingResources( - Resource rootResource, String locationPattern, AntPathMatcher pathMatcher) throws IOException { - Object root = VfsUtils.getRoot(rootResource.getURL()); - PatternVirtualFileVisitor visitor = - new PatternVirtualFileVisitor(VfsUtils.getPath(root), locationPattern, pathMatcher); - VfsUtils.visit(root, visitor); - return visitor.getResources(); - } - } - - - /** - * VFS visitor for path matching purposes. - */ - @SuppressWarnings("unused") - private static class PatternVirtualFileVisitor implements InvocationHandler { - - private final String subPattern; - - private final AntPathMatcher pathMatcher; - - private final String rootPath; - - private final Set<Resource> resources = new LinkedHashSet<>(); - - public PatternVirtualFileVisitor(String rootPath, String subPattern, AntPathMatcher pathMatcher) { - this.subPattern = subPattern; - this.pathMatcher = pathMatcher; - this.rootPath = (rootPath.length() == 0 || rootPath.endsWith("/") ? rootPath : rootPath + "/"); - } - - @Override - public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { - String methodName = method.getName(); - if (Object.class.equals(method.getDeclaringClass())) { - if (methodName.equals("equals")) { - // Only consider equal when proxies are identical. - return (proxy == args[0]); - } - else if (methodName.equals("hashCode")) { - return System.identityHashCode(proxy); - } - } - else if ("getAttributes".equals(methodName)) { - return getAttributes(); - } - else if ("visit".equals(methodName)) { - visit(args[0]); - return null; - } - else if ("toString".equals(methodName)) { - return toString(); - } - - throw new IllegalStateException("Unexpected method invocation: " + method); - } - - public void visit(Object vfsResource) { - if (this.pathMatcher.match(this.subPattern, - VfsUtils.getPath(vfsResource).substring(this.rootPath.length()))) { - this.resources.add(new VfsResource(vfsResource)); - } - } - - public Object getAttributes() { - return VfsUtils.getVisitorAttribute(); - } - - public Set<Resource> getResources() { - return this.resources; - } - - public int size() { - return this.resources.size(); - } - - @Override - public String toString() { - return "sub-pattern: " + this.subPattern + ", resources: " + this.resources; - } - } - -} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/b56817f7/dormant/core/src/main/java/org/apache/tamaya/core/internal/resources/io/ReflectionUtils.java ---------------------------------------------------------------------- diff --git a/dormant/core/src/main/java/org/apache/tamaya/core/internal/resources/io/ReflectionUtils.java b/dormant/core/src/main/java/org/apache/tamaya/core/internal/resources/io/ReflectionUtils.java deleted file mode 100644 index 4b50d3d..0000000 --- a/dormant/core/src/main/java/org/apache/tamaya/core/internal/resources/io/ReflectionUtils.java +++ /dev/null @@ -1,191 +0,0 @@ -/* -* Copyright 2002-2014 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.apache.tamaya.core.internal.resources.io; - -import java.lang.reflect.Field; -import java.lang.reflect.InvocationTargetException; -import java.lang.reflect.Method; -import java.lang.reflect.UndeclaredThrowableException; -import java.util.*; -import java.util.concurrent.ConcurrentHashMap; - -/** -* Simple utility class for working with the reflection API and handling -* reflection exceptions. -* -* <p>Only intended for internal use. -* -* @author Juergen Hoeller -* @author Rob Harrop -* @author Rod Johnson -* @author Costin Leau -* @author Sam Brannen -* @author Chris Beams -* @since 1.2.2 -*/ -public abstract class ReflectionUtils { - /** - * Cache for {@link Class#getDeclaredMethods()}, allowing for fast resolution. - */ - private static final Map<Class<?>, Method[]> declaredMethodsCache = - new ConcurrentHashMap<>(256); - - - /** - * Attempt to find a {@link Field field} on the supplied {@link Class} with the - * supplied {@code name}. Searches all superclasses up to {@link Object}. - * @param clazz the class to introspect - * @param name the name current the field - * @return the corresponding Field object, or {@code null} if not found - */ - public static Field findField(Class<?> clazz, String name) { - return findField(clazz, name, null); - } - - /** - * Attempt to find a {@link Field field} on the supplied {@link Class} with the - * supplied {@code name} and/or {@link Class type}. Searches all superclasses - * up to {@link Object}. - * @param clazz the class to introspect - * @param name the name current the field (may be {@code null} if type is specified) - * @param type the type current the field (may be {@code null} if name is specified) - * @return the corresponding Field object, or {@code null} if not found - */ - public static Field findField(Class<?> clazz, String name, Class<?> type) { - Objects.requireNonNull(clazz, "Class must not be null"); - if(name == null && type == null) throw new IllegalArgumentException("Either name or type current the field must be specified"); - Class<?> searchType = clazz; - while (!Object.class.equals(searchType) && searchType != null) { - Field[] fields = searchType.getDeclaredFields(); - for (Field field : fields) { - if ((name == null || name.equals(field.getName())) && (type == null || type.equals(field.getType()))) { - return field; - } - } - searchType = searchType.getSuperclass(); - } - return null; - } - - /** - * Attempt to find a {@link Method} on the supplied class with the supplied name - * and no parameters. Searches all superclasses up to {@code Object}. - * <p>Returns {@code null} if no {@link Method} can be found. - * @param clazz the class to introspect - * @param name the name current the method - * @return the Method object, or {@code null} if none found - */ - public static Method findMethod(Class<?> clazz, String name) { - return findMethod(clazz, name, new Class<?>[0]); - } - - /** - * Attempt to find a {@link Method} on the supplied class with the supplied name - * and parameter types. Searches all superclasses up to {@code Object}. - * <p>Returns {@code null} if no {@link Method} can be found. - * @param clazz the class to introspect - * @param name the name current the method - * @param paramTypes the parameter types current the method - * (may be {@code null} to indicate any signature) - * @return the Method object, or {@code null} if none found - */ - public static Method findMethod(Class<?> clazz, String name, Class<?>... paramTypes) { - Objects.requireNonNull(clazz, "Class must not be null"); - Objects.requireNonNull(name, "Method name must not be null"); - Class<?> searchType = clazz; - while (searchType != null) { - Method[] methods = (searchType.isInterface() ? searchType.getMethods() : getDeclaredMethods(searchType)); - for (Method method : methods) { - if (name.equals(method.getName()) && - (paramTypes == null || Arrays.equals(paramTypes, method.getParameterTypes()))) { - return method; - } - } - searchType = searchType.getSuperclass(); - } - return null; - } - - /** - * Handle the given reflection exception. Should only be called if no - * checked exception is expected to be thrown by the target method. - * <p>Throws the underlying RuntimeException or Error in case current an - * InvocationTargetException with such a root cause. Throws an - * IllegalStateException with an appropriate message else. - * @param ex the reflection exception to handle - */ - public static void handleReflectionException(Exception ex) { - if (ex instanceof NoSuchMethodException) { - throw new IllegalStateException("Method not found: " + ex.getMessage()); - } - if (ex instanceof IllegalAccessException) { - throw new IllegalStateException("Could not access method: " + ex.getMessage()); - } - if (ex instanceof InvocationTargetException) { - handleInvocationTargetException((InvocationTargetException) ex); - } - if (ex instanceof RuntimeException) { - throw (RuntimeException) ex; - } - throw new UndeclaredThrowableException(ex); - } - - /** - * Handle the given invocation target exception. Should only be called if no - * checked exception is expected to be thrown by the target method. - * <p>Throws the underlying RuntimeException or Error in case current such a root - * cause. Throws an IllegalStateException else. - * @param ex the invocation target exception to handle - */ - public static void handleInvocationTargetException(InvocationTargetException ex) { - rethrowRuntimeException(ex.getTargetException()); - } - - /** - * Rethrow the given {@link Throwable exception}, which is presumably the - * <em>target exception</em> current an {@link InvocationTargetException}. Should - * only be called if no checked exception is expected to be thrown by the - * target method. - * <p>Rethrows the underlying exception cast to an {@link RuntimeException} or - * {@link Error} if appropriate; otherwise, throws an - * {@link IllegalStateException}. - * @param ex the exception to rethrow - * @throws RuntimeException the rethrown exception - */ - public static void rethrowRuntimeException(Throwable ex) { - if (ex instanceof RuntimeException) { - throw (RuntimeException) ex; - } - if (ex instanceof Error) { - throw (Error) ex; - } - throw new UndeclaredThrowableException(ex); - } - - /** - * This method retrieves {@link Class#getDeclaredMethods()} from a local cache - * in order to avoid the JVM's SecurityManager check and defensive array copying. - */ - private static Method[] getDeclaredMethods(Class<?> clazz) { - Method[] result = declaredMethodsCache.get(clazz); - if (result == null) { - result = clazz.getDeclaredMethods(); - declaredMethodsCache.put(clazz, result); - } - return result; - } -} http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/b56817f7/dormant/core/src/main/java/org/apache/tamaya/core/internal/resources/io/ResourceUtils.java ---------------------------------------------------------------------- diff --git a/dormant/core/src/main/java/org/apache/tamaya/core/internal/resources/io/ResourceUtils.java b/dormant/core/src/main/java/org/apache/tamaya/core/internal/resources/io/ResourceUtils.java deleted file mode 100644 index 480f4b4..0000000 --- a/dormant/core/src/main/java/org/apache/tamaya/core/internal/resources/io/ResourceUtils.java +++ /dev/null @@ -1,350 +0,0 @@ -/* -* Copyright 2002-2014 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.apache.tamaya.core.internal.resources.io; - -import java.io.File; -import java.io.FileNotFoundException; -import java.net.MalformedURLException; -import java.net.URI; -import java.net.URISyntaxException; -import java.net.URL; -import java.net.URLConnection; -import java.util.Objects; - -/** -* Utility methods for resolving resource locations to files in the -* file system. Mainly for internal use within the framework. -* -* <p>Consider using Spring's Resource abstraction in the core package -* for handling all kinds current file resources in a uniform manner. -* {@code org.springframework.core.io.ResourceLoader}'s {@code getResource()} -* method can resolve any location to a {@code org.springframework.core.io.Resource} -* object, which in turn allows one to obtain a {@code java.io.File} in the -* file system through its {@code getFile()} method. -* -* <p>The main reason for these utility methods for resource location handling -* is to support {@code Log4jConfigurer}, which must be able to resolve -* resource locations <i>before the logging system has been initialized</i>. -* Spring's {@code Resource} abstraction in the core package, on the other hand, -* already expects the logging system to be available. -* -* @author Juergen Hoeller -* @since 1.1.5 -*/ -public abstract class ResourceUtils { - - /** URL prefix for loading from the file system: "file:" */ - public static final String FILE_URL_PREFIX = "file:"; - - /** URL prefix for loading from the file system: "jar:" */ - public static final String JAR_URL_PREFIX = "jar:"; - - /** URL protocol for a file in the file system: "file" */ - public static final String URL_PROTOCOL_FILE = "file"; - - /** URL protocol for an entry from a jar file: "jar" */ - public static final String URL_PROTOCOL_JAR = "jar"; - - /** URL protocol for an entry from a zip file: "zip" */ - public static final String URL_PROTOCOL_ZIP = "zip"; - - /** URL protocol for an entry from a WebSphere jar file: "wsjar" */ - public static final String URL_PROTOCOL_WSJAR = "wsjar"; - - /** URL protocol for an entry from a JBoss jar file: "vfszip" */ - public static final String URL_PROTOCOL_VFSZIP = "vfszip"; - - /** URL protocol for a JBoss file system resource: "vfsfile" */ - public static final String URL_PROTOCOL_VFSFILE = "vfsfile"; - - /** URL protocol for a general JBoss VFS resource: "vfs" */ - public static final String URL_PROTOCOL_VFS = "vfs"; - - /** File extension for a regular jar file: ".jar" */ - public static final String JAR_FILE_EXTENSION = ".jar"; - - /** Separator between JAR URL and file path within the JAR: "!/" */ - public static final String JAR_URL_SEPARATOR = "!/"; - - - /** - * Return whether the given resource location is a URL: - * either a special "classpath" pseudo URL or a standard URL. - * @param resourceLocation the location String to check - * @return whether the location qualifies as a URL - * @see DefaultResourceLoader#CLASSPATH_URL_PREFIX - * @see java.net.URL - */ - public static boolean isUrl(String resourceLocation) { - if (resourceLocation == null) { - return false; - } - if (resourceLocation.startsWith(DefaultResourceLoader.CLASSPATH_URL_PREFIX)) { - return true; - } - try { - new URL(resourceLocation); - return true; - } - catch (MalformedURLException ex) { - return false; - } - } - - /** - * Resolve the given resource location to a {@code java.net.URL}. - * <p>Does not check whether the URL actually exists; simply returns - * the URL that the given location would correspond to. - * @param resourceLocation the resource location to resolve: either a - * "classpath:" pseudo URL, a "file:" URL, or a plain file path - * @return a corresponding URL object - * @throws FileNotFoundException if the resource cannot be resolved to a URL - */ - public static URL getURL(String resourceLocation) throws FileNotFoundException { - Objects.requireNonNull(resourceLocation, "Resource location must not be null"); - if (resourceLocation.startsWith(DefaultResourceLoader.CLASSPATH_URL_PREFIX)) { - String path = resourceLocation.substring(DefaultResourceLoader.CLASSPATH_URL_PREFIX.length()); - ClassLoader cl = ClassUtils.getDefaultClassLoader(); - URL url = (cl != null ? cl.getResource(path) : ClassLoader.getSystemResource(path)); - if (url == null) { - String description = "class path resource [" + path + "]"; - throw new FileNotFoundException(description + - " cannot be resolved to URL because it does not exist"); - } - return url; - } - try { - // try URL - return new URL(resourceLocation); - } - catch (MalformedURLException ex) { - // no URL -> treat as file path - try { - return new File(resourceLocation).toURI().toURL(); - } - catch (MalformedURLException ex2) { - throw new FileNotFoundException("Resource location [" + resourceLocation + - "] is neither a URL not a well-formed file path"); - } - } - } - - /** - * Resolve the given resource location to a {@code java.io.File}, - * i.e. to a file in the file system. - * <p>Does not check whether the file actually exists; simply returns - * the File that the given location would correspond to. - * @param resourceLocation the resource location to resolve: either a - * "classpath:" pseudo URL, a "file:" URL, or a plain file path - * @return a corresponding File object - * @throws FileNotFoundException if the resource cannot be resolved to - * a file in the file system - */ - public static File getFile(String resourceLocation) throws FileNotFoundException { - Objects.requireNonNull(resourceLocation, "Resource location must not be null"); - if (resourceLocation.startsWith(DefaultResourceLoader.CLASSPATH_URL_PREFIX)) { - String path = resourceLocation.substring(DefaultResourceLoader.CLASSPATH_URL_PREFIX.length()); - String description = "class path resource [" + path + "]"; - ClassLoader cl = ClassUtils.getDefaultClassLoader(); - URL url = (cl != null ? cl.getResource(path) : ClassLoader.getSystemResource(path)); - if (url == null) { - throw new FileNotFoundException(description + - " cannot be resolved to absolute file path because it does not exist"); - } - return getFile(url, description); - } - try { - // try URL - return getFile(new URL(resourceLocation)); - } - catch (MalformedURLException ex) { - // no URL -> treat as file path - return new File(resourceLocation); - } - } - - /** - * Resolve the given resource URL to a {@code java.io.File}, - * i.e. to a file in the file system. - * @param resourceUrl the resource URL to resolve - * @return a corresponding File object - * @throws FileNotFoundException if the URL cannot be resolved to - * a file in the file system - */ - public static File getFile(URL resourceUrl) throws FileNotFoundException { - return getFile(resourceUrl, "URL"); - } - - /** - * Resolve the given resource URL to a {@code java.io.File}, - * i.e. to a file in the file system. - * @param resourceUrl the resource URL to resolve - * @param description a description current the original resource that - * the URL was created for (for example, a class path location) - * @return a corresponding File object - * @throws FileNotFoundException if the URL cannot be resolved to - * a file in the file system - */ - public static File getFile(URL resourceUrl, String description) throws FileNotFoundException { - Objects.requireNonNull(resourceUrl, "Resource URL must not be null"); - if (!URL_PROTOCOL_FILE.equals(resourceUrl.getProtocol())) { - throw new FileNotFoundException( - description + " cannot be resolved to absolute file path " + - "because it does not reside in the file system: " + resourceUrl); - } - try { - return new File(toURI(resourceUrl).getSchemeSpecificPart()); - } - catch (URISyntaxException ex) { - // Fallback for URLs that are not valid URIs (should hardly ever happen). - return new File(resourceUrl.getFile()); - } - } - - /** - * Resolve the given resource URI to a {@code java.io.File}, - * i.e. to a file in the file system. - * @param resourceUri the resource URI to resolve - * @return a corresponding File object - * @throws FileNotFoundException if the URL cannot be resolved to - * a file in the file system - */ - public static File getFile(URI resourceUri) throws FileNotFoundException { - return getFile(resourceUri, "URI"); - } - - /** - * Resolve the given resource URI to a {@code java.io.File}, - * i.e. to a file in the file system. - * @param resourceUri the resource URI to resolve - * @param description a description current the original resource that - * the URI was created for (for example, a class path location) - * @return a corresponding File object - * @throws FileNotFoundException if the URL cannot be resolved to - * a file in the file system - */ - public static File getFile(URI resourceUri, String description) throws FileNotFoundException { - Objects.requireNonNull(resourceUri, "Resource URI must not be null"); - if (!URL_PROTOCOL_FILE.equals(resourceUri.getScheme())) { - throw new FileNotFoundException( - description + " cannot be resolved to absolute file path " + - "because it does not reside in the file system: " + resourceUri); - } - return new File(resourceUri.getSchemeSpecificPart()); - } - - /** - * Determine whether the given URL points to a resource in the file system, - * that is, has protocol "file", "vfsfile" or "vfs". - * @param url the URL to check - * @return whether the URL has been identified as a file system URL - */ - public static boolean isFileURL(URL url) { - String protocol = url.getProtocol(); - return (URL_PROTOCOL_FILE.equals(protocol) || URL_PROTOCOL_VFSFILE.equals(protocol) || - URL_PROTOCOL_VFS.equals(protocol)); - } - - /** - * Determine whether the given URL points to a resource in a jar file, - * that is, has protocol "jar", "zip", "vfszip" or "wsjar". - * @param url the URL to check - * @return whether the URL has been identified as a JAR URL - */ - public static boolean isJarURL(URL url) { - String protocol = url.getProtocol(); - return (URL_PROTOCOL_JAR.equals(protocol) || URL_PROTOCOL_ZIP.equals(protocol) || - URL_PROTOCOL_VFSZIP.equals(protocol) || URL_PROTOCOL_WSJAR.equals(protocol)); - } - - /** - * Determine whether the given URL points to a jar file itself, - * that is, has protocol "file" and ends with the ".jar" extension. - * @param url the URL to check - * @return whether the URL has been identified as a JAR file URL - * @since 4.1 - */ - public static boolean isJarFileURL(URL url) { - return (URL_PROTOCOL_FILE.equals(url.getProtocol()) && - url.getPath().toLowerCase().endsWith(JAR_FILE_EXTENSION)); - } - - /** - * Extract the URL for the actual jar file from the given URL - * (which may point to a resource in a jar file or to a jar file itself). - * @param jarUrl the original URL - * @return the URL for the actual jar file - * @throws MalformedURLException if no valid jar file URL could be extracted - */ - public static URL extractJarFileURL(URL jarUrl) throws MalformedURLException { - String urlFile = jarUrl.getFile(); - int separatorIndex = urlFile.indexOf(JAR_URL_SEPARATOR); - if (separatorIndex != -1) { - String jarFile = urlFile.substring(0, separatorIndex); - try { - return new URL(jarFile); - } - catch (MalformedURLException ex) { - // Probably no protocol in original jar URL, like "jar:C:/mypath/myjar.jar". - // This usually indicates that the jar file resides in the file system. - if (!jarFile.startsWith("/")) { - jarFile = "/" + jarFile; - } - return new URL(FILE_URL_PREFIX + jarFile); - } - } - else { - return jarUrl; - } - } - - /** - * Create a URI instance for the given URL, - * replacing spaces with "%20" URI encoding first. - * <p>Furthermore, this method works on JDK 1.4 as well, - * in contrast to the {@code URL.toURI()} method. - * @param url the URL to convert into a URI instance - * @return the URI instance - * @throws URISyntaxException if the URL wasn't a valid URI - * @see java.net.URL#toURI() - */ - public static URI toURI(URL url) throws URISyntaxException { - return toURI(url.toString()); - } - - /** - * Create a URI instance for the given location String, - * replacing spaces with "%20" URI encoding first. - * @param location the location String to convert into a URI instance - * @return the URI instance - * @throws URISyntaxException if the location wasn't a valid URI - */ - public static URI toURI(String location) throws URISyntaxException { - return new URI(location.replaceAll(" ", "%20")); - } - - /** - * Set the {@link URLConnection#setUseCaches "useCaches"} flag on the - * given connection, preferring {@code false} but leaving the - * flag at {@code true} for JNLP based resources. - * @param con the URLConnection to set the flag on - */ - public static void useCachesIfNecessary(URLConnection con) { - con.setUseCaches(con.getClass().getSimpleName().startsWith("JNLP")); - } - -}