001 package railo.runtime.tag; 002 003 import java.io.IOException; 004 005 import railo.commons.io.log.Log; 006 import railo.commons.io.log.LogAndSource; 007 import railo.commons.io.log.LogUtil; 008 import railo.commons.lang.StringUtil; 009 import railo.runtime.PageSource; 010 import railo.runtime.converter.ConverterException; 011 import railo.runtime.converter.ScriptConverter; 012 import railo.runtime.debug.DebugTrace; 013 import railo.runtime.debug.DebuggerPro; 014 import railo.runtime.exp.Abort; 015 import railo.runtime.exp.ApplicationException; 016 import railo.runtime.exp.PageException; 017 import railo.runtime.ext.tag.BodyTagImpl; 018 import railo.runtime.functions.other.Dump; 019 import railo.runtime.interpreter.VariableInterpreter; 020 import railo.runtime.op.Caster; 021 import railo.runtime.type.Struct; 022 import railo.runtime.type.dt.DateTimeImpl; 023 import railo.runtime.type.scope.Scope; 024 import railo.runtime.type.trace.TraceObjectSupport; 025 026 public final class Trace extends BodyTagImpl { 027 028 private boolean abort=false; 029 private boolean follow=false; 030 private String category; 031 private boolean inline=false; 032 private String text; 033 private int type=Log.LEVEL_INFO; 034 private String var; 035 private Struct caller; 036 037 038 @Override 039 public void release() { 040 super.release(); 041 abort=false; 042 category=null; 043 inline=false; 044 text=null; 045 type=Log.LEVEL_INFO; 046 var=null; 047 caller=null; 048 follow=false; 049 } 050 051 /** 052 * @param abort the abort to set 053 */ 054 public void setAbort(boolean abort) { 055 this.abort = abort; 056 } 057 public void setFollow(boolean follow) { 058 this.follow = follow; 059 } 060 061 /** 062 * @param category the category to set 063 */ 064 public void setCategory(String category) { 065 this.category = category; 066 } 067 068 /** 069 * @param inline the inline to set 070 */ 071 public void setInline(boolean inline) { 072 this.inline = inline; 073 } 074 075 /** 076 * @param text the text to set 077 */ 078 public void setText(String text) { 079 this.text = text; 080 } 081 082 /** 083 * @param type the type to set 084 * @throws ApplicationException 085 */ 086 public void setType(String strType) throws ApplicationException { 087 strType = strType.toLowerCase().trim(); 088 if("info".equals(strType)) type=Log.LEVEL_INFO; 089 if("information".equals(strType)) type=Log.LEVEL_INFO; 090 else if("warn".equals(strType)) type=Log.LEVEL_WARN; 091 else if("warning".equals(strType)) type=Log.LEVEL_WARN; 092 else if("error".equals(strType)) type=Log.LEVEL_ERROR; 093 else if("fatal information".equals(strType)) type=Log.LEVEL_FATAL; 094 else if("fatal-information".equals(strType)) type=Log.LEVEL_FATAL; 095 else if("fatal_information".equals(strType)) type=Log.LEVEL_FATAL; 096 else if("fatalinformation".equals(strType)) type=Log.LEVEL_FATAL; 097 else if("fatal info".equals(strType)) type=Log.LEVEL_FATAL; 098 else if("fatal-info".equals(strType)) type=Log.LEVEL_FATAL; 099 else if("fatal_info".equals(strType)) type=Log.LEVEL_FATAL; 100 else if("fatalinfo".equals(strType)) type=Log.LEVEL_FATAL; 101 else if("fatal".equals(strType)) type=Log.LEVEL_FATAL; 102 else if("debug".equals(strType)) type=Log.LEVEL_DEBUG; 103 else if("debugging".equals(strType)) type=Log.LEVEL_DEBUG; 104 else if("debuging".equals(strType)) type=Log.LEVEL_DEBUG; 105 else throw new ApplicationException("invalid value ["+strType+"] for attribute [type], valid values are [Debug, Information, Warning, Error, Fatal Information]"); 106 } 107 108 /** 109 * @param var the var to set 110 */ 111 public void setVar(String var) { 112 this.var = var; 113 } 114 115 public void setCaller(Struct caller) { 116 this.caller = caller; 117 } 118 119 /** 120 * @param var the var to set 121 */ 122 public void setVariable(String var) { 123 this.var = var; 124 } 125 126 @Override 127 public int doStartTag() { 128 return EVAL_BODY_INCLUDE; 129 } 130 131 132 @Override 133 public int doEndTag() throws PageException { 134 try { 135 _doEndTag(); 136 } 137 catch (IOException e) {} 138 return EVAL_PAGE; 139 } 140 141 public void _doEndTag() throws IOException, PageException { 142 143 PageSource page = pageContext.getCurrentTemplatePageSource(); 144 145 // var 146 String varValue=null; 147 Object value=null,traceValue=null; 148 if(!StringUtil.isEmpty(var)) { 149 150 try { 151 if(caller instanceof Scope) value=VariableInterpreter.getVariable(pageContext,var,(Scope)caller); 152 else value = pageContext.getVariable(var); 153 } 154 catch (PageException e) { 155 varValue="(undefined)"; 156 follow=false; 157 } 158 159 if(follow){ 160 //print.o(1); 161 if(StringUtil.isEmpty(text,true)) text=var; 162 //print.o(2); 163 traceValue=TraceObjectSupport.toTraceObject(pageContext.getDebugger(), value, type, category, text); 164 165 if(caller instanceof Scope) VariableInterpreter.setVariable(pageContext,var,traceValue,(Scope)caller); 166 else pageContext.setVariable(var,traceValue); 167 } 168 169 try { 170 varValue=new ScriptConverter().serialize(value); 171 } 172 catch (ConverterException e) { 173 if(value!=null)varValue="("+Caster.toTypeName(value)+")"; 174 } 175 176 177 178 } 179 180 DebugTrace trace = pageContext.getDebugger().addTrace(type,category,text,page,var,varValue); 181 DebugTrace[] traces = ((DebuggerPro)pageContext.getDebugger()).getTraces(pageContext); 182 183 String total="(1st trace)"; 184 if(traces.length>1) { 185 long t=0; 186 for(int i=0;i<traces.length;i++) { 187 t+=traces[i].getTime(); 188 } 189 total="("+t+")"; 190 } 191 192 boolean hasCat=!StringUtil.isEmpty(trace.getCategory()); 193 boolean hasText=!StringUtil.isEmpty(trace.getText()); 194 boolean hasVar=!StringUtil.isEmpty(var); 195 196 // inline 197 if(inline) { 198 railo.runtime.format.TimeFormat tf = new railo.runtime.format.TimeFormat(pageContext.getConfig().getLocale()); 199 StringBuffer sb=new StringBuffer(); 200 sb.append("<table border=\"0\" cellpadding=\"0\" cellspacing=\"0\" bgcolor=\"white\">"); 201 sb.append("<tr>"); 202 //sb.append("<td><img src=\"/CFIDE/debug/images/Error_16x16.gif\" alt=\"Error type\">"); 203 sb.append("<td>"); 204 sb.append("<font color=\"orange\">"); 205 sb.append("<b>"); 206 sb.append(LogUtil.toStringType(trace.getType(),"INFO")+" - "); 207 sb.append("[CFTRACE "+tf.format(new DateTimeImpl(pageContext.getConfig()), "hh:mm:ss:l")+"]"); 208 sb.append("["+trace.getTime()+" ms "+total+"]"); 209 sb.append("["+trace.getTemplate()+" @ line: "+trace.getLine()+"]"); 210 if(hasCat || hasText)sb.append(" -"); 211 if(hasCat)sb.append(" ["+trace.getCategory()+"]"); 212 if(hasText)sb.append(" <i>"+trace.getText()+" </i>"); 213 sb.append("</b>"); 214 sb.append("</font>"); 215 sb.append("</td>"); 216 sb.append("</tr>"); 217 sb.append("</table>"); 218 pageContext.forceWrite(sb.toString()); 219 220 if(hasVar)Dump.call(pageContext, value, var); 221 222 } 223 224 // log 225 LogAndSource log = pageContext.getConfig().getTraceLogger(); 226 StringBuffer msg=new StringBuffer(); 227 msg.append("["+trace.getTime()+" ms "+total+"] "); 228 msg.append("["+trace.getTemplate()+" @ line: "+trace.getLine()+"]"); 229 if(hasCat || hasText || hasVar) msg.append("- "); 230 if(hasCat)msg.append("["+trace.getCategory()+"] "); 231 if(hasVar)msg.append("["+var+"="+varValue+"] "); 232 if(hasText)msg.append(" "+trace.getText()+" "); 233 log.log(trace.getType(), "cftrace", msg.toString()); 234 235 // abort 236 if(abort) throw new Abort(Abort.SCOPE_REQUEST); 237 238 } 239 240 @Override 241 public void doInitBody() { 242 243 } 244 245 @Override 246 public int doAfterBody() { 247 return SKIP_BODY; 248 } 249 250 /** 251 * sets if has body or not 252 * @param hasBody 253 */ 254 public void hasBody(boolean hasBody) { 255 256 } 257 }