package org.atomojo.app.client;
import java.net.URI;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.logging.Logger;
import org.infoset.xml.Document;
import org.restlet.Client;
import org.restlet.Context;
import org.restlet.Request;
import org.restlet.Response;
import org.restlet.data.ChallengeResponse;
import org.restlet.data.ChallengeScheme;
import org.restlet.data.Cookie;
import org.restlet.data.Method;
import org.restlet.data.Protocol;
import org.restlet.data.Reference;
import org.restlet.representation.Representation;
/**
* This class provides a way to script interations with a APP-enabled
* server. You can write scripts as an XML document and then load
* and run them via this class. In all the examples, the script uses
* the namespace {http://www.atomojo.org/Vocabulary/APPInteraction/2010/1/0}
*
* The basic structure is:
*
* {@code
* <interaction>
* (get|create|update|delete|for-feed|loop)+
* </interaction>
*
* <loop variable=xs:NCName start=xs:integer end=xs:integer>
* (for-feed|loop)+
* </loop>
*
* <for-feed href=xs:anyURI>
* (get|create|update|delete|loop)+
* </for-feed>
* }
* @author alex
*/
public class APPInteraction {
interface Action {
void apply(URI baseURI)
throws Exception;
}
class SequenceAction implements Action {
List<Action> actions = new ArrayList<Action>();
public void apply(URI baseURI)
throws Exception
{
for (Action action : actions) {
action.apply(baseURI);
}
}
}
class CreateAction implements Action {
String href;
Representation content;
CreateAction(String href,Representation content) {
this.href = href;
this.content = content;
}
public void apply(URI baseURI)
throws Exception
{
post(new Reference(baseURI.resolve(href).toString()),content);
}
}
class UpdateAction implements Action {
String href;
Representation content;
UpdateAction(String href,Representation content) {
this.href = href;
this.content = content;
}
public void apply(URI baseURI)
throws Exception
{
put(new Reference(baseURI.resolve(href).toString()),content);
}
}
class DeleteAction implements Action {
String href;
DeleteAction(String href) {
this.href = href;
}
public void apply(URI baseURI)
throws Exception
{
delete(new Reference(baseURI.resolve(href).toString()));
}
}
class GetAction implements Action {
String href;
GetAction(String href) {
this.href = href;
}
public void apply(URI baseURI)
throws Exception
{
get(new Reference(baseURI.resolve(href).toString()));
}
}
class HeadAction implements Action {
String href;
HeadAction(String href) {
this.href = href;
}
public void apply(URI baseURI)
throws Exception
{
head(new Reference(baseURI.resolve(href).toString()));
}
}
Context context;
URI docBaseURI;
Action root;
Cookie cookie;
Identity identity;
Map<String,Client> clients;
public APPInteraction(Context context) {
this.context = context;
root = new SequenceAction();
clients = new HashMap<String,Client>();
}
public void setCookie(Cookie cookie)
{
this.cookie = cookie;
}
public void setIdentity(String username,String password)
{
this.identity = new Identity(username,password);
}
public void setIdentity(Identity identity)
{
this.identity = identity;
}
protected Client getClient(String scheme) {
Client client = clients.get(scheme);
if (client==null) {
client = new Client(context,Protocol.valueOf(scheme));
clients.put(scheme,client);
}
return client;
}
protected Response get(Reference uri)
{
Client client = getClient(uri.getScheme());
Request request = new Request(Method.GET,uri);
if (identity!=null) {
request.setChallengeResponse(new ChallengeResponse(ChallengeScheme.HTTP_BASIC,identity.getName(),identity.getPassword()));
}
if (cookie!=null) {
request.getCookies().add(cookie);
}
return client.handle(request);
}
protected Response head(Reference uri)
{
Client client = getClient(uri.getScheme());
Request request = new Request(Method.HEAD,uri);
if (identity!=null) {
request.setChallengeResponse(new ChallengeResponse(ChallengeScheme.HTTP_BASIC,identity.getName(),identity.getPassword()));
}
if (cookie!=null) {
request.getCookies().add(cookie);
}
return client.handle(request);
}
protected Response post(Reference uri,Representation entity)
{
Client client = getClient(uri.getScheme());
Request request = new Request(Method.POST,uri);
if (identity!=null) {
request.setChallengeResponse(new ChallengeResponse(ChallengeScheme.HTTP_BASIC,identity.getName(),identity.getPassword()));
}
if (cookie!=null) {
request.getCookies().add(cookie);
}
request.setEntity(entity);
return client.handle(request);
}
protected Response put(Reference uri,Representation entity)
{
Client client = getClient(uri.getScheme());
Request request = new Request(Method.PUT,uri);
if (identity!=null) {
request.setChallengeResponse(new ChallengeResponse(ChallengeScheme.HTTP_BASIC,identity.getName(),identity.getPassword()));
}
if (cookie!=null) {
request.getCookies().add(cookie);
}
request.setEntity(entity);
return client.handle(request);
}
protected Response delete(Reference uri)
{
Client client = getClient(uri.getScheme());
Request request = new Request(Method.DELETE,uri);
if (identity!=null) {
request.setChallengeResponse(new ChallengeResponse(ChallengeScheme.HTTP_BASIC,identity.getName(),identity.getPassword()));
}
if (cookie!=null) {
request.getCookies().add(cookie);
}
return client.handle(request);
}
public void load(Document doc) {
docBaseURI = doc.getBaseURI();
}
public void apply()
throws Exception
{
apply(null);
}
public void apply(URI baseURI)
throws Exception
{
root.apply(baseURI==null ? docBaseURI : baseURI);
}
}