package com.eveinfo.api;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.UnsupportedEncodingException;
import java.net.URL;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.Map.Entry;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
import org.xml.sax.XMLReader;
import com.eveinfo.tools.Logging;
public abstract class AbstractApiParser<E extends ApiResponse, J extends AbstractApiHandler<E>> {
protected enum Path {
CORP("/corp"), CHARACTER("/char"), NONE("");
private final String path;
Path(String path) {
this.path = path;
}
public String getPath() {
return path;
}
};
private final String filename = "cacheFile.ser";
public static final String EVE_API_SERVER = "api.eve-online.com";
public static final String EVE_API_URL = "http://" + EVE_API_SERVER;
// protected static final String EVE_API_URL = "http://eveapiproxy.appspot.com";
protected static final String CORP_PATH = "/corp";
protected static final String CHAR_PATH = "/char";
// TODO changer.
public static String CACHE_DIR = "/data/data/com.eveinfo/app_cache";
private final Class<E> clazz;
private final int apiVersion;
protected final Map<String, E> cache = new HashMap<String, E>();
private final String pageURL;
private boolean cachingEnabled = false;
private boolean serializeCaching = false;
private boolean cacheOnly = false;
public AbstractApiParser(Class<E> clazz, int apiVersion, String pageURL) {
this.clazz = clazz;
this.apiVersion = apiVersion;
this.pageURL = pageURL;
deSerializeCache();
}
protected boolean isCached(String requestUrl) {
boolean containsKey = cache.containsKey(requestUrl);
if (containsKey) {
if (cacheOnly) {
return true;
}
E cachedResponse = cache.get(requestUrl);
Date cachedUntil = cachedResponse.getCachedUntil();
Date now = Calendar.getInstance().getTime();
return cachedUntil.after(now);
}
return false;
}
private String getRequestUrl(ApiAuth auth, String pageURL) throws UnsupportedEncodingException {
return getRequestUrl(auth, Path.NONE, pageURL);
}
private String getRequestUrl(ApiAuth auth, Path path, String pageURL) throws UnsupportedEncodingException {
String requestUrl = EVE_API_URL;
requestUrl += path.getPath();
requestUrl += pageURL;
requestUrl += auth.getUrlParams();
requestUrl += "&version=" + apiVersion;
return requestUrl;
}
protected E getResponse(ApiAuth auth, Path path, J handler) throws IOException, SAXException,
ParserConfigurationException, ApiException, NoCacheFoundExecption {
return getResponse(getRequestUrl(auth, path, pageURL), handler);
}
protected E getResponse(ApiAuth auth, J handler) throws IOException, SAXException, ParserConfigurationException,
ApiException, NoCacheFoundExecption {
return getResponse(getRequestUrl(auth, pageURL), handler);
}
protected E getResponse(ApiAuth auth, Map<String, String> extraParams, J handler) throws IOException, SAXException,
ParserConfigurationException, ApiException, NoCacheFoundExecption {
String requestUrl = getRequestUrl(auth, pageURL);
for (Entry<String, String> entry : extraParams.entrySet()) {
requestUrl += "&" + entry.getKey() + "=" + entry.getValue();
}
return getResponse(requestUrl, handler);
}
protected E getResponse(Map<String, String> extraParams, J handler) throws IOException, SAXException,
ParserConfigurationException, ApiException, NoCacheFoundExecption {
String requestUrl = EVE_API_URL + pageURL;
boolean first = true;
for (Entry<String, String> entry : extraParams.entrySet()) {
if (first)
requestUrl += "?";
else
requestUrl += "&";
requestUrl += entry.getKey() + "=" + entry.getValue();
first = false;
}
return getResponse(requestUrl, handler);
}
protected E getResponse(String paramName, String paramValue, J handler) throws IOException, SAXException,
ParserConfigurationException, ApiException, NoCacheFoundExecption {
System.out.println(paramValue);
return getResponse(EVE_API_URL + pageURL + "?" + paramName + "=" + paramValue, handler);
}
protected E getResponse(J handler) throws IOException, SAXException, ParserConfigurationException, ApiException,
NoCacheFoundExecption {
return getResponse(EVE_API_URL + pageURL, handler);
}
private E getResponse(String requestUrl, J handler) throws ParserConfigurationException, SAXException, IOException,
ApiException, NoCacheFoundExecption {
requestUrl = requestUrl.replace(" ", "%20");
if (isCachingEnabled() && isCached(requestUrl)) {
System.out.println("cache : " + requestUrl);
return cache.get(requestUrl);
}
if (isCacheOnly()) {
throw new NoCacheFoundExecption();
}
System.out.println("url : " + requestUrl);
SAXParserFactory spf = SAXParserFactory.newInstance();
SAXParser sp = spf.newSAXParser();
XMLReader xr = sp.getXMLReader();
xr.setContentHandler(handler);
xr.parse(new InputSource(new URL(requestUrl).openStream()));
E response = (E) handler.getParsedData();
if (isCachingEnabled()) {
cache.put(requestUrl, response);
serializeCache();
}
return response;
}
synchronized private void serializeCache() {
if (!(isCachingEnabled() && isSerializeCaching()))
return;
try {
FileOutputStream fos = new FileOutputStream(getCacheFile());
ObjectOutputStream out = new ObjectOutputStream(fos);
out.writeObject(cache);
out.close();
} catch (IOException e) {
Logging.getInstance().e(e);
e.printStackTrace();
}
}
@SuppressWarnings("unchecked")
synchronized public void deSerializeCache() {
if (!(isCachingEnabled() && isSerializeCaching())) {
return;
}
try {
File cacheFile = getCacheFile();
if (!(cacheFile.exists() && cacheFile.canRead())) {
return;
}
FileInputStream fis = new FileInputStream(cacheFile);
ObjectInputStream in = new ObjectInputStream(fis);
try {
Map<String, E> oldCache = (Map<String, E>) in.readObject();
cache.putAll(oldCache);
} catch (ClassNotFoundException e) {
Logging.getInstance().e(e);
e.printStackTrace();
}
in.close();
} catch (IOException e) {
Logging.getInstance().e(e);
e.printStackTrace();
}
}
private File getCacheFile() {
String cacheFilename = clazz.getCanonicalName() + "_" + filename;
return new File(CACHE_DIR, cacheFilename);
}
public boolean isCachingEnabled() {
return cachingEnabled;
}
public void setCachingEnabled(boolean cachingEnabled) {
this.cachingEnabled = cachingEnabled;
}
public boolean isSerializeCaching() {
return serializeCaching;
}
public void setSerializeCaching(boolean serializeCaching) {
this.serializeCaching = serializeCaching;
}
public void clearCache() {
this.cache.clear();
}
public void setCacheOnly(boolean cacheOnly) {
this.cacheOnly = cacheOnly;
}
public boolean isCacheOnly() {
return cacheOnly;
}
}
|