DiskCachingLoader.java
package com.ljs.ootp.extract.html.loader;
import com.google.common.base.Charsets;
import com.google.common.base.Throwables;
import com.google.common.cache.AbstractCache;
import com.google.common.io.Files;
import java.io.File;
import java.io.IOException;
import java.net.URLEncoder;
import java.nio.charset.Charset;
import java.util.concurrent.Callable;
import org.apache.commons.lang3.StringUtils;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
/**
*
* @author lstephen
*/
public final class DiskCachingLoader implements PageLoader {
public static final String DEFAULT_CACHE_DIR = "c:/ootp/cache";
private final DiskCache cache;
private final PageLoader wrapped;
private DiskCachingLoader(String dir, PageLoader wrapped) {
cache = DiskCache.cachingTo(dir);
this.wrapped = wrapped;
}
@Override
public Document load(String url) {
return cache.get(url, PageLoaders.asCallable(wrapped, url));
}
private static final class DiskCache
extends AbstractCache<String, Document> {
private static final Charset CHARSET = Charsets.UTF_8;
private final String dir;
private DiskCache(String dir) {
super();
this.dir = dir;
}
private File getFileForKey(Object key) {
String pathName =
StringUtils.substringBeforeLast(key.toString(), "/");
try {
File path = new File(
dir,
URLEncoder.encode(pathName, CHARSET.name()));
String fileName =
StringUtils.substringAfterLast(key.toString(), "/");
File forKey = new File(
path,
URLEncoder.encode(fileName, CHARSET.name()));
Files.createParentDirs(forKey);
return forKey;
} catch (IOException e) {
throw Throwables.propagate(e);
}
}
@Override
public void put(String key, Document value) {
try {
Files.write(value.outerHtml(), getFileForKey(key), CHARSET);
} catch (IOException e) {
throw Throwables.propagate(e);
}
}
@Override
public Document get(String key, Callable<? extends Document> callable) {
Document doc = getIfPresent(key);
if (doc == null) {
try {
put(key, callable.call());
} catch (Exception e) {
throw Throwables.propagate(e);
}
return getIfPresent(key);
} else {
return doc;
}
}
@Override
public Document getIfPresent(Object key) {
File f = getFileForKey(key);
if (f.exists()) {
try {
return Jsoup.parse(f, CHARSET.name());
} catch (IOException e) {
throw Throwables.propagate(e);
}
} else {
return null;
}
}
public static DiskCache cachingTo(String dir) {
return new DiskCache(dir);
}
}
public static DiskCachingLoader wrap(PageLoader loader) {
return create(DEFAULT_CACHE_DIR, loader);
}
public static DiskCachingLoader create(String dir, PageLoader loader) {
return new DiskCachingLoader(dir, loader);
}
}