package com.koushikdutta.ion; import com.google.gson.JsonArray; import com.google.gson.JsonObject; import com.google.gson.reflect.TypeToken; import com.koushikdutta.async.callback.CompletedCallback; import com.koushikdutta.async.future.Future; import com.koushikdutta.async.future.SimpleFuture; import com.koushikdutta.async.parser.AsyncParser; import com.koushikdutta.async.parser.DocumentParser; import com.koushikdutta.async.parser.StringParser; import com.koushikdutta.async.stream.FileDataSink; import com.koushikdutta.async.util.FileCache; import com.koushikdutta.ion.gson.GsonArrayParser; import com.koushikdutta.ion.gson.GsonObjectParser; import com.koushikdutta.ion.gson.GsonSerializer; import org.w3c.dom.Document; import java.io.File; /** * Created by koush on 11/17/13. */ public class FileCacheStore { Ion ion; FileCache cache; String rawKey; FileCacheStore(Ion ion, FileCache cache, String rawKey) { this.ion = ion; this.cache = cache; this.rawKey = rawKey; } private <T> Future<T> put(final T value, final AsyncParser<T> parser) { final SimpleFuture<T> ret = new SimpleFuture<T>(); Ion.getIoExecutorService().execute(new Runnable() { @Override public void run() { final String key = computeKey(); final File file = cache.getTempFile(); final FileDataSink sink = new FileDataSink(ion.getServer(), file); parser.write(sink, value, new CompletedCallback() { @Override public void onCompleted(Exception ex) { sink.end(); if (ex != null) { file.delete(); ret.setComplete(ex); return; } cache.commitTempFiles(key, file); ret.setComplete(value); } }); } }); return ret; } public Future<String> putString(String value) { return put(value, new StringParser()); } public Future<JsonObject> putJsonObject(JsonObject value) { return put(value, new GsonObjectParser()); } public Future<Document> putDocument(Document value) { return put(value, new DocumentParser()); } public Future<JsonArray> putJsonArray(JsonArray value) { return put(value, new GsonArrayParser()); } /* public Future<InputStream> putInputStream(InputStream value) { throw new AssertionError("not implemented"); } public Future<byte[]> putByteArray(byte[] bytes) { throw new AssertionError("not implemented"); } */ public <T> Future<T> put(T value, Class<T> clazz) { return put(value, new GsonSerializer<T>(ion.configure().getGson(), clazz)); } public <T> Future<T> put(T value, TypeToken<T> token) { return put(value, new GsonSerializer<T>(ion.configure().getGson(), token)); } private <T> Future<T> as(final AsyncParser<T> parser) { final SimpleFuture<T> ret = new SimpleFuture<T>(); Ion.getIoExecutorService().execute(new Runnable() { @Override public void run() { try { final String key = computeKey(); final File file = cache.getFile(key); if (!file.exists()) { ret.setComplete((T)null); return; } ion.build(ion.getContext()).load(file) .as(parser) .setCallback(ret.getCompletionCallback()); } catch (Exception e) { ret.setComplete(e); } } }); return ret; } private <T> T get(final AsyncParser<T> parser) { try { final String key = computeKey(); final File file = cache.getFile(key); return ion.build(ion.getContext()).load(file) .as(parser) .get(); } catch (Exception e) { return null; } } public String getString() { return get(new StringParser()); } public Future<String> asString() { return as(new StringParser()); } public Future<JsonObject> asJsonObject() { return as(new GsonObjectParser()); } public JsonObject getJsonObject() { return get(new GsonObjectParser()); } public Future<JsonArray> asJsonArray() { return as(new GsonArrayParser()); } public JsonArray getJsonArray() { return get(new GsonArrayParser()); } public Future<Document> asDocument() { return as(new DocumentParser()); } public Document getDocument() { return get(new DocumentParser()); } public <T> Future<T> as(Class<T> clazz) { return as(new GsonSerializer<T>(ion.configure().getGson(), clazz)); } public <T> T get(Class<T> clazz) { return get(new GsonSerializer<T>(ion.configure().getGson(), clazz)); } public <T> Future<T> as(TypeToken<T> token) { return as(new GsonSerializer<T>(ion.configure().getGson(), token)); } public <T> T get(TypeToken<T> token) { return get(new GsonSerializer<T>(ion.configure().getGson(), token)); } private String computeKey() { return rawKey.replace(":", "_"); } public void remove() { final String key = computeKey(); cache.remove(key); } }