com.ovea.tadjin.util.Resource Maven / Gradle / Ivy
The newest version!
/**
* Copyright (C) 2011 Ovea
*
* 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.ovea.tadjin.util;
import java.io.*;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLConnection;
import java.nio.channels.Channels;
import java.nio.channels.FileChannel;
import java.nio.channels.WritableByteChannel;
import java.util.Arrays;
public abstract class Resource {
private Resource() {
}
public abstract URL toURL();
public abstract File toFile();
public abstract InputStream read();
public abstract OutputStream write();
public abstract String readAsString();
public abstract byte[] readAsBytes();
public abstract boolean isFile();
public abstract boolean isURL();
public abstract boolean exist();
@Override
public abstract String toString();
@Override
public abstract boolean equals(Object obj);
@Override
public abstract int hashCode();
public void transferTo(File dest) {
dest.getParentFile().mkdirs();
if (isFile()) {
try {
transfer(toFile(), new RandomAccessFile(dest, "rw").getChannel());
} catch (FileNotFoundException e) {
throw new ResourceException(this, e.getMessage(), e);
} catch (IOException e) {
throw new ResourceException(this, e.getMessage(), e);
}
} else {
try {
transfer(read(), new FileOutputStream(dest));
} catch (FileNotFoundException e) {
throw new ResourceException(this, e.getMessage(), e);
} catch (IOException e) {
throw new ResourceException(this, e.getMessage(), e);
}
}
}
/**
* classpath:
*
* file:
*
* http://...
*/
public static Resource from(String pattern) {
if (pattern == null)
throw new IllegalArgumentException("Missing parameter");
if (pattern.startsWith("classpath:"))
return from(Thread.currentThread().getContextClassLoader(), pattern.substring(10));
if (pattern.startsWith("file:"))
return new FileResource(new File(pattern.substring(5)));
try {
return new UrlResource(new URL(pattern));
} catch (MalformedURLException e) {
throw new IllegalArgumentException("Invalid resource " + pattern + " : " + e.getMessage(), e);
}
}
public static Resource from(ClassLoader classloader, String pattern) {
if (pattern == null)
throw new IllegalArgumentException("Missing parameter");
if (pattern.startsWith("/"))
pattern = pattern.substring(1);
return new ClassPathResource(classloader, pattern);
}
public static Resource from(File file) {
return new FileResource(file);
}
public static Resource from(URL url) {
return new UrlResource(url);
}
public static Resource fromData(String data) {
return new ByteResource(data.getBytes());
}
public static Resource fromData(byte[] data) {
return new ByteResource(data);
}
private static class ByteResource extends ReadOnlyBufferBasedResource {
private final byte[] data;
private ByteResource(byte[] data) {
this.data = data;
}
@Override
public InputStream read() {
try {
return new ByteArrayInputStream(data);
} catch (Exception e) {
throw new ResourceException(this, e.getMessage(), e);
}
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
ByteResource that = (ByteResource) o;
return Arrays.equals(data, that.data);
}
@Override
public int hashCode() {
return Arrays.hashCode(data);
}
}
private static final class ClassPathResource extends UrlBasedResource {
private final String path;
private final ClassLoader classloader;
private ClassPathResource(ClassLoader classloader, String path) {
this.path = path;
this.classloader = classloader;
}
@Override
public URL toURL() {
URL url = classloader.getResource(path);
if (url == null) {
throw new ResourceException(this, path + " cannot be found on classpath");
}
return url;
}
@Override
public String toString() {
return "classpath:" + path;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
ClassPathResource that = (ClassPathResource) o;
return path.equals(that.path);
}
@Override
public int hashCode() {
return path.hashCode();
}
@Override
public boolean exist() {
return classloader.getResource(path) != null;
}
}
private static final class UrlResource extends UrlBasedResource {
private final URL url;
private UrlResource(URL url) {
this.url = url;
}
@Override
public URL toURL() {
return url;
}
@Override
public String toString() {
return url.toString();
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
UrlResource that = (UrlResource) o;
return url.equals(that.url);
}
@Override
public int hashCode() {
return url.hashCode();
}
@Override
public boolean exist() {
InputStream is = null;
try {
is = toIS(url);
return true;
} catch (Exception e) {
return false;
} finally {
if (is != null) {
try {
is.close();
} catch (IOException ignored) {
}
}
}
}
}
private static final class FileResource extends UrlBasedResource {
private final File file;
private FileResource(File file) {
this.file = file;
}
@Override
public URL toURL() {
try {
return file.toURI().toURL();
} catch (Exception e) {
throw new ResourceException(this, e.getMessage(), e);
}
}
@Override
public String toString() {
return file.toString();
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
FileResource that = (FileResource) o;
return file.equals(that.file);
}
@Override
public int hashCode() {
return file.hashCode();
}
@Override
public boolean exist() {
return file.exists();
}
}
static abstract class UrlBasedResource extends Resource {
@Override
public final InputStream read() {
URL url = toURL();
File file = Resource.urlToFile(url);
try {
if (file != null)
return Channels.newInputStream(new RandomAccessFile(file, "r").getChannel());
return toIS(url);
} catch (IOException e) {
throw new ResourceException(this, e.getMessage(), e);
}
}
@Override
public final OutputStream write() {
URL url = toURL();
File file = Resource.urlToFile(url);
try {
if (file != null) {
return Channels.newOutputStream(new RandomAccessFile(file, "rw").getChannel());
}
URLConnection connection = url.openConnection();
connection.setUseCaches(false);
connection.connect();
return connection.getOutputStream();
} catch (IOException e) {
throw new ResourceException(this, e.getMessage(), e);
}
}
@Override
public final File toFile() {
URL url = toURL();
File file = Resource.urlToFile(url);
if (file == null)
throw new ResourceException(this, "Unable to convert " + url + " to a file");
return file;
}
@Override
public boolean isURL() {
return true;
}
@Override
public final String readAsString() {
return new String(readAsBytes());
}
@Override
public final byte[] readAsBytes() {
URL url = toURL();
File file = Resource.urlToFile(url);
try {
return file != null ? readBytes(file) : readBytes(url);
} catch (IOException e) {
throw new ResourceException(this, e.getMessage(), e);
}
}
@Override
public final boolean isFile() {
try {
return Resource.urlToFile(toURL()) != null;
} catch (Exception e) {
return false;
}
}
}
static abstract class ReadOnlyBufferBasedResource extends Resource {
@Override
public final File toFile() {
throw new UnsupportedOperationException();
}
@Override
public final String readAsString() {
return new String(readAsBytes());
}
@Override
public byte[] readAsBytes() {
try {
return readBytes(read());
} catch (IOException e) {
throw new ResourceException(this, e.getMessage(), e);
}
}
@Override
public final boolean isFile() {
return false;
}
@Override
public final boolean isURL() {
return false;
}
@Override
public String toString() {
return "";
}
@Override
public final URL toURL() {
throw new UnsupportedOperationException();
}
@Override
public final OutputStream write() {
throw new UnsupportedOperationException();
}
@Override
public boolean exist() {
return true;
}
}
static byte[] readBytes(URL url) throws IOException {
return readBytes(toIS(url));
}
static byte[] readBytes(File file) throws IOException {
FileChannel channel = null;
ByteArrayOutputStream baos = new ByteArrayOutputStream();
transfer(file, Channels.newChannel(baos));
return baos.toByteArray();
}
static void transfer(File src, WritableByteChannel out) throws IOException {
FileChannel channel = null;
try {
channel = new RandomAccessFile(src, "r").getChannel();
channel.transferTo(0, src.length(), out);
} finally {
if (channel != null) {
try {
channel.close();
} catch (IOException ignored) {
}
}
try {
out.close();
} catch (IOException ignored) {
}
}
}
static InputStream toIS(URL url) throws IOException {
URLConnection connection = url.openConnection();
connection.setUseCaches(false);
connection.connect();
return connection.getInputStream();
}
static byte[] readBytes(InputStream in) throws IOException {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
transfer(in, baos);
return baos.toByteArray();
}
static void transfer(InputStream in, OutputStream out) throws IOException {
try {
byte[] buffer = new byte[8196];
int c;
while ((c = in.read(buffer)) != -1)
out.write(buffer, 0, c);
} finally {
try {
in.close();
} catch (IOException ignored) {
}
try {
out.close();
} catch (IOException ignored) {
}
}
}
static File urlToFile(URL url) {
try {
return new File(url.toURI());
} catch (Exception e) {
return null;
}
}
}