All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.wl4g.infra.common.resource.ResourceUtils2 Maven / Gradle / Ivy

There is a newer version: 3.1.72
Show newest version
/*
 * Copyright 2017 ~ 2025 the original author or authors. James Wong 
 *
 * 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.wl4g.infra.common.resource;

import static com.google.common.base.Charsets.UTF_8;
import static com.google.common.io.Resources.getResource;
import static java.util.Objects.nonNull;
import static org.apache.commons.lang3.StringUtils.isBlank;

/**
 * Retention of upstream license agreement statement:
* Thank you very much spring framework, We fully comply with and support the open license * agreement of spring. The purpose of migration is to solve the problem * that these elegant API programs can still be easily used without running * in the spring environment. *
* Copyright 2002-2017 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. */ import java.io.File; import java.io.FileNotFoundException; import java.io.IOException; import java.net.MalformedURLException; import java.net.URI; import java.net.URISyntaxException; import java.net.URL; import java.net.URLConnection; import javax.annotation.Nullable; import org.apache.commons.lang3.StringUtils; import com.google.common.io.Resources; import com.wl4g.infra.common.lang.Assert2; import com.wl4g.infra.common.lang.ClassUtils2; /** * Utility methods for resolving resource locations to files in the file system. * Mainly for internal use within the framework. * *

* Consider using Spring's Resource abstraction in the core package for handling * all kinds of file resources in a uniform manner. * {@link org.springframework.core.io.ResourceLoader}'s {@code getResource()} * method can resolve any location to a * {@link 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. * * @author Juergen Hoeller * @since 1.1.5 * @see org.springframework.core.io.Resource * @see org.springframework.core.io.ClassPathResource * @see org.springframework.core.io.FileSystemResource * @see org.springframework.core.io.UrlResource * @see org.springframework.core.io.ResourceLoader */ public abstract class ResourceUtils2 { /** 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 prefix for loading from a jar file: "jar:". */ public static final String JAR_URL_PREFIX = "jar:"; /** URL prefix for loading from a war file on Tomcat: "war:". */ public static final String WAR_URL_PREFIX = "war:"; /** 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 war file: "war". */ public static final String URL_PROTOCOL_WAR = "war"; /** 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 = "!/"; /** Special separator between WAR URL and jar part on Tomcat. */ public static final String WAR_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(@Nullable 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}. *

* 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 { Assert2.notNull(resourceLocation, "Resource location must not be null"); if (resourceLocation.startsWith(CLASSPATH_URL_PREFIX)) { String path = resourceLocation.substring(CLASSPATH_URL_PREFIX.length()); ClassLoader cl = ClassUtils2.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. *

* 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 { Assert2.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 = ClassUtils2.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 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 { Assert2.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 * @since 2.5 */ 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 * @since 2.5 */ public static File getFile(URI resourceUri, String description) throws FileNotFoundException { Assert2.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, * i.e. 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. i.e. * has protocol "jar", "war, ""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_WAR.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; } } /** * Extract the URL for the outermost archive from the given jar/war URL * (which may point to a resource in a jar file or to a jar file itself). *

* In the case of a jar file nested within a war file, this will return a * URL to the war file since that is the one resolvable in the file system. * * @param jarUrl * the original URL * @return the URL for the actual jar file * @throws MalformedURLException * if no valid jar file URL could be extracted * @since 4.1.8 * @see #extractJarFileURL(URL) */ public static URL extractArchiveURL(URL jarUrl) throws MalformedURLException { String urlFile = jarUrl.getFile(); int endIndex = urlFile.indexOf(WAR_URL_SEPARATOR); if (endIndex != -1) { // Tomcat's // "war:file:...mywar.war*/WEB-INF/lib/myjar.jar!/myentry.txt" String warFile = urlFile.substring(0, endIndex); if (URL_PROTOCOL_WAR.equals(jarUrl.getProtocol())) { return new URL(warFile); } int startIndex = warFile.indexOf(WAR_URL_PREFIX); if (startIndex != -1) { return new URL(warFile.substring(startIndex + WAR_URL_PREFIX.length())); } } // Regular "jar:file:...myjar.jar!/myentry.txt" return extractJarFileURL(jarUrl); } /** * Create a URI instance for the given URL, replacing spaces with "%20" URI * encoding first. * * @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")); } // --- Exstenssion tools. --- /** * Gets resource string with class path * * @param loadByClass * @param resourceName * @return */ public static String getResourceString(@Nullable Class loadByClass, @Nullable String resourceName) { if (isBlank(resourceName)) { return null; } URL url = null; if (nonNull(loadByClass)) { // Find by class String basePath = loadByClass.getName(); basePath = basePath.substring(0, basePath.lastIndexOf(".")).replace(".", "/"); url = getResource(basePath + "/" + resourceName); } else { // Fallback url = getResource(resourceName); } try { return nonNull(url) ? Resources.toString(url, UTF_8) : null; } catch (IOException e) { throw new IllegalStateException(e); } } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy