package com.gravspace.handlers;
import java.lang.reflect.InvocationTargetException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.apache.commons.lang.StringUtils;
import org.apache.http.Header;
import org.apache.http.HttpRequest;
import org.apache.http.HttpResponse;
import org.apache.http.protocol.HttpContext;
import scala.concurrent.Await;
import scala.concurrent.Future;
import scala.concurrent.duration.Duration;
import akka.actor.ActorRef;
import akka.actor.Status;
import akka.actor.UntypedActor;
import akka.actor.UntypedActorContext;
import akka.dispatch.Futures;
import akka.event.Logging;
import akka.event.LoggingAdapter;
import com.gravspace.abstractions.IWidget;
import com.gravspace.abstractions.IPage;
import com.gravspace.abstractions.PageRoute;
import com.gravspace.exceptions.PageNotFoundException;
import com.gravspace.messages.RequestMessage;
import com.gravspace.messages.ResponseMessage;
import com.gravspace.util.Layers;
public class PageHandler extends UntypedActor {
LoggingAdapter log = Logging.getLogger(getContext().system(), this);
List<PageRoute> pages;
Map<String, ActorRef> routes;
private Map<Layers, ActorRef> routers;
public PageHandler(Map<Layers, ActorRef> routers, List<PageRoute> pages){
this.pages = pages;
this.routers = routers;
}
@Override
public void onReceive(Object rawMessage) throws Exception {
log.info("Page got: "+rawMessage.getClass().getCanonicalName());
if (rawMessage instanceof RequestMessage){
log.info("Handelling Request");
RequestMessage message = (RequestMessage)rawMessage;
String uri = message.getPayload().getRequestLine().getUri();
String[] split = StringUtils.split(uri, "?", 2);
String path = split[0];
String query = "";
if (split.length > 1){
query = split[1];
}
Future<ResponseMessage> rendered = null;
try {
IPage page = loadPage(path, message.getPayload().getRequestLine().getMethod().toUpperCase(), query, message.getPayload().getHeaders(), message.getPayload().getContent());
rendered = page.build();
} catch (PageNotFoundException pnf){
rendered = Futures.failed(pnf);
} catch (InstantiationException | IllegalAccessException | IllegalArgumentException | InvocationTargetException | NoSuchMethodException | SecurityException e){
log.error(String.format("Error in handelling [%s]", e.getClass().getCanonicalName()), e);
rendered = Futures.failed(e);
} catch (Throwable e) {
rendered = Futures.failed(e);
}
akka.pattern.Patterns.pipe(rendered, this.getContext().dispatcher()).to(getSender());
}
else {
unhandled(rawMessage);
}
}
private IPage loadPage(String path, String method, String query, Header[] headers, byte[] content) throws PageNotFoundException, InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException, NoSuchMethodException, SecurityException {
Map<String, String> parameters = new HashMap<String, String>();
for (PageRoute route: pages){
if (route.getTemplate().match(path, parameters)){
IPage page = route.getPageClass().getConstructor(Map.class, ActorRef.class, UntypedActorContext.class).newInstance(routers, getSender(), this.context());
page.initialise(path,
method,
query,
headers,
content,
parameters
);
return page;
}
}
throw new PageNotFoundException(String.format("Page matching [%s] not found", path));
}
}