package coldfusion.cfc;
import java.io.File;
import java.io.IOException;
import java.io.OutputStream;
import java.io.Serializable;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Map.Entry;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import railo.loader.engine.CFMLEngine;
import railo.loader.engine.CFMLEngineFactory;
import railo.runtime.Component;
import railo.runtime.PageContext;
import railo.runtime.exp.PageException;
import railo.runtime.type.Collection.Key;
import railo.runtime.type.Struct;
import railo.runtime.util.Cast;
import railo.runtime.util.Creation;
public class CFCProxy {
private CFMLEngine engine;
private Cast caster;
private Creation creator;
private Component cfc=null;
private String path;
private Map thisData;
private boolean invokeDirectly=true;
private boolean autoFlush;
public CFCProxy(String path) throws Throwable {
this(path, null, true);
}
public CFCProxy(String path, boolean invokeDirectly) throws Throwable {
this(path, null, invokeDirectly);
}
public CFCProxy(String path, Map initialThis) throws Throwable {
this(path, initialThis, true);
}
public CFCProxy(String path, Map initialThis, boolean invokeDirectly) throws Throwable {
engine = CFMLEngineFactory.getInstance();
caster = engine.getCastUtil();
creator = engine.getCreationUtil();
this.path=path;
this.invokeDirectly=invokeDirectly;
setThisScope(initialThis);
}
private void initCFC(PageContext pc) {
if(cfc==null && (invokeDirectly || pc!=null)) {
try {
if(pc==null)pc=engine.getThreadPageContext();
cfc=engine.getCreationUtil().createComponentFromPath(pc, path);
} catch (PageException pe) {}
}
}
public void setThisScope(Map data) {
if(data!=null) {
if(thisData==null)this.thisData=new HashMap();
Iterator<Entry> it = data.entrySet().iterator();
Entry entry;
while(it.hasNext()){
entry = it.next();
thisData.put(entry.getKey(), entry.getValue());
}
}
}
public Map getThisScope() {
initCFC(null);
if(cfc==null)return null;
Struct rtn=creator.createStruct();
Iterator<Entry<Key, Object>> it = cfc.entryIterator();
Entry<Key, Object> entry;
while(it.hasNext()){
entry = it.next();
rtn.setEL(entry.getKey(), entry.getValue());
}
return rtn;
}
public final Object invoke(String methodName, Object args[]) throws Throwable {
if(invokeDirectly) return _invoke(methodName, args);
return _invoke(methodName, args, null, null, null);
}
public final Object invoke(String methodName, Object args[], HttpServletRequest request, HttpServletResponse response) throws Throwable {
if(invokeDirectly) return _invoke(methodName, args);
return _invoke(methodName, args, request, response, null);
}
public final Object invoke(String methodName, Object args[], HttpServletRequest request, HttpServletResponse response, OutputStream out) throws Throwable {
if(invokeDirectly) return _invoke(methodName, args);
return _invoke(methodName, args, request, response, out);
}
public static boolean inInvoke() {
return false;
}
private Object _invoke(String methodName, Object[] args) throws PageException {
CFMLEngine engine = CFMLEngineFactory.getInstance();
PageContext pc = engine.getThreadPageContext();
initCFC(pc);
return cfc.call(pc, methodName, args);
}
private Object _invoke(String methodName, Object[] args, HttpServletRequest req, HttpServletResponse rsp, OutputStream out) throws PageException {
CFMLEngine engine = CFMLEngineFactory.getInstance();
Creation creator = engine.getCreationUtil();
PageContext originalPC = engine.getThreadPageContext();
// no OutputStream
if(out==null)out=DevNullOutputStream.DEV_NULL_OUTPUT_STREAM;
// no Request
if(req==null){
// TODO new File
req=creator.createHttpServletRequest(new File("."), "Railo", "/", "", null, null, null, null, null);
}
// noRespone
if(rsp==null){
rsp=creator.createHttpServletResponse(out);
}
PageContext pc = creator.createPageContext(req,rsp,out);
try{
engine.registerThreadPageContext(pc);
initCFC(pc);
return cfc.call(pc, methodName, args);
}
finally{
if(autoFlush) {
try {
pc.getRootWriter().flush();
} catch (Throwable t) {}
}
engine.registerThreadPageContext(originalPC);
}
}
public void flush() throws IOException {
CFMLEngine engine = CFMLEngineFactory.getInstance();
PageContext pc = engine.getThreadPageContext();
pc.getRootWriter().flush();
}
public void setAutoFlush(boolean autoFlush) {
this.autoFlush = autoFlush;
}
public void setApplicationExecution(boolean doApp)
{
//executeApplication = doApp;
}
}
final class DevNullOutputStream extends OutputStream implements Serializable {
public static final DevNullOutputStream DEV_NULL_OUTPUT_STREAM=new DevNullOutputStream();
/**
* Constructor of the class
*/
private DevNullOutputStream() {}
/**
* @see java.io.OutputStream#close()
*/
public void close(){}
/**
* @see java.io.OutputStream#flush()
*/
public void flush() {}
/**
* @see java.io.OutputStream#write(byte[], int, int)
*/
public void write(byte[] b, int off, int len) {}
/**
* @see java.io.OutputStream#write(byte[])
*/
public void write(byte[] b) {}
/**
* @see java.io.OutputStream#write(int)
*/
public void write(int b) {}
}