be.atbash.util.resource.ResourceUtil Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of utils-se Show documentation
Show all versions of utils-se Show documentation
Some utilities only requiring Java SE for all the Atbash projects
The newest version!
/*
* Copyright 2014-2022 Rudy De Busscher (https://www.atbash.be)
*
* 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 be.atbash.util.resource;
import be.atbash.util.PublicAPI;
import be.atbash.util.StringUtils;
import be.atbash.util.ordered.OrderComparator;
import be.atbash.util.resource.internal.ClassPathResourceReader;
import be.atbash.util.resource.internal.FileResourceReader;
import be.atbash.util.resource.internal.URLResourceReader;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.URI;
import java.util.*;
@PublicAPI
public class ResourceUtil {
/**
* Resource path prefix that specifies to load from a file location, value is {@code file:}
*/
public static final String FILE_PREFIX = "file:";
/**
* Resource path prefix that specifies to load from a url location, value is {@code url:}
*/
public static final String URL_PREFIX = "url:";
/**
* Resource path prefix that specifies to load from a classpath location, value is {@code classpath:}
*/
public static final String CLASSPATH_PREFIX = "classpath:";
private static ResourceUtil INSTANCE;
private final List readers;
private ResourceUtil() {
readers = new ArrayList<>();
readers.add(new ClassPathResourceReader());
readers.add(new URLResourceReader());
readers.add(new FileResourceReader());
// current Thread
for (ResourceReader resourceReader : ServiceLoader.load(ResourceReader.class)) {
readers.add(resourceReader);
}
// Classloader for deployment
for (ResourceReader resourceReader : ServiceLoader.load(ResourceReader.class, ResourceUtil.class.getClassLoader())) {
if (!isReaderFound(resourceReader)) {
readers.add(resourceReader);
}
}
readers.sort(new OrderComparator());
}
private boolean isReaderFound(ResourceReader resourceReader) {
boolean result = false;
for (ResourceReader reader : readers) {
// We need to check the class here, but since we are using FQCN Sonar check can be disabled here.
if (reader.getClass().getName().equals(resourceReader.getClass().getName())) { // NOSONAR
result = true;
}
}
return result;
}
/**
* Returns {@code true} if the resource can be read by an implementation (based on the prefix in most cases)
*
* @param resourcePath Location of the resource to be tested.
* @return true when resource can be read, false otherwise.
*/
public boolean isSupported(String resourcePath) {
return isSupported(resourcePath, null);
}
/**
* Returns {@code true} if the resource can be read by an implementation (based on the prefix in most cases)
*
* @param resourcePath Location of the resource to be tested.
* @param context Optional value defining the context (like servletContext) from which resource must be read
* @return true when resource can be read, false otherwise.
*/
public boolean isSupported(String resourcePath, Object context) {
if (StringUtils.isEmpty(resourcePath)) {
// When null or empty, we can't read it!
return false;
}
boolean result = false;
Iterator iterator = getInstance().readers.iterator();
while (!result && iterator.hasNext()) {
result = iterator.next().canRead(resourcePath, context);
}
return result;
}
/**
* Returns {@code true} if the resource at the specified path exists, {@code false} otherwise. This
* method supports scheme prefixes on the path.
*
* @param resourcePath the path of the resource to check.
* @return {@code true} if the resource at the specified path exists, {@code false} otherwise.
*/
public boolean resourceExists(String resourcePath) {
return resourceExists(resourcePath, null);
}
/**
* Returns {@code true} if the resource at the specified path exists, {@code false} otherwise. This
* method supports scheme prefixes on the path.
*
* @param resourcePath the path of the resource to check.
* @param context Optional value defining the context (like servletContext) from which resource must be read
* @return {@code true} if the resource at the specified path exists, {@code false} otherwise.
*/
public boolean resourceExists(String resourcePath, Object context) {
boolean result = false;
Iterator iterator = getInstance().readers.iterator();
while (!result && iterator.hasNext()) {
result = iterator.next().exists(resourcePath, context);
}
return result;
}
/**
* Returns the InputStream for the resource represented by the specified path, supporting scheme
* prefixes that direct how to acquire the input stream
* ({@link #CLASSPATH_PREFIX CLASSPATH_PREFIX},
* {@link #URL_PREFIX URL_PREFIX}, or {@link #FILE_PREFIX FILE_PREFIX}). If the path is not prefixed by one
* of these schemes, the path is assumed to be a file-based path that can be loaded with a
* {@link FileInputStream FileInputStream}.
*
* @param path the String path representing the resource to obtain.
* @return the InputStream for the specified resource.
* @throws IOException if there is a problem acquiring the resource at the specified path.
*/
public InputStream getStream(String path) throws IOException {
return getStream(path, null);
}
/**
* Returns the InputStream for the resource represented by the specified path, supporting scheme
* prefixes that direct how to acquire the input stream
* ({@link #CLASSPATH_PREFIX CLASSPATH_PREFIX},
* {@link #URL_PREFIX URL_PREFIX}, or {@link #FILE_PREFIX FILE_PREFIX}). If the path is not prefixed by one
* of these schemes, the path is assumed to be a file-based path that can be loaded with a
* {@link FileInputStream FileInputStream}.
*
* @param path the String path representing the resource to obtain.
* @param context Optional value defining the context (like servletContext) from which resource must be read
* @return the InputStream for the specified resource.
* @throws IOException if there is a problem acquiring the resource at the specified path.
*/
public InputStream getStream(String path, Object context) throws IOException {
InputStream result = null;
if (StringUtils.hasText(path)) {
Iterator iterator = getInstance().readers.iterator();
while (result == null && iterator.hasNext()) {
ResourceReader reader = iterator.next();
if (reader.canRead(path, context)) {
result = reader.load(path, context);
}
}
}
return result;
}
/**
* Returns the content of the resource represented by the specified path. Underlying, it uses
* {@code getStream} to access the resource.
*
* @param path the String path representing the resource to obtain.
* @return the content of the resource or null when resource could not be handled (unknown type)
* @throws IOException if there is a problem acquiring the resource at the specified path.
*/
public String getContent(String path) throws IOException {
return getContent(path, null);
}
/**
* Returns the content of the resource represented by the specified path. Underlying, it uses
* {@code getStream} to access the resource.
*
* @param path the String path representing the resource to obtain.
* @param context Optional value defining the context (like servletContext) from which resource must be read
* @return the content of the resource or null when resource could not be handled (unknown type)
* @throws IOException if there is a problem acquiring the resource at the specified path.
*/
public String getContent(String path, Object context) throws IOException {
InputStream stream = getStream(path, context);
if (stream == null) {
return null;
}
Scanner s = new Scanner(stream).useDelimiter("\\A");
String result = s.hasNext() ? s.next() : "";
stream.close();
return result;
}
public List getResources(String resourcePath) {
List result = new ArrayList<>();
readers.forEach(rr -> result.addAll(rr.getResources(resourcePath)));
return result;
}
public static synchronized ResourceUtil getInstance() {
// Synchronize methods are not so bad for performance anymore and since only 1 synchronized static there are no side effects
if (INSTANCE == null) {
INSTANCE = new ResourceUtil();
}
return INSTANCE;
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy