001    package coldfusion.cfc;
002    
003    import java.io.File;
004    import java.io.IOException;
005    import java.io.OutputStream;
006    import java.io.Serializable;
007    import java.util.HashMap;
008    import java.util.Iterator;
009    import java.util.Map;
010    import java.util.Map.Entry;
011    
012    import javax.servlet.http.HttpServletRequest;
013    import javax.servlet.http.HttpServletResponse;
014    
015    import railo.loader.engine.CFMLEngine;
016    import railo.loader.engine.CFMLEngineFactory;
017    import railo.runtime.Component;
018    import railo.runtime.PageContext;
019    import railo.runtime.exp.PageException;
020    import railo.runtime.type.Collection.Key;
021    import railo.runtime.type.Struct;
022    import railo.runtime.util.Cast;
023    import railo.runtime.util.Creation;
024    
025    
026    public class CFCProxy {
027            
028            private CFMLEngine engine;
029            private Cast caster;
030            private Creation creator;
031            
032            private Component cfc=null;
033        private String path;
034            private Map thisData;
035            private boolean invokeDirectly=true;
036            private boolean autoFlush;
037    
038            public CFCProxy(String path) throws Throwable {
039                    this(path, null, true);
040        }
041    
042        public CFCProxy(String path, boolean invokeDirectly) throws Throwable {
043                    this(path, null, invokeDirectly);
044        }
045    
046        public CFCProxy(String path, Map initialThis) throws Throwable {
047            this(path, initialThis, true);
048        }
049    
050        public CFCProxy(String path, Map initialThis, boolean invokeDirectly) throws Throwable {
051            engine = CFMLEngineFactory.getInstance();
052            caster = engine.getCastUtil();
053            creator = engine.getCreationUtil();
054            
055            this.path=path;
056                    this.invokeDirectly=invokeDirectly;
057                    setThisScope(initialThis);
058        }
059    
060        private void initCFC(PageContext pc) {
061            if(cfc==null && (invokeDirectly || pc!=null)) {
062                            try {
063                                    if(pc==null)pc=engine.getThreadPageContext();
064                                    cfc=engine.getCreationUtil().createComponentFromPath(pc, path);
065                            } catch (PageException pe) {}
066            }
067            }
068            
069        public void setThisScope(Map data) {
070                    if(data!=null) {
071                            if(thisData==null)this.thisData=new HashMap();
072                            
073                            Iterator<Entry> it = data.entrySet().iterator();
074                    Entry entry;
075                    while(it.hasNext()){
076                            entry = it.next();
077                            thisData.put(entry.getKey(), entry.getValue());
078                    }
079                    }
080        }
081    
082        public Map getThisScope() {
083            initCFC(null);
084            if(cfc==null)return null;
085            
086            Struct rtn=creator.createStruct();
087            Iterator<Entry<Key, Object>> it = cfc.entryIterator();
088            Entry<Key, Object> entry;
089            while(it.hasNext()){
090                    entry = it.next();
091                    rtn.setEL(entry.getKey(), entry.getValue());
092            }
093            return rtn;
094        }
095        
096        public final Object invoke(String methodName, Object args[]) throws Throwable {
097            if(invokeDirectly) return _invoke(methodName, args);
098            return _invoke(methodName, args, null, null, null);
099        }
100    
101            public final Object invoke(String methodName, Object args[], HttpServletRequest request, HttpServletResponse response) throws Throwable {
102                    if(invokeDirectly) return _invoke(methodName, args);
103            return _invoke(methodName, args, request, response, null);
104        }
105            
106        public final Object invoke(String methodName, Object args[], HttpServletRequest request, HttpServletResponse response, OutputStream out) throws Throwable {
107            if(invokeDirectly) return _invoke(methodName, args);
108            return _invoke(methodName, args, request, response, out);
109        }
110    
111        public static boolean inInvoke() {
112            return false;
113        }
114    
115        private Object _invoke(String methodName, Object[] args) throws PageException {
116            CFMLEngine engine = CFMLEngineFactory.getInstance();
117                    PageContext pc = engine.getThreadPageContext();
118                    initCFC(pc);
119            return cfc.call(pc, methodName, args);
120            }
121        
122        private Object _invoke(String methodName, Object[] args, HttpServletRequest req, HttpServletResponse rsp, OutputStream out) throws PageException {
123            CFMLEngine engine = CFMLEngineFactory.getInstance();
124                    Creation creator = engine.getCreationUtil();
125                    PageContext originalPC = engine.getThreadPageContext();
126                    
127                    // no OutputStream
128                    if(out==null)out=DevNullOutputStream.DEV_NULL_OUTPUT_STREAM;
129                    
130                    // no Request
131                    if(req==null){
132                            // TODO new File
133                            req=creator.createHttpServletRequest(new File("."), "Railo", "/", "", null, null, null, null, null);
134                    }
135                    // noRespone
136                    if(rsp==null){
137                            rsp=creator.createHttpServletResponse(out);
138                    }
139                    
140                    
141                    PageContext pc = creator.createPageContext(req,rsp,out);
142                    try{
143                            engine.registerThreadPageContext(pc);
144                            initCFC(pc);
145                    return cfc.call(pc, methodName, args);
146                    }
147                    finally{
148                            if(autoFlush) {
149                                    try {
150                                            pc.getRootWriter().flush();
151                                    } catch (Throwable t) {}
152                            }
153                            engine.registerThreadPageContext(originalPC);
154                    }
155            }
156    
157        public void flush() throws IOException {
158            CFMLEngine engine = CFMLEngineFactory.getInstance();
159                    PageContext pc = engine.getThreadPageContext();
160                    pc.getRootWriter().flush();
161        }
162    
163        public void setAutoFlush(boolean autoFlush) {
164            this.autoFlush = autoFlush;
165        }
166    
167        public void setApplicationExecution(boolean doApp)
168        {
169            //executeApplication = doApp;
170        }
171    
172    }
173    
174    final class DevNullOutputStream extends OutputStream implements Serializable {
175            
176            public static final DevNullOutputStream DEV_NULL_OUTPUT_STREAM=new DevNullOutputStream();
177            
178            /**
179             * Constructor of the class
180             */
181            private DevNullOutputStream() {}
182            
183        /**
184         * @see java.io.OutputStream#close()
185         */
186        public void close(){}
187    
188        /**
189         * @see java.io.OutputStream#flush()
190         */
191        public void flush() {}
192    
193        /**
194         * @see java.io.OutputStream#write(byte[], int, int)
195         */
196        public void write(byte[] b, int off, int len) {}
197    
198        /**
199         * @see java.io.OutputStream#write(byte[])
200         */
201        public void write(byte[] b) {}
202    
203        /**
204         * @see java.io.OutputStream#write(int)
205         */
206        public void write(int b) {}
207    
208    }