package com.brightgenerous.commons;
import static com.brightgenerous.commons.ObjectUtils.*;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.Reader;
import java.io.Serializable;
import java.lang.ref.SoftReference;
import java.util.HashSet;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Properties;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import com.brightgenerous.commons.crypto.CryptoUtils;
import com.brightgenerous.lang.Args;
public class ResourceUtils implements Serializable {
private static final long serialVersionUID = 9090432624771374976L;
static class InstanceKey implements Serializable {
private static final long serialVersionUID = 7729994660988922129L;
private final Class<?> clazz;
private final String file;
private final String encode;
public InstanceKey(Class<?> clazz, String file, String encode) {
this.clazz = clazz;
this.file = file;
this.encode = encode;
}
@Override
public int hashCode() {
final int multiplier = 37;
int result = 17;
result = (multiplier * result) + hashCodeEscapeNull(clazz);
result = (multiplier * result) + hashCodeEscapeNull(file);
result = (multiplier * result) + hashCodeEscapeNull(encode);
return result;
}
@Override
public boolean equals(Object obj) {
if (obj == null) {
return false;
}
if (!(obj instanceof InstanceKey)) {
return false;
}
InstanceKey other = (InstanceKey) obj;
if (!equalsEscapeNull(clazz, other.clazz)) {
return false;
}
if (!equalsEscapeNull(file, other.file)) {
return false;
}
if (!equalsEscapeNull(encode, other.encode)) {
return false;
}
return true;
}
}
private final Class<?> clazz;
private final String file;
private final String encode;
protected ResourceUtils(Class<?> clazz, String file, String encode) {
Args.notNull(file, "file");
this.clazz = clazz;
this.file = file;
this.encode = encode;
}
public static ResourceUtils get(String file) {
return get(file, null);
}
public static ResourceUtils get(String file, String encode) {
return get(null, file, encode);
}
public static ResourceUtils get(Class<?> clazz, String file) {
return get(clazz, file, null);
}
public static ResourceUtils get(Class<?> clazz, String file, String encode) {
return getInstance(clazz, file, encode);
}
private static volatile Map<InstanceKey, SoftReference<ResourceUtils>> cache;
protected static ResourceUtils getInstance(Class<?> clazz, String file, String encode) {
if (cache == null) {
synchronized (CryptoUtils.class) {
if (cache == null) {
cache = new ConcurrentHashMap<>();
}
}
}
InstanceKey ik = new InstanceKey(clazz, file, encode);
SoftReference<ResourceUtils> sr = cache.get(ik);
ResourceUtils ret;
if (sr != null) {
ret = sr.get();
if (ret != null) {
return ret;
}
Set<InstanceKey> dels = new HashSet<>();
for (Entry<InstanceKey, SoftReference<ResourceUtils>> entry : cache.entrySet()) {
if (entry.getValue().get() == null) {
dels.add(entry.getKey());
}
}
for (InstanceKey del : dels) {
cache.remove(del);
}
}
ret = new ResourceUtils(clazz, file, encode);
cache.put(ik, new SoftReference<>(ret));
return ret;
}
public InputStream getInputStream() {
return getInputStream(clazz, file);
}
public Reader getReader() throws IOException {
return getReader(clazz, file, encode);
}
public String readAsString() throws IOException {
return readAsString(clazz, file, encode);
}
public Properties readAsPropetries() throws IOException {
return readAsPropetries(clazz, file, encode);
}
public static InputStream getInputStream(String file) {
return getInputStream(null, file);
}
public static InputStream getInputStream(Class<?> clazz, String file) {
Args.notNull(file, "file");
if (clazz == null) {
return ClassLoader.getSystemResourceAsStream(file);
}
return clazz.getResourceAsStream(file);
}
public static Reader getReader(String file) throws IOException {
return getReader(file, null);
}
public static Reader getReader(String file, String encode) throws IOException {
return getReader(null, file, encode);
}
public static Reader getReader(Class<?> clazz, String file) throws IOException {
return getReader(clazz, file, null);
}
public static Reader getReader(Class<?> clazz, String file, String encode) throws IOException {
Args.notNull(file, "file");
InputStream inputStream = getInputStream(clazz, file);
if (inputStream == null) {
return null;
}
if (encode == null) {
return new InputStreamReader(inputStream);
}
return new InputStreamReader(inputStream, encode);
}
public static String readAsString(String file) throws IOException {
return readAsString(file, null);
}
public static String readAsString(String file, String encode) throws IOException {
return readAsString(null, file, encode);
}
public static String readAsString(Class<?> clazz, String file) throws IOException {
return readAsString(clazz, file, null);
}
public static String readAsString(Class<?> clazz, String file, String encode)
throws IOException {
Args.notNull(file, "file");
String ret = null;
InputStream inputStream = getInputStream(clazz, file);
if (inputStream != null) {
BufferedReader bufferedReader;
if (encode == null) {
bufferedReader = new BufferedReader(new InputStreamReader(inputStream));
} else {
bufferedReader = new BufferedReader(new InputStreamReader(inputStream, encode));
}
try (BufferedReader br = bufferedReader) {
StringBuilder sb = new StringBuilder();
String line;
while ((line = bufferedReader.readLine()) != null) {
sb.append(line);
sb.append(System.lineSeparator());
}
ret = sb.toString();
}
}
return ret;
}
public static Properties readAsPropetries(String file) throws IOException {
return readAsPropetries(file, null);
}
public static Properties readAsPropetries(String file, String encode) throws IOException {
return readAsPropetries(null, file, encode);
}
public static Properties readAsPropetries(Class<?> clazz, String file) throws IOException {
return readAsPropetries(clazz, file, null);
}
public static Properties readAsPropetries(Class<?> clazz, String file, String encode)
throws IOException {
Args.notNull(file, "file");
Properties ret = null;
InputStream inputStream = getInputStream(clazz, file);
if (inputStream != null) {
if (encode == null) {
try (InputStream is = inputStream) {
ret = new Properties();
ret.load(is);
}
} else {
try (Reader r = new InputStreamReader(inputStream, encode)) {
ret = new Properties();
ret.load(r);
}
}
}
return ret;
}
@Override
public int hashCode() {
if (HashCodeUtils.resolved()) {
return HashCodeUtils.hashCodeAlt(null, this);
}
return super.hashCode();
}
@Override
public boolean equals(Object obj) {
if (EqualsUtils.resolved()) {
return EqualsUtils.equalsAlt(null, this, obj);
}
return super.equals(obj);
}
@Override
public String toString() {
if (ToStringUtils.resolved()) {
return ToStringUtils.toStringAlt(this);
}
return super.toString();
}
}