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 }