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