package com.revolsys.spring.resource;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.io.Reader;
import java.io.Writer;
import java.net.URI;
import java.net.URL;
import java.net.URLConnection;
import java.nio.ByteOrder;
import java.nio.channels.Channels;
import java.nio.channels.ReadableByteChannel;
import java.nio.channels.WritableByteChannel;
import java.nio.charset.Charset;
import java.nio.file.Path;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.function.Function;
import java.util.function.Predicate;
import com.revolsys.collection.list.Lists;
import com.revolsys.io.FileNames;
import com.revolsys.io.FileUtil;
import com.revolsys.io.channels.ChannelReader;
import com.revolsys.io.channels.ChannelWriter;
import com.revolsys.io.file.Paths;
import com.revolsys.predicate.Predicates;
import com.revolsys.util.Exceptions;
import com.revolsys.util.Property;
public interface Resource extends org.springframework.core.io.Resource {
static String CLASSPATH_URL_PREFIX = "classpath:";
ThreadLocal<Resource> BASE_RESOURCE = new ThreadLocal<>();
static boolean exists(final Resource resource) {
if (resource == null) {
return false;
} else {
return resource.exists();
}
}
static Resource getBaseResource() {
final Resource baseResource = Resource.BASE_RESOURCE.get();
if (baseResource == null) {
return new FileSystemResource(FileUtil.getCurrentDirectory());
} else {
return baseResource;
}
}
static Resource getBaseResource(final String childPath) {
final Resource baseResource = getBaseResource();
return baseResource.newChildResource(childPath);
}
static File getFileOrCreateTempFile(final Resource resource) {
try {
if (resource instanceof FileSystemResource) {
return resource.getFile();
} else {
final String filename = resource.getFilename();
final String baseName = FileUtil.getBaseName(filename);
final String fileExtension = FileNames.getFileNameExtension(filename);
return File.createTempFile(baseName, fileExtension);
}
} catch (final IOException e) {
throw new RuntimeException("Unable to get file for " + resource, e);
}
}
static File getOrDownloadFile(final Resource resource) {
try {
return resource.getFile();
} catch (final Throwable e) {
if (resource.exists()) {
final String baseName = resource.getBaseName();
final String fileNameExtension = resource.getFileNameExtension();
final File file = FileUtil.newTempFile(baseName, fileNameExtension);
FileUtil.copy(resource.getInputStream(), file);
return file;
} else {
throw new IllegalArgumentException("Cannot get File for resource " + resource, e);
}
}
}
static Resource getResource(final Object source) {
if (source == null) {
return null;
} else if (source instanceof Resource) {
return (Resource)source;
} else if (source instanceof Path) {
return new PathResource((Path)source);
} else if (source instanceof File) {
return new FileSystemResource((File)source);
} else if (source instanceof URL) {
return new UrlResource((URL)source);
} else if (source instanceof URI) {
return new UrlResource((URI)source);
} else if (source instanceof CharSequence) {
return getResource(source.toString());
} else if (source instanceof InputStream) {
return new InputStreamResource((InputStream)source);
} else if (source instanceof OutputStream) {
return new OutputStreamResource("", (OutputStream)source);
} else if (source instanceof org.springframework.core.io.Resource) {
if (source instanceof org.springframework.core.io.ClassPathResource) {
final org.springframework.core.io.ClassPathResource springResource = (org.springframework.core.io.ClassPathResource)source;
return new ClassPathResource(springResource.getPath(), springResource.getClassLoader());
} else if (source instanceof org.springframework.core.io.FileSystemResource) {
final org.springframework.core.io.FileSystemResource springResource = (org.springframework.core.io.FileSystemResource)source;
return new FileSystemResource(springResource.getFile());
} else if (source instanceof org.springframework.core.io.PathResource) {
final org.springframework.core.io.PathResource springResource = (org.springframework.core.io.PathResource)source;
return new PathResource(springResource.getPath());
} else if (source instanceof org.springframework.core.io.UrlResource) {
final org.springframework.core.io.UrlResource springResource = (org.springframework.core.io.UrlResource)source;
try {
return new UrlResource(springResource.getURL());
} catch (final IOException e) {
throw Exceptions.wrap(e);
}
}
}
throw new IllegalArgumentException(source.getClass() + " is not supported");
}
static Resource getResource(final String location) {
if (Property.hasValue(location)) {
if (location.charAt(0) == '/' || location.length() > 1 && location.charAt(1) == ':') {
return new PathResource(location);
} else if (location.startsWith(CLASSPATH_URL_PREFIX)) {
final ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
final String path = location.substring(CLASSPATH_URL_PREFIX.length());
return new ClassPathResource(path, classLoader);
} else {
return new UrlResource(location);
}
}
return null;
}
static Resource setBaseResource(final Resource baseResource) {
final Resource oldResource = Resource.BASE_RESOURCE.get();
Resource.BASE_RESOURCE.set(baseResource);
return oldResource;
}
default String contentsAsString() {
final Reader reader = newReader();
return FileUtil.getString(reader);
}
default void copyFrom(final InputStream in) {
try (
final InputStream in2 = in;
final OutputStream out = newBufferedOutputStream();) {
FileUtil.copy(in2, out);
} catch (final IOException e) {
throw Exceptions.wrap(e);
}
}
default void copyFrom(final Resource source) {
if (source != null) {
try (
final InputStream in = source.newBufferedInputStream()) {
copyFrom(in);
} catch (final IOException e) {
throw Exceptions.wrap(e);
}
}
}
default void copyTo(final OutputStream out) {
try (
final OutputStream out2 = out;
final InputStream in = newBufferedInputStream();) {
FileUtil.copy(in, out2);
} catch (final IOException e) {
throw Exceptions.wrap(e);
}
}
default void copyTo(final Resource target) {
if (target != null) {
target.copyFrom(this);
}
}
default boolean createParentDirectories() {
return false;
}
@Override
Resource createRelative(String relativePath);
default boolean delete() {
return false;
}
default String getBaseName() {
final String filename = getFilename();
return FileNames.getBaseName(filename);
}
default List<String> getChildFileNames() {
if (isFile()) {
final File file = getFile();
final List<String> childFileNames = Lists.newArray(file.list());
Collections.sort(childFileNames);
return childFileNames;
} else {
return Collections.emptyList();
}
}
default List<String> getChildFileNames(final Predicate<String> filter) {
final List<String> fileNames = getChildFileNames();
return Predicates.filter(fileNames, filter);
}
default List<Resource> getChildren() {
final List<Resource> children = new ArrayList<>();
for (final String fileName : getChildFileNames()) {
final Resource newChildResource = newChildResource(fileName);
children.add(newChildResource);
}
return children;
}
default List<Resource> getChildren(final Predicate<String> filter) {
final List<Resource> children = new ArrayList<>();
for (final String fileName : getChildFileNames(filter)) {
final Resource newChildResource = newChildResource(fileName);
children.add(newChildResource);
}
return children;
}
@Override
File getFile();
default String getFileNameExtension() {
final String filename = getFilename();
return FileNames.getFileNameExtension(filename);
}
@Override
InputStream getInputStream();
default long getLastModified() {
try {
return lastModified();
} catch (final IOException e) {
return Long.MAX_VALUE;
}
}
default Resource getParent() {
return null;
}
default URI getUri() {
try {
return getURI();
} catch (final IOException e) {
throw Exceptions.wrap(e);
}
}
default String getUriString() {
final URI uri = getUri();
if (uri == null) {
return null;
} else {
return uri.toString();
}
}
@Override
URL getURL();
default boolean isFile() {
try {
getFile();
return true;
} catch (final Throwable e) {
return false;
}
}
default InputStream newBufferedInputStream() {
final InputStream in = newInputStream();
return new BufferedInputStream(in);
}
default <IS, IS2 extends IS> IS newBufferedInputStream(final Function<InputStream, IS2> factory) {
final InputStream out = newBufferedInputStream();
return factory.apply(out);
}
default OutputStream newBufferedOutputStream() {
final OutputStream out = newOutputStream();
return new BufferedOutputStream(out);
}
default <OS extends OutputStream> OS newBufferedOutputStream(
final Function<OutputStream, OS> factory) {
final OutputStream out = newBufferedOutputStream();
return factory.apply(out);
}
default BufferedReader newBufferedReader() {
final Reader in = newReader();
return new BufferedReader(in);
}
default ChannelReader newChannelReader() {
return newChannelReader(8096, ByteOrder.BIG_ENDIAN);
}
default ChannelReader newChannelReader(final int capacity) {
return newChannelReader(capacity, ByteOrder.BIG_ENDIAN);
}
default ChannelReader newChannelReader(final int capacity, final ByteOrder byteOrder) {
final ReadableByteChannel in = newReadableByteChannel();
return new ChannelReader(in, capacity, byteOrder);
}
default ChannelWriter newChannelWriter() {
return newChannelWriter(8096, ByteOrder.BIG_ENDIAN);
}
default ChannelWriter newChannelWriter(final int capacity) {
return newChannelWriter(capacity, ByteOrder.BIG_ENDIAN);
}
default ChannelWriter newChannelWriter(final int capacity, final ByteOrder byteOrder) {
final WritableByteChannel in = newWritableByteChannel();
return new ChannelWriter(in, capacity, byteOrder);
}
default Resource newChildResource(final CharSequence childPath) {
return createRelative(childPath.toString());
}
default InputStream newInputStream() {
return getInputStream();
}
default OutputStream newOutputStream() {
try {
final URL url = getURL();
final String protocol = url.getProtocol();
if (protocol.equals("file") || protocol.equals("folderconnection")) {
final File file = getFile();
final File parentFile = file.getParentFile();
if (parentFile != null) {
parentFile.mkdirs();
}
return new FileOutputStream(file);
} else {
final URLConnection connection = url.openConnection();
connection.setDoOutput(true);
return connection.getOutputStream();
}
} catch (final IOException e) {
throw Exceptions.wrap(e);
}
}
default PrintWriter newPrintWriter() {
final Writer writer = newWriter();
return new PrintWriter(writer);
}
default ReadableByteChannel newReadableByteChannel() {
final InputStream in = newInputStream();
return Channels.newChannel(in);
}
default Reader newReader() {
final InputStream in = getInputStream();
return FileUtil.newUtf8Reader(in);
}
default Resource newResourceAddExtension(final String extension) {
final String fileName = getFilename();
final String newFileName = fileName + "." + extension;
final Resource parent = getParent();
if (parent == null) {
return null;
} else {
return parent.newChildResource(newFileName);
}
}
default Resource newResourceChangeExtension(final String extension) {
final String baseName = getBaseName();
final String newFileName = baseName + "." + extension;
final Resource parent = getParent();
if (parent == null) {
return null;
} else {
return parent.newChildResource(newFileName);
}
}
default WritableByteChannel newWritableByteChannel() {
final OutputStream out = newOutputStream();
return Channels.newChannel(out);
}
default Writer newWriter() {
final OutputStream stream = newOutputStream();
return FileUtil.newUtf8Writer(stream);
}
default Writer newWriter(final Charset charset) {
final OutputStream stream = newOutputStream();
return new OutputStreamWriter(stream, charset);
}
default Path toPath() {
if (isFile()) {
final Path path = getFile().toPath();
if (Paths.exists(path)) {
try {
return path.toRealPath();
} catch (final IOException e) {
return path;
}
} else {
return path;
}
} else {
return null;
}
}
}