001    package railo.intergral.fusiondebug.server;
002    
003    import java.io.PrintWriter;
004    import java.util.ArrayList;
005    import java.util.Iterator;
006    import java.util.List;
007    import java.util.Map.Entry;
008    
009    import railo.commons.io.SystemUtil;
010    import railo.commons.lang.SystemOut;
011    import railo.runtime.CFMLFactory;
012    import railo.runtime.CFMLFactoryImpl;
013    import railo.runtime.Info;
014    import railo.runtime.PageContextImpl;
015    import railo.runtime.config.Config;
016    import railo.runtime.config.ConfigWebImpl;
017    import railo.runtime.engine.CFMLEngineImpl;
018    import railo.runtime.engine.ThreadLocalPageContext;
019    import railo.runtime.op.Caster;
020    import railo.runtime.security.SerialNumber;
021    import railo.runtime.type.Collection.Key;
022    import railo.runtime.type.Struct;
023    
024    import com.intergral.fusiondebug.server.IFDController;
025    import com.intergral.fusiondebug.server.IFDThread;
026    
027    /**
028     * 
029     */
030    public class FDControllerImpl implements IFDController {
031    
032    
033            private List exceptionTypes;
034            private CFMLEngineImpl engine;
035            private boolean isEnterprise;
036            
037            
038            public FDControllerImpl(CFMLEngineImpl engine,String serial){
039                    this.isEnterprise=SerialNumber.isEnterprise(serial);
040                    this.engine=engine;
041            }
042    
043            @Override
044            public String getEngineName() {
045                    return "Railo";
046            }
047    
048            @Override
049            public String getEngineVersion() {
050                    return Info.getVersionAsString();
051            }
052    
053            @Override
054            public List getExceptionTypes() {
055                    if(exceptionTypes==null){
056                            exceptionTypes=new ArrayList();
057                            exceptionTypes.add("application");
058                            exceptionTypes.add("expression");
059                            exceptionTypes.add("database");
060                            exceptionTypes.add("custom_type");
061                            exceptionTypes.add("lock");
062                            exceptionTypes.add("missinginclude");
063                            exceptionTypes.add("native");
064                            exceptionTypes.add("security");
065                            exceptionTypes.add("template");
066                    }
067                    return exceptionTypes;
068            }
069    
070            /**
071             * @deprecated use instead <code>{@link #getLicenseInformation(String)}</code>
072             */
073            public String getLicenseInformation() {
074                    throw new RuntimeException("please replace your fusiondebug-api-server-1.0.xxx-SNAPSHOT.jar with a newer version");
075            }
076    
077            @Override
078            public String getLicenseInformation(String key) {
079                    if(!isEnterprise) {
080                            SystemOut.print(new PrintWriter(System.err),"FD Server Licensing does not work with the Open Source Version of Railo or Enterprise Version of Railo that is not enabled");
081                            return null;
082                    }
083                    return FDLicense.getLicenseInformation(key);
084            }
085    
086    
087            @Override
088            public void output(String message) {
089                    Config config = ThreadLocalPageContext.getConfig();
090                    PrintWriter out=config==null?SystemUtil.getPrintWriter(SystemUtil.OUT):((ConfigWebImpl)config).getOutWriter();
091                    SystemOut.print(out, message);
092            }
093    
094            @Override
095            public List pause() {
096                    List<IFDThread> threads = new ArrayList<IFDThread>();
097                    Iterator<Entry<String, CFMLFactory>> it = engine.getCFMLFactories().entrySet().iterator();
098                    Entry<String, CFMLFactory> entry;
099                    while(it.hasNext()){
100                            entry = it.next();
101                            pause(entry.getKey(),(CFMLFactoryImpl) entry.getValue(), threads);
102                    }
103                    
104                    return threads;
105            }
106            
107            private void pause(String name,CFMLFactoryImpl factory,List<IFDThread> threads) {
108                    Struct pcs = factory.getRunningPageContextes();
109                    Iterator<Entry<Key, Object>> it = pcs.entryIterator();
110                    PageContextImpl pc;
111                    
112                    while(it.hasNext()){
113                            pc=(PageContextImpl) it.next().getValue();
114                            try {
115                                    pc.getThread().wait();
116                            } catch (InterruptedException e) {
117                                    e.printStackTrace();
118                            }
119                            threads.add(new FDThreadImpl(this,factory,name,pc));
120                    }
121            }
122            
123            @Override
124            public boolean getCaughtStatus(
125                            String exceptionType,
126                            String executionUnitName,
127                String executionUnitPackage,
128                String sourceFilePath,
129                String sourceFileName,
130                int lineNumber) {
131                    // TODO [007]
132                    return true;
133            }
134    
135            @Override
136            public IFDThread getByNativeIdentifier(String id) {
137                    Iterator<Entry<String, CFMLFactory>> it = engine.getCFMLFactories().entrySet().iterator();
138                    Entry<String, CFMLFactory> entry;
139                    FDThreadImpl thread;
140                    while(it.hasNext()){
141                            entry = it.next();
142                            thread = getByNativeIdentifier( entry.getKey(),(CFMLFactoryImpl) entry.getValue(),id);
143                            if(thread!=null) return thread;
144                    }
145                    return null;
146            }
147            
148            /**
149             * checks a single CFMLFactory for the thread
150             * @param name
151             * @param factory
152             * @param id
153             * @return matching thread or null
154             */
155            private FDThreadImpl getByNativeIdentifier(String name,CFMLFactoryImpl factory,String id) {
156                    Struct pcs = factory.getRunningPageContextes();
157                    Iterator it = pcs.entrySet().iterator();
158                    PageContextImpl pc;
159                    
160                    while(it.hasNext()){
161                            pc=(PageContextImpl) ((Entry) it.next()).getValue();
162                            if(equals(pc,id)) return new FDThreadImpl(this,factory,name,pc);
163                    }
164                    return null;
165            }
166    
167            /**
168             * check if thread of PageContext match given id
169             * @param pc
170             * @param id
171             * @return match the id the pagecontext
172             */
173            private boolean equals(PageContextImpl pc, String id) {
174                    Thread thread = pc.getThread();
175                    if(Caster.toString(FDThreadImpl.id(pc)).equals(id)) return true;
176                    if(Caster.toString(thread.getId()).equals(id)) return true;
177                    if(Caster.toString(thread.hashCode()).equals(id)) return true;
178                    return false;
179            }
180    
181            @Override
182            public String getCompletionMethod() {
183                    return "serviceCFML";
184            }
185    
186            @Override
187            public String getCompletionType() {
188                    return CFMLEngineImpl.class.getName();
189            }
190    
191            @Override
192            public void release() {
193                    this.engine.allowRequestTimeout(true);
194            }
195    }