You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
340 lines
13 KiB
340 lines
13 KiB
/* |
|
* 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 com.fr.third.springframework.util; |
|
|
|
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; |
|
|
|
/** |
|
* 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 of file resources in a uniform manner. |
|
* {@link com.fr.third.springframework.core.io.ResourceLoader}'s {@code getResource()} |
|
* method can resolve any location to a {@link com.fr.third.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 {@link 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 |
|
* @see com.fr.third.springframework.core.io.Resource |
|
* @see com.fr.third.springframework.core.io.ClassPathResource |
|
* @see com.fr.third.springframework.core.io.FileSystemResource |
|
* @see com.fr.third.springframework.core.io.UrlResource |
|
* @see com.fr.third.springframework.core.io.ResourceLoader |
|
*/ |
|
public abstract class ResourceUtils { |
|
|
|
/** Pseudo URL prefix for loading from the class path: "classpath:" */ |
|
public static final String CLASSPATH_URL_PREFIX = "classpath:"; |
|
|
|
/** URL prefix for loading from the file system: "file:" */ |
|
public static final String FILE_URL_PREFIX = "file:"; |
|
|
|
/** 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"; |
|
|
|
/** 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 #CLASSPATH_URL_PREFIX |
|
* @see java.net.URL |
|
*/ |
|
public static boolean isUrl(String resourceLocation) { |
|
if (resourceLocation == null) { |
|
return false; |
|
} |
|
if (resourceLocation.startsWith(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 { |
|
Assert.notNull(resourceLocation, "Resource location must not be null"); |
|
if (resourceLocation.startsWith(CLASSPATH_URL_PREFIX)) { |
|
String path = resourceLocation.substring(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 { |
|
Assert.notNull(resourceLocation, "Resource location must not be null"); |
|
if (resourceLocation.startsWith(CLASSPATH_URL_PREFIX)) { |
|
String path = resourceLocation.substring(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 reside in the file system"); |
|
} |
|
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 of 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 { |
|
Assert.notNull(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 of 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 { |
|
Assert.notNull(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)); |
|
} |
|
|
|
/** |
|
* 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(StringUtils.replace(location, " ", "%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")); |
|
} |
|
|
|
}
|
|
|