package com.servershepherd.beume;
import java.io.IOException;
import java.util.HashMap;
import java.util.logging.Level;
import java.util.logging.Logger;
import net.sf.ehcache.Element;
import net.sf.ehcache.constructs.blocking.UpdatingCacheEntryFactory;
import org.apache.commons.httpclient.Header;
import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.HttpStatus;
import org.apache.commons.httpclient.MultiThreadedHttpConnectionManager;
import org.apache.commons.httpclient.URI;
import org.apache.commons.httpclient.URIException;
import org.apache.commons.httpclient.methods.GetMethod;
/**
*
* @author marc
*/
class BackCacheUpdater implements UpdatingCacheEntryFactory {
HttpClient client;
public BackCacheUpdater() {
MultiThreadedHttpConnectionManager connectionManager = new MultiThreadedHttpConnectionManager();
client = new HttpClient(connectionManager);
}
@Override
public void updateEntryValue(Object key, Object value) throws Exception {
Object im=getImage(key);
// Do not update the entry if its returning errors
if (im instanceof String) return;
value=im;
}
@Override
public Object createEntry(Object key) {
Object im=getImage(key);
if (im instanceof String) {
return new Element(key, im,0,CommonResources.BACK_ERROR_RETAIN_SECS);
}
return im;
}
private Object getImage(Object key) {
byte[] v ;
BackKey fk = (BackKey) key;
String message="Unknown error";
try {
GetMethod method = new GetMethod();
method.setURI(new URI(fk.source_url, true));
int returnCode = client.executeMethod(method);
if (returnCode == HttpStatus.SC_OK) {
HashMap<String, Object> headers = extractHeaders(method);
String contentType = (String) headers.get("content-type");
Integer contentLength = (Integer) headers.get("content-length");
if ((contentType != null) && (contentType.startsWith("image"))) {
if ((contentLength != null) && (contentLength < CommonResources.BACK_REQ_MAX_LENGTH)) {
// We could use getResponseBody As a Stream, but we will do
// exactly the same as the library. Why bother.
v = method.getResponseBody();
return v;
} else {
message="Request: " + fk.source_url + " above max length threshold (" + contentLength + "/" + CommonResources.BACK_REQ_MAX_LENGTH + ")";
Logger.getLogger(BackCacheUpdater.class.getName()).log(Level.WARNING,message);
}
} else {
message="Request: " + fk.source_url + " is not an image (" + contentType + ")";
Logger.getLogger(BackCacheUpdater.class.getName()).log(Level.WARNING, message );
}
} else {
message= "Request: " + fk.source_url + " failed. Return code : " + returnCode;
Logger.getLogger(BackCacheUpdater.class.getName()).log(Level.WARNING, message);
}
} catch (IllegalStateException|URIException ex) {
message="Request: " + fk.source_url + " URI problem. ";
Logger.getLogger(BackCacheUpdater.class.getName()).log(Level.SEVERE, message, ex);
} catch (IOException ex) {
message="Request: " + fk.source_url + " IO Exception. ";
Logger.getLogger(BackCacheUpdater.class.getName()).log(Level.SEVERE, message, ex);
}
return message;
}
private HashMap<String,Object> extractHeaders(GetMethod method) throws NumberFormatException {
HashMap<String,Object> headers=new HashMap<>();
for (Header a : method.getResponseHeaders()) {
if (a.getName()!=null) {
String pkey=a.getName().toLowerCase();
Object value=a.getValue();
switch (pkey) {
case "content-length":
value=Integer.parseInt((String)value);
default:
headers.put(pkey, value);
}
}
}
return headers;
}
}