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.util.ArrayList; 022import java.util.List; 023 024import lucee.commons.io.SystemUtil; 025import lucee.commons.io.log.Log; 026import lucee.commons.io.res.Resource; 027import lucee.commons.io.res.util.ResourceUtil; 028import lucee.runtime.CFMLFactoryImpl; 029import lucee.runtime.PageContext; 030import lucee.runtime.PageContextImpl; 031import lucee.runtime.PageSource; 032import lucee.runtime.config.ConfigImpl; 033import lucee.transformer.bytecode.util.ASMUtil; 034 035import com.intergral.fusiondebug.server.IFDController; 036import com.intergral.fusiondebug.server.IFDStackFrame; 037import com.intergral.fusiondebug.server.IFDThread; 038 039public class FDThreadImpl implements IFDThread { 040 041 042 private PageContextImpl pc; 043 private String name; 044 private FDControllerImpl engine; 045 //private CFMLFactoryImpl factory; 046 047 048 public FDThreadImpl(FDControllerImpl engine,CFMLFactoryImpl factory, String name, PageContextImpl pc) { 049 this.engine=engine; 050 //this.factory=factory; 051 this.name=name; 052 this.pc=pc; 053 } 054 055 @Override 056 public String getName() { 057 return name+":"+pc.getCFID(); 058 } 059 060 @Override 061 public int id() { 062 return pc.getId(); 063 } 064 065 public static int id(PageContext pc) { 066 return pc.getId(); 067 } 068 069 @Override 070 public void stop() { 071 Log log = ((ConfigImpl)pc.getConfig()).getLog("application"); 072 SystemUtil.stop(pc,log); 073 } 074 075 @Override 076 public Thread getThread() { 077 return pc.getThread(); 078 } 079 080 @Override 081 public String getOutputBuffer() { 082 return pc.getRootOut().toString(); 083 } 084 085 086 public List getStackFrames() { 087 return getStack(); 088 } 089 public List getStack() { 090 List stack = pc.getPageSourceList(); 091 092 StackTraceElement[] traces = pc.getThread().getStackTrace(); 093 String template=""; 094 StackTraceElement trace=null; 095 ArrayList list=new ArrayList(); 096 Resource res; 097 PageSource ps; 098 int index=stack.size(); 099 for(int i=traces.length-1;i>=0;i--) { 100 trace=traces[i]; 101 ps=null; 102 if(trace.getLineNumber()<=0) continue; 103 template=trace.getFileName(); 104 if(template==null || ResourceUtil.getExtension(template,"").equals("java")) continue; 105 106 if(index>0)ps=(PageSource) stack.get(--index); 107 if(ps==null || !isEqual(ps,trace)){ 108 ps=toPageSource(pc,template); 109 } 110 FDStackFrameImpl frame = new FDStackFrameImpl(this,pc,trace,ps); 111 if(ASMUtil.isOverfowMethod(trace.getMethodName())) list.set(0,frame); 112 else list.add(0,frame); 113 } 114 return list; 115 } 116 117 public IFDStackFrame getTopStack(){ 118 return getTopStackFrame(); 119 } 120 121 @Override 122 public IFDStackFrame getTopStackFrame(){ 123 PageSource ps = pc.getCurrentPageSource(); 124 125 StackTraceElement[] traces = pc.getThread().getStackTrace(); 126 String template=""; 127 StackTraceElement trace=null; 128 129 for(int i=0;i<traces.length;i++) { 130 trace=traces[i]; 131 if(trace.getLineNumber()<=0) continue; 132 template=trace.getFileName(); 133 if(template==null || ResourceUtil.getExtension(template,"").equals("java")) continue; 134 135 if(ps==null || !isEqual(ps,trace)){ 136 ps=toPageSource(pc,template); 137 } 138 break; 139 } 140 return new FDStackFrameImpl(this,pc,trace,ps); 141 } 142 143 private PageSource toPageSource(PageContextImpl pc2, String template) { 144 Resource res = ResourceUtil.toResourceNotExisting(pc, template); 145 return pc.toPageSource(res, null); 146 } 147 148 private boolean isEqual(PageSource ps, StackTraceElement trace) { 149 // class name do not match 150 if(!ps.getFullClassName().equals(trace.getClassName())) return false; 151 // filename to not match 152 if(!ps.getResource().getAbsolutePath().equals(trace.getFileName())) return false; 153 154 return true; 155 } 156 157 /** 158 * @return the engine 159 */ 160 public IFDController getController() { 161 return engine; 162 } 163 164 165}