001/** 002 * 003 * Copyright (c) 2014, the Railo Company Ltd. All rights reserved. 004 * 005 * This library is free software; you can redistribute it and/or 006 * modify it under the terms of the GNU Lesser General Public 007 * License as published by the Free Software Foundation; either 008 * version 2.1 of the License, or (at your option) any later version. 009 * 010 * This library is distributed in the hope that it will be useful, 011 * but WITHOUT ANY WARRANTY; without even the implied warranty of 012 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 013 * Lesser General Public License for more details. 014 * 015 * You should have received a copy of the GNU Lesser General Public 016 * License along with this library. If not, see <http://www.gnu.org/licenses/>. 017 * 018 **/ 019package lucee.intergral.fusiondebug.server; 020 021import java.io.PrintWriter; 022import java.util.ArrayList; 023import java.util.Iterator; 024import java.util.List; 025import java.util.Map; 026import java.util.Map.Entry; 027 028import lucee.commons.io.SystemUtil; 029import lucee.commons.lang.SystemOut; 030import lucee.runtime.CFMLFactory; 031import lucee.runtime.CFMLFactoryImpl; 032import lucee.runtime.Info; 033import lucee.runtime.PageContextImpl; 034import lucee.runtime.config.Config; 035import lucee.runtime.config.ConfigWebImpl; 036import lucee.runtime.engine.CFMLEngineImpl; 037import lucee.runtime.engine.ThreadLocalPageContext; 038import lucee.runtime.op.Caster; 039import lucee.runtime.security.SerialNumber; 040 041import com.intergral.fusiondebug.server.IFDController; 042import com.intergral.fusiondebug.server.IFDThread; 043 044/** 045 * 046 */ 047public class FDControllerImpl implements IFDController { 048 049 050 private List exceptionTypes; 051 private CFMLEngineImpl engine; 052 private boolean isEnterprise; 053 054 055 public FDControllerImpl(CFMLEngineImpl engine,String serial){ 056 this.isEnterprise=SerialNumber.isEnterprise(serial); 057 this.engine=engine; 058 } 059 060 @Override 061 public String getEngineName() { 062 return "Lucee"; 063 } 064 065 @Override 066 public String getEngineVersion() { 067 return Info.getVersionAsString(); 068 } 069 070 @Override 071 public List getExceptionTypes() { 072 if(exceptionTypes==null){ 073 exceptionTypes=new ArrayList(); 074 exceptionTypes.add("application"); 075 exceptionTypes.add("expression"); 076 exceptionTypes.add("database"); 077 exceptionTypes.add("custom_type"); 078 exceptionTypes.add("lock"); 079 exceptionTypes.add("missinginclude"); 080 exceptionTypes.add("native"); 081 exceptionTypes.add("security"); 082 exceptionTypes.add("template"); 083 } 084 return exceptionTypes; 085 } 086 087 /** 088 * @deprecated use instead <code>{@link #getLicenseInformation(String)}</code> 089 */ 090 public String getLicenseInformation() { 091 throw new RuntimeException("please replace your fusiondebug-api-server-1.0.xxx-SNAPSHOT.jar with a newer version"); 092 } 093 094 @Override 095 public String getLicenseInformation(String key) { 096 if(!isEnterprise) { 097 SystemOut.print(new PrintWriter(System.err),"FD Server Licensing does not work with the Open Source Version of Lucee or Enterprise Version of Lucee that is not enabled"); 098 return null; 099 } 100 return FDLicense.getLicenseInformation(key); 101 } 102 103 104 @Override 105 public void output(String message) { 106 Config config = ThreadLocalPageContext.getConfig(); 107 PrintWriter out=config==null?SystemUtil.getPrintWriter(SystemUtil.OUT):((ConfigWebImpl)config).getOutWriter(); 108 SystemOut.print(out, message); 109 } 110 111 @Override 112 public List pause() { 113 List<IFDThread> threads = new ArrayList<IFDThread>(); 114 Iterator<Entry<String, CFMLFactory>> it = engine.getCFMLFactories().entrySet().iterator(); 115 Entry<String, CFMLFactory> entry; 116 while(it.hasNext()){ 117 entry = it.next(); 118 pause(entry.getKey(),(CFMLFactoryImpl) entry.getValue(), threads); 119 } 120 121 return threads; 122 } 123 124 private void pause(String name,CFMLFactoryImpl factory,List<IFDThread> threads) { 125 Map<Integer, PageContextImpl> pcs = factory.getActivePageContexts(); 126 Iterator<PageContextImpl> it = pcs.values().iterator(); 127 PageContextImpl pc; 128 129 while(it.hasNext()){ 130 pc=it.next(); 131 try { 132 pc.getThread().wait(); 133 } catch (InterruptedException e) { 134 e.printStackTrace(); 135 } 136 threads.add(new FDThreadImpl(this,factory,name,pc)); 137 } 138 } 139 140 @Override 141 public boolean getCaughtStatus( 142 String exceptionType, 143 String executionUnitName, 144 String executionUnitPackage, 145 String sourceFilePath, 146 String sourceFileName, 147 int lineNumber) { 148 // TODO [007] 149 return true; 150 } 151 152 @Override 153 public IFDThread getByNativeIdentifier(String id) { 154 Iterator<Entry<String, CFMLFactory>> it = engine.getCFMLFactories().entrySet().iterator(); 155 Entry<String, CFMLFactory> entry; 156 FDThreadImpl thread; 157 while(it.hasNext()){ 158 entry = it.next(); 159 thread = getByNativeIdentifier( entry.getKey(),(CFMLFactoryImpl) entry.getValue(),id); 160 if(thread!=null) return thread; 161 } 162 return null; 163 } 164 165 /** 166 * checks a single CFMLFactory for the thread 167 * @param name 168 * @param factory 169 * @param id 170 * @return matching thread or null 171 */ 172 private FDThreadImpl getByNativeIdentifier(String name,CFMLFactoryImpl factory,String id) { 173 Map<Integer, PageContextImpl> pcs = factory.getActivePageContexts(); 174 Iterator<PageContextImpl> it = pcs.values().iterator(); 175 PageContextImpl pc; 176 177 while(it.hasNext()){ 178 pc=it.next(); 179 if(equals(pc,id)) return new FDThreadImpl(this,factory,name,pc); 180 } 181 return null; 182 } 183 184 /** 185 * check if thread of PageContext match given id 186 * @param pc 187 * @param id 188 * @return match the id the pagecontext 189 */ 190 private boolean equals(PageContextImpl pc, String id) { 191 Thread thread = pc.getThread(); 192 if(Caster.toString(FDThreadImpl.id(pc)).equals(id)) return true; 193 if(Caster.toString(thread.getId()).equals(id)) return true; 194 if(Caster.toString(thread.hashCode()).equals(id)) return true; 195 return false; 196 } 197 198 @Override 199 public String getCompletionMethod() { 200 return "serviceCFML"; 201 } 202 203 @Override 204 public String getCompletionType() { 205 return CFMLEngineImpl.class.getName(); 206 } 207 208 @Override 209 public void release() { 210 this.engine.allowRequestTimeout(true); 211 } 212}