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