001    package railo.runtime.functions.system;
002    
003    import railo.commons.io.res.util.ResourceUtil;
004    import railo.runtime.PageContext;
005    import railo.runtime.PageContextImpl;
006    import railo.runtime.ext.function.Function;
007    import railo.runtime.type.Array;
008    import railo.runtime.type.ArrayImpl;
009    import railo.runtime.type.Collection;
010    import railo.runtime.type.KeyImpl;
011    import railo.runtime.type.Struct;
012    import railo.runtime.type.StructImpl;
013    import railo.runtime.type.UDF;
014    import railo.runtime.type.util.KeyConstants;
015    
016    /**
017     * returns the root of this actuell Page Context
018     */
019    public final class CallStackGet implements Function {
020    
021            private static final long serialVersionUID = -5853145189662102420L;
022            static final Collection.Key LINE_NUMBER = KeyImpl.init("LineNumber");
023    
024            public static Array call(PageContext pc) {
025                    Array arr=new ArrayImpl();
026                    _getTagContext(pc, arr, new Exception("Stack trace"),LINE_NUMBER);
027                    return arr;
028            }
029            
030            public static void _getTagContext(PageContext pc, Array tagContext, Throwable t,Collection.Key lineNumberName) {
031                    //Throwable root = t.getRootCause();
032                    Throwable cause = t.getCause(); 
033                    if(cause!=null)_getTagContext(pc, tagContext, cause,lineNumberName);
034                    StackTraceElement[] traces = t.getStackTrace();
035                    
036                    UDF[] udfs = ((PageContextImpl)pc).getUDFs();
037                    
038            int line=0;
039                    String template;
040                    Struct item;
041                    StackTraceElement trace=null;
042                    String functionName;
043                    int index=udfs.length-1;
044                    for(int i=0;i<traces.length;i++) {
045                            trace=traces[i];
046                            template=trace.getFileName();
047                            if(trace.getLineNumber()<=0 || template==null || ResourceUtil.getExtension(template,"").equals("java")) continue;
048                            if("udfCall".equals(trace.getMethodName()) && index>-1) 
049                                    functionName=udfs[index--].getFunctionName();
050                            
051                            else functionName="";
052                            
053                            item=new StructImpl();
054                            line=trace.getLineNumber();
055                            item.setEL(KeyConstants._function,functionName);
056                            item.setEL(KeyConstants._template,template);
057                            item.setEL(lineNumberName,new Double(line));
058                            tagContext.appendEL(item);
059                    }
060            }
061    }