/*
* TemplateResource.java
*
* Created on September 7, 2007, 11:33 AM
*
* To change this template, choose Tools | Template Manager
* and open the template in the editor.
*/
package org.atomojo.www.util.script;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.Reader;
import java.io.StringReader;
import java.net.URI;
import java.util.Map;
import java.util.logging.Level;
import javax.xml.transform.OutputKeys;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerException;
import javax.xml.transform.stream.StreamResult;
import javax.xml.transform.stream.StreamSource;
import org.atomojo.www.util.Identity;
import org.restlet.Client;
import org.restlet.Request;
import org.restlet.Response;
import org.restlet.data.ChallengeResponse;
import org.restlet.data.ChallengeScheme;
import org.restlet.data.CharacterSet;
import org.restlet.data.Cookie;
import org.restlet.data.MediaType;
import org.restlet.data.Method;
import org.restlet.data.Parameter;
import org.restlet.data.Protocol;
import org.restlet.data.Reference;
import org.restlet.data.Status;
import org.restlet.representation.OutputRepresentation;
import org.restlet.representation.Representation;
import org.restlet.resource.ServerResource;
/**
*
* @author alex
*/
public class ScriptResource extends ServerResource
{
URI script;
URI resource;
MediaType type;
ScriptCache scriptCache;
String username;
String password;
/**
* Creates a new instance of TemplateResource
*/
public ScriptResource(ScriptCache scriptCache,URI script,URI resource,MediaType type)
{
setNegotiated(false);
this.script = script;
this.resource = resource;
this.type = type;
this.scriptCache = scriptCache;
this.username =null;
this.password = null;
}
public void setResourceUser(String username, String password)
{
this.username = username;
this.password = password;
}
public Representation get()
{
try {
final Transformer xform = scriptCache.get(script);
if (xform==null) {
getLogger().warning("Script "+script+" was not found.");
getResponse().setStatus(Status.CLIENT_ERROR_NOT_FOUND);
return null;
}
Request remoteRequest = null;
Client client = null;
if (resource!=null && !"jar".equals(resource.getScheme())) {
client = getContext().getClientDispatcher();
//client = new Client(getContext().createChildContext(),Protocol.valueOf(resource.getScheme()));
client.getContext().getAttributes().put("hostnameVerifier", org.apache.commons.ssl.HostnameVerifier.DEFAULT);
remoteRequest = new Request(Method.GET,new Reference(resource.toString()));
if (username!=null) {
remoteRequest.setChallengeResponse(new ChallengeResponse(ChallengeScheme.HTTP_BASIC,username,password));
}
Cookie cookie = getRequest().getCookies().getFirst("I");
if (cookie!=null) {
remoteRequest.getCookies().add(cookie);
}
}
final Response resourceResponse = remoteRequest==null ? null : client.handle(remoteRequest);
if (resourceResponse==null || resourceResponse.getStatus().isSuccess() && resourceResponse.isEntityAvailable()) {
getResponse().setStatus(Status.SUCCESS_OK);
Representation rep = new OutputRepresentation(type) {
public void write(OutputStream os)
throws IOException
{
try {
xform.clearParameters();
final Identity identity = (Identity)getRequest().getAttributes().get(Identity.IDENTITY_ATTR);
if (identity!=null) {
xform.setParameter("user.session",identity.getSession());
xform.setParameter("user.id",identity.getId());
xform.setParameter("user.alias",identity.getAlias());
if (identity.getName()!=null) {
xform.setParameter("user.name",identity.getName());
}
if (identity.getEmail()!=null) {
xform.setParameter("user.email",identity.getEmail());
}
}
xform.setParameter("request.resource.path",getRequest().getResourceRef().getPath());
xform.setParameter("request.resource.authority",getRequest().getResourceRef().getAuthority());
xform.setParameter("request.resource.scheme",getRequest().getResourceRef().getScheme());
xform.setParameter("request.resource.query",getRequest().getResourceRef().getQuery());
xform.setParameter("request.resource.fragment",getRequest().getResourceRef().getFragment());
Map<String,Object> attrs = getRequest().getAttributes();
for (String name : attrs.keySet()) {
Object value = attrs.get(name);
if (value instanceof String) {
xform.setParameter(name,value);
}
}
for (Parameter param : getContext().getParameters()) {
xform.setParameter(param.getName(),param.getValue());
}
xform.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "yes");
Reader input = null;
try {
if (resourceResponse==null) {
input = resource==null ? new StringReader("<doc/>") : new InputStreamReader(resource.toURL().openStream());
} else {
input = resourceResponse.getEntity().getReader();
}
try {
xform.transform(new StreamSource(input,resource==null ? null : resource.toString()),new StreamResult(new OutputStreamWriter(os,"UTF-8")));
} catch (TransformerException ex) {
getLogger().log(Level.SEVERE,"Cannot transform feed due to script error.",ex);
}
} finally {
if (input!=null) {
input.close();
}
}
} finally {
if (resourceResponse!=null) {
resourceResponse.getEntity().release();
}
}
}
public void release() {
scriptCache.release(script, xform);
}
};
rep.setCharacterSet(CharacterSet.UTF_8);
return rep;
} else {
scriptCache.release(script, xform);
getResponse().setStatus(resourceResponse.getStatus());
getResponse().setEntity(resourceResponse.getEntity());
}
} catch (IOException ex) {
getLogger().log(Level.SEVERE,"I/O error while getting script "+script,ex);
getResponse().setStatus(Status.SERVER_ERROR_INTERNAL);
} catch (TransformerException ex) {
getLogger().log(Level.SEVERE,"Error while getting script "+script,ex);
getResponse().setStatus(Status.SERVER_ERROR_INTERNAL);
}
return null;
}
}