001 package railo.intergral.fusiondebug.server; 002 003 import java.util.ArrayList; 004 import java.util.Collections; 005 import java.util.Comparator; 006 import java.util.Iterator; 007 import java.util.List; 008 import java.util.Map.Entry; 009 010 import railo.commons.lang.StringUtil; 011 import railo.intergral.fusiondebug.server.type.FDVariable; 012 import railo.intergral.fusiondebug.server.util.FDCaster; 013 import railo.runtime.PageContextImpl; 014 import railo.runtime.PageSource; 015 import railo.runtime.exp.PageException; 016 import railo.runtime.op.Caster; 017 import railo.runtime.type.Collection; 018 import railo.runtime.type.KeyImpl; 019 import railo.runtime.type.Scope; 020 import railo.runtime.type.Struct; 021 import railo.runtime.type.scope.ClusterNotSupported; 022 import railo.runtime.type.scope.UndefinedImpl; 023 024 import com.intergral.fusiondebug.server.FDLanguageException; 025 import com.intergral.fusiondebug.server.IFDStackFrame; 026 import com.intergral.fusiondebug.server.IFDThread; 027 import com.intergral.fusiondebug.server.IFDVariable; 028 029 public class FDStackFrameImpl implements IFDStackFrame { 030 031 032 private static final Collection.Key CALLER = KeyImpl.intern("caller"); 033 034 private static final int[] SCOPES_AS_INT = new int[]{ 035 Scope.SCOPE_VARIABLES,Scope.SCOPE_CGI,Scope.SCOPE_URL,Scope.SCOPE_FORM, 036 Scope.SCOPE_COOKIE,Scope.SCOPE_CLIENT,Scope.SCOPE_APPLICATION,Scope.SCOPE_CALLER, 037 Scope.SCOPE_CLUSTER,Scope.SCOPE_REQUEST,Scope.SCOPE_SERVER,Scope.SCOPE_SESSION 038 }; 039 private static final String[] SCOPES_AS_STRING = new String[]{ 040 "variables","cgi","url","form", 041 "cookie","client","application","caller", 042 "cluster","request","server","session" 043 }; 044 045 private PageContextImpl pc; 046 private FDThreadImpl thread; 047 048 //private StackTraceElement trace; 049 050 private PageSource ps; 051 052 private int line; 053 054 private static Comparator comparator=new FDVariableComparator(); 055 056 public FDStackFrameImpl(FDThreadImpl thread,PageContextImpl pc, StackTraceElement trace, PageSource ps){ 057 this(thread, pc, ps, trace.getLineNumber()); 058 } 059 public FDStackFrameImpl(FDThreadImpl thread,PageContextImpl pc, PageSource ps, int line){ 060 this.thread=thread; 061 this.pc=pc; 062 this.line=line; 063 this.ps=ps; 064 } 065 066 /** 067 * @see com.intergral.fusiondebug.server.IFDStackFrame#evaluate(java.lang.String) 068 */ 069 public IFDVariable evaluate(String expression) throws FDLanguageException { 070 try { 071 return new FDVariable(this,expression,FDCaster.toFDValue(this,pc.evaluate(expression))); 072 } 073 catch (PageException e) { 074 throw new FDLanguageException(e); 075 } 076 } 077 078 /** 079 * @see com.intergral.fusiondebug.server.IFDStackFrame#getExecutionUnitName() 080 */ 081 public String getExecutionUnitName() { 082 return ps.getClassName(); 083 } 084 085 /** 086 * @see com.intergral.fusiondebug.server.IFDStackFrame#getExecutionUnitPackage() 087 */ 088 public String getExecutionUnitPackage() { 089 return ps.getPackageName(); 090 } 091 092 /** 093 * @see com.intergral.fusiondebug.server.IFDStackFrame#getLineNumber() 094 */ 095 public int getLineNumber() { 096 return line; 097 098 } 099 100 /** 101 * @see com.intergral.fusiondebug.server.IFDStackFrame#getSourceFileName() 102 */ 103 public String getSourceFileName() { 104 return ps.getFileName(); 105 } 106 107 /** 108 * @see com.intergral.fusiondebug.server.IFDStackFrame#getSourceFilePath() 109 */ 110 public String getSourceFilePath() { 111 String name = getSourceFileName(); 112 String path=ps.getDisplayPath(); 113 if(StringUtil.endsWithIgnoreCase(path, name)) 114 path=path.substring(0,path.length()-name.length()); 115 return path; 116 } 117 118 /** 119 * @see com.intergral.fusiondebug.server.IFDStackFrame#getThread() 120 */ 121 public IFDThread getThread() { 122 return thread; 123 } 124 125 /** 126 * @see com.intergral.fusiondebug.server.IFDStackFrame#getScopeNames() 127 */ 128 public List getScopeNames() { 129 List implScopes = ((UndefinedImpl) pc.undefinedScope()).getScopeNames(); 130 for(int i=0;i<SCOPES_AS_INT.length;i++){ 131 if(!implScopes.contains(SCOPES_AS_STRING[i]) && enabled(pc,SCOPES_AS_INT[i])) 132 implScopes.add(SCOPES_AS_STRING[i]); 133 } 134 return implScopes; 135 } 136 public static List testScopeNames(PageContextImpl pc) { 137 return new FDStackFrameImpl(null,pc,null,null).getScopeNames(); 138 } 139 140 private static boolean enabled(PageContextImpl pc,int scope) { 141 if(Scope.SCOPE_CLIENT==scope){ 142 return pc.getApplicationContext().isSetClientManagement(); 143 } 144 if(Scope.SCOPE_SESSION==scope){ 145 return pc.getApplicationContext().isSetSessionManagement(); 146 } 147 if(Scope.SCOPE_CALLER==scope){ 148 return pc.undefinedScope().get(CALLER,null) instanceof Struct; 149 } 150 if(Scope.SCOPE_CLUSTER==scope){ 151 try { 152 return !(pc.clusterScope() instanceof ClusterNotSupported); 153 } catch (PageException e) { 154 //e.printStackTrace(); 155 return false; 156 } 157 } 158 return true; 159 } 160 161 /** 162 * @see com.intergral.fusiondebug.server.IFDStackFrame#getVariables() 163 */ 164 public List getVariables() { 165 Iterator it = getScopeNames().iterator(); 166 List list=new ArrayList(); 167 168 while(it.hasNext()){ 169 try { 170 getVariables(this,pc,list, (String)it.next()); 171 } 172 catch (FDLanguageException e) {e.printStackTrace();} 173 } 174 return sort(list); 175 } 176 177 public static List testVariables(PageContextImpl pc) { 178 return new FDStackFrameImpl(null,pc,null,null).getVariables(); 179 } 180 181 182 /** 183 * @see com.intergral.fusiondebug.server.IFDStackFrame#getVariables(java.lang.String) 184 */ 185 public List getVariables(String strScope) throws FDLanguageException { 186 return sort(getVariables(this,pc,new ArrayList(), strScope)); 187 } 188 189 190 public static List testVariables(PageContextImpl pc,String strScope) throws FDLanguageException { 191 return new FDStackFrameImpl(null,pc,null,null).getVariables(strScope); 192 } 193 194 private static List getVariables(FDStackFrameImpl frame,PageContextImpl pc,List list,String strScope) throws FDLanguageException { 195 Scope scope; 196 try { 197 scope = pc.scope(strScope, null); 198 if(scope!=null) return copyValues(frame,list,scope); 199 200 Object value=pc.undefinedScope().get(strScope,null); 201 if(value!=null) { 202 if(value instanceof Struct)return copyValues(frame,new ArrayList(),(Struct)value); 203 throw new FDLanguageException("["+strScope+"] is not of type scope, type is ["+Caster.toTypeName(value)+"]"); 204 } 205 throw new FDLanguageException("["+strScope+"] does not exist in the current context"); 206 } 207 catch (PageException e) { 208 throw new FDLanguageException(e); 209 } 210 } 211 212 /** 213 * copy all data from given struct to given list and translate it to a FDValue 214 * @param to list to fill with values 215 * @param from struct to read values from 216 * @return the given list 217 */ 218 private static List copyValues(FDStackFrameImpl frame,List to,Struct from) { 219 Iterator it = from.entrySet().iterator(); 220 Entry entry; 221 while(it.hasNext()){ 222 entry=(Entry) it.next(); 223 to.add(new FDVariable(frame,(String)entry.getKey(),FDCaster.toFDValue(frame,entry.getValue()))); 224 } 225 return to; 226 } 227 228 private static List sort(List list) { 229 Collections.sort(list,comparator); 230 return list; 231 } 232 233 /** 234 * @see com.intergral.fusiondebug.server.IFDStackFrame#getFrameInformation() 235 */ 236 public String getFrameInformation() { 237 return ps.getFullRealpath(); 238 } 239 240 public String toString(){ 241 return "path:"+getSourceFilePath()+";name:"+getSourceFileName()+";unit-pack:"+getExecutionUnitPackage()+";unit-name:"+getExecutionUnitName()+";line:"+getLineNumber(); 242 } 243 244 245 } 246 247 class FDVariableComparator implements Comparator { 248 249 /** 250 * @see java.util.Comparator#compare(T, T) 251 */ 252 public int compare(Object o1, Object o2) { 253 return ((FDVariable)o1).getName().compareToIgnoreCase(((FDVariable)o2).getName()); 254 } 255 }