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.runtime.exp; 020 021import java.io.IOException; 022import java.io.InputStream; 023import java.io.PrintStream; 024import java.io.PrintWriter; 025import java.io.StringWriter; 026import java.lang.reflect.InvocationTargetException; 027import java.util.Iterator; 028import java.util.LinkedList; 029 030import lucee.commons.io.CharsetUtil; 031import lucee.commons.io.IOUtil; 032import lucee.commons.io.res.Resource; 033import lucee.commons.io.res.util.ResourceUtil; 034import lucee.commons.lang.ClassUtil; 035import lucee.commons.lang.ExceptionUtil; 036import lucee.commons.lang.MappingUtil; 037import lucee.commons.lang.StringUtil; 038import lucee.runtime.Info; 039import lucee.runtime.PageContext; 040import lucee.runtime.PageContextImpl; 041import lucee.runtime.PageSource; 042import lucee.runtime.PageSourceImpl; 043import lucee.runtime.config.Config; 044import lucee.runtime.config.ConfigWeb; 045import lucee.runtime.dump.DumpData; 046import lucee.runtime.dump.DumpProperties; 047import lucee.runtime.dump.DumpTable; 048import lucee.runtime.dump.SimpleDumpData; 049import lucee.runtime.engine.ThreadLocalPageContext; 050import lucee.runtime.err.ErrorPage; 051import lucee.runtime.op.Caster; 052import lucee.runtime.type.Array; 053import lucee.runtime.type.ArrayImpl; 054import lucee.runtime.type.Collection; 055import lucee.runtime.type.Collection.Key; 056import lucee.runtime.type.Struct; 057import lucee.runtime.type.StructImpl; 058import lucee.runtime.type.dt.DateTimeImpl; 059import lucee.runtime.type.util.KeyConstants; 060import lucee.runtime.type.util.ListUtil; 061import lucee.runtime.writer.CFMLWriter; 062import lucee.transformer.bytecode.util.SourceNameClassVisitor.SourceInfo; 063 064/** 065 * Lucee Runtime Page Exception, all runtime Exception are sub classes of this class 066 */ 067public abstract class PageExceptionImpl extends PageException { 068 069 private static final long serialVersionUID = -5816929795661373219L; 070 071 072 073 074 075 private Array tagContext=new ArrayImpl(); 076 private Struct additional=new StructImpl(Struct.TYPE_LINKED); 077 /** 078 * Field <code>detail</code> 079 */ 080 protected String detail=""; 081 //private Throwable rootCause; 082 private int tracePointer; 083 private String errorCode="0"; 084 private String extendedInfo=null; 085 086 private String type; 087 private String customType; 088 private boolean isInitTagContext=false; 089 private LinkedList<PageSource> sources=new LinkedList<PageSource>(); 090 private String varName; 091 092 093 094 095 096 private boolean exposeMessage; 097 098 099 /** 100 * Class Constructor 101 * @param message Exception Message 102 * @param type Type as String 103 */ 104 public PageExceptionImpl(String message,String type) { 105 this(message,type,null); 106 } 107 /** 108 * Class Constructor 109 * @param message Exception Message 110 * @param type Type as String 111 * @param customType CUstom Type as String 112 */ 113 public PageExceptionImpl(String message,String type, String customType) { 114 super(message==null?"":message); 115 //rootCause=this; 116 this.type=type.toLowerCase().trim(); 117 this.customType=customType; 118 //setAdditional("customType",getCustomTypeAsString()); 119 } 120 121 /** 122 * Class Constructor 123 * @param e exception 124 * @param type Type as String 125 */ 126 public PageExceptionImpl(Throwable e,String type) { 127 this(e,type,null); 128 } 129 130 /** 131 * Class Constructor 132 * @param e exception 133 * @param type Type as String 134 * @param customType CUstom Type as String 135 */ 136 public PageExceptionImpl(Throwable e,String type, String customType) { 137 super(StringUtil.isEmpty(e.getMessage(),true)?e.getClass().getName():e.getMessage()); 138 if(e instanceof InvocationTargetException)e=((InvocationTargetException)e).getTargetException(); 139 140 //this.i 141 initCause(e); 142 //this.setStackTrace(e.getStackTrace()); 143 144 if(e instanceof IPageException) { 145 IPageException pe=(IPageException)e; 146 this.additional=pe.getAdditional(); 147 this.setDetail(pe.getDetail()); 148 this.setErrorCode(pe.getErrorCode()); 149 this.setExtendedInfo(pe.getExtendedInfo()); 150 } 151 152 //else if(e.getCause()!=null)rootCause=e.getCause(); 153 //else rootCause=e; 154 155 this.type=type.trim(); 156 this.customType=(customType==null)?this.type:customType; 157 } 158 159 @Override 160 public String getDetail() { 161 if(detail==null || detail.equals(getMessage()))return ""; 162 return detail; 163 } 164 165 @Override 166 public String getErrorCode() { return errorCode==null?"":errorCode; } 167 168 @Override 169 public String getExtendedInfo() { return extendedInfo==null?"":extendedInfo; } 170 171 @Override 172 public void setDetail(String detail) { 173 this.detail=detail; 174 } 175 @Override 176 public void setErrorCode(String errorCode) { 177 this.errorCode=errorCode; 178 } 179 @Override 180 public void setExtendedInfo(String extendedInfo) { 181 this.extendedInfo=extendedInfo; 182 } 183 184 public final Struct getCatchBlock() { 185 return getCatchBlock(ThreadLocalPageContext.getConfig()); 186 } 187 188 @Override 189 public final Struct getCatchBlock(PageContext pc) { 190 return getCatchBlock(ThreadLocalPageContext.getConfig(pc)); 191 } 192 193 @Override 194 public CatchBlock getCatchBlock(Config config) { 195 return new CatchBlockImpl(this); 196 } 197 198 public Array getTagContext(Config config) { 199 if(isInitTagContext) return tagContext; 200 _getTagContext( config,tagContext,getStackTraceElements(this),sources); 201 isInitTagContext=true; 202 return tagContext; 203 } 204 205 206 public static Array getTagContext(Config config,StackTraceElement[] traces) { 207 Array tagContext=new ArrayImpl(); 208 _getTagContext( config,tagContext,traces,new LinkedList<PageSource>()); 209 return tagContext; 210 } 211 212 private static void _getTagContext(Config config, Array tagContext, StackTraceElement[] traces, 213 LinkedList<PageSource> sources) { 214 //StackTraceElement[] traces = getStackTraceElements(t); 215 int line=0; 216 String template="",tlast; 217 Struct item; 218 StackTraceElement trace=null; 219 int index=-1; 220 PageSource ps; 221 222 PageContextImpl pc=null; 223 if(config instanceof ConfigWeb) 224 pc = (PageContextImpl) ThreadLocalPageContext.get(); 225 226 227 for(int i=0;i<traces.length;i++) { 228 trace=traces[i]; 229 tlast=template; 230 template=trace.getFileName(); 231 232 if(trace.getLineNumber()<=0 || template==null || ResourceUtil.getExtension(template,"").equals("java")) continue; 233 // content 234 if(!StringUtil.emptyIfNull(tlast).equals(template))index++; 235 236 String[] content=null; 237 String dspPath=template; 238 try { 239 240 241 Resource res = config.getResource(template); 242 if(!res.exists()) { 243 PageSource _ps = pc==null?null:pc.getPageSource(template); 244 res=_ps==null?null:_ps.getPhyscalFile(); 245 if(res==null || !res.exists()) { 246 res=config.getResource(_ps.getDisplayPath()); 247 if(res!=null && res.exists()) dspPath=res.getAbsolutePath(); 248 } 249 else dspPath=res.getAbsolutePath(); 250 } 251 else dspPath=res.getAbsolutePath(); 252 253 // template is absolute, so this is not necessary if(!res.exists()) res = ResourceUtil.toResourceNotExisting(ThreadLocalPageContext.get(), template,true,true); 254 255 // class was not build on the local filesystem 256 if(!res.exists()) { 257 // try to make a match by class name 258 259 SourceInfo si=pc!=null?MappingUtil.getMatch(pc,trace):MappingUtil.getMatch(config,trace); 260 if(si!=null && si.relativePath!=null) { 261 dspPath=si.relativePath; 262 res = ResourceUtil.toResourceNotExisting(ThreadLocalPageContext.get(), si.relativePath,true,true); 263 if(!res.exists()) { 264 PageSource _ps = PageSourceImpl.best(config.getPageSources(ThreadLocalPageContext.get(), null, si.relativePath, false, false, true)); 265 if(_ps!=null && _ps.exists()) { 266 res=_ps.getResource(); 267 } 268 } 269 } 270 } 271 272 if(res.exists()) { 273 InputStream is = res.getInputStream(); 274 if (ClassUtil.isBytecode(is)) { 275 content = new String[] {}; //empty code array to show ?? 276 } 277 else 278 content=IOUtil.toStringArray(IOUtil.getReader(res,CharsetUtil.toCharset(config.getTemplateCharset()))); 279 IOUtil.closeEL(is); 280 } 281 else { 282 if(sources.size()>index)ps = sources.get(index); 283 else ps=null; 284 285 if(ps!=null && trace.getClassName().equals(ps.getFullClassName())) { 286 if(ps.physcalExists()) 287 content=IOUtil.toStringArray(IOUtil.getReader(ps.getPhyscalFile(), CharsetUtil.toCharset(config.getTemplateCharset()))); 288 template=ps.getDisplayPath(); 289 } 290 } 291 } 292 catch (Throwable th) { 293 ExceptionUtil.rethrowIfNecessary(th); 294 th.printStackTrace(); 295 } 296 297 // check last 298 if(tagContext.size()>0){ 299 try { 300 Struct last=(Struct) tagContext.getE(tagContext.size()); 301 if(last.get(KeyConstants._Raw_Trace).equals(trace.toString()))continue; 302 } 303 catch (Exception e) { 304 //e.printStackTrace(); 305 } 306 } 307 308 item=new StructImpl(); 309 line=trace.getLineNumber(); 310 item.setEL(KeyConstants._template,dspPath); 311 item.setEL(KeyConstants._line,new Double(line)); 312 item.setEL(KeyConstants._id,"??"); 313 item.setEL(KeyConstants._Raw_Trace,trace.toString()); 314 item.setEL(KeyConstants._type,"cfml"); 315 item.setEL(KeyConstants._column,new Double(0)); 316 if(content!=null) { 317 if(content.length > 0) { 318 item.setEL(KeyConstants._codePrintHTML,getCodePrint(content,line,true)); 319 item.setEL(KeyConstants._codePrintPlain,getCodePrint(content,line,false)); 320 } else { 321 item.setEL(KeyConstants._codePrintHTML,"??"); 322 item.setEL(KeyConstants._codePrintPlain,"??"); 323 } 324 } 325 else { 326 item.setEL(KeyConstants._codePrintHTML,""); 327 item.setEL(KeyConstants._codePrintPlain,""); 328 } 329 // FUTURE id 330 tagContext.appendEL(item); 331 } 332 } 333 334 335 336 public int getPageDeep() { 337 StackTraceElement[] traces = getStackTraceElements(this); 338 339 String template="",tlast; 340 StackTraceElement trace=null; 341 int index=0; 342 for(int i=0;i<traces.length;i++) { 343 trace=traces[i]; 344 tlast=template; 345 template=trace.getFileName(); 346 if(trace.getLineNumber()<=0 || template==null || ResourceUtil.getExtension(template,"").equals("java")) continue; 347 if(!StringUtil.emptyIfNull(tlast).equals(template))index++; 348 349 } 350 return index; 351 } 352 353 354 @Override 355 public Struct getErrorBlock(PageContext pc,ErrorPage ep) { 356 Struct struct=new StructImpl(); 357 358 struct.setEL("browser",pc.cgiScope().get("HTTP_USER_AGENT","")); 359 struct.setEL("datetime",new DateTimeImpl(pc)); 360 struct.setEL("diagnostics",getMessage()+' '+getDetail()+"<br>The error occurred on line "+getLine(pc.getConfig())+" in file "+getFile(pc.getConfig())+"."); 361 struct.setEL("GeneratedContent",getGeneratedContent(pc)); 362 struct.setEL("HTTPReferer",pc.cgiScope().get("HTTP_REFERER","")); 363 struct.setEL("mailto",ep.getMailto()); 364 struct.setEL(KeyConstants._message,getMessage()); 365 struct.setEL("QueryString",StringUtil.emptyIfNull(pc. getHttpServletRequest().getQueryString())); 366 struct.setEL("RemoteAddress",pc.cgiScope().get("REMOTE_ADDR","")); 367 struct.setEL("RootCause",getCatchBlock(pc)); 368 struct.setEL("StackTrace",getStackTraceAsString()); 369 struct.setEL(KeyConstants._template,pc. getHttpServletRequest().getServletPath()); 370 371 struct.setEL(KeyConstants._Detail,getDetail()); 372 struct.setEL("ErrorCode",getErrorCode()); 373 struct.setEL("ExtendedInfo",getExtendedInfo()); 374 struct.setEL(KeyConstants._type,getTypeAsString()); 375 struct.setEL("TagContext",getTagContext(pc.getConfig())); 376 struct.setEL("additional",additional); 377 // TODO RootCause,StackTrace 378 379 return struct; 380 } 381 382 private String getGeneratedContent(PageContext pc){ 383 PageContextImpl pci=(PageContextImpl)pc; 384 CFMLWriter ro=pci.getRootOut(); 385 String gc=ro.toString(); 386 try{ 387 ro.clearBuffer(); 388 } 389 catch(IOException ioe){} 390 if(gc==null) return ""; 391 return gc; 392 } 393 394 395 /** 396 * @return return the file where the failure occurred 397 */ 398 private String getFile(Config config) { 399 if(getTagContext(config).size()==0) return ""; 400 401 Struct sct=(Struct) getTagContext(config).get(1,null); 402 return Caster.toString(sct.get(KeyConstants._template,""),""); 403 } 404 405 public String getLine(Config config) { 406 if(getTagContext(config).size()==0) return ""; 407 408 Struct sct=(Struct) getTagContext(config).get(1,null); 409 return Caster.toString(sct.get(KeyConstants._line,""),""); 410 } 411 412 @Override 413 public void addContext(PageSource pr, int line, int column, StackTraceElement element) { 414 if(line==-187) { 415 sources.add(pr); 416 return; 417 } 418 419 Struct struct=new StructImpl(); 420 //print.out(pr.getDisplayPath()); 421 try { 422 String[] content=pr.getSource(); 423 struct.set(KeyConstants._template,pr.getDisplayPath()); 424 struct.set(KeyConstants._line,new Double(line)); 425 struct.set(KeyConstants._id,"??"); 426 struct.set(KeyConstants._Raw_Trace,(element!=null)?element.toString():""); 427 struct.set(KeyConstants._Type,"cfml"); 428 struct.set(KeyConstants._column,new Double(column)); 429 if(content!=null){ 430 struct.set(KeyConstants._codePrintHTML,getCodePrint(content,line,true)); 431 struct.set(KeyConstants._codePrintPlain,getCodePrint(content,line,false)); 432 } 433 tagContext.append(struct); 434 } 435 catch (Exception e) {} 436 } 437 438 private static String getCodePrint(String[] content,int line, boolean asHTML ) { 439 StringBuilder sb=new StringBuilder(); 440 // bad Line 441 for(int i=line-2;i<line+3;i++) { 442 if(i>0 && i<=content.length) { 443 if(asHTML && i==line)sb.append("<b>"); 444 if(asHTML)sb.append(i+": "+StringUtil.escapeHTML(content[i-1])); 445 else sb.append(i+": "+(content[i-1])); 446 if(asHTML && i==line)sb.append("</b>"); 447 if(asHTML)sb.append("<br>"); 448 sb.append('\n'); 449 } 450 } 451 return sb.toString(); 452 } 453 454 @Override 455 public DumpData toDumpData(PageContext pageContext, int maxlevel, DumpProperties dp) { 456 457 //FFFFCF 458 DumpTable htmlBox = new DumpTable("exception","#ff9900","#FFCC00","#000000"); 459 htmlBox.setTitle("Lucee ["+Info.getVersionAsString()+"] - Error ("+StringUtil.ucFirst(getTypeAsString())+")"); 460 461 462 // Message 463 htmlBox.appendRow(1,new SimpleDumpData("Message"),new SimpleDumpData(getMessage())); 464 465 // Detail 466 String detail=getDetail(); 467 if(!StringUtil.isEmpty(detail,true)) 468 htmlBox.appendRow(1,new SimpleDumpData("Detail"),new SimpleDumpData(detail)); 469 470 // additional 471 Iterator<Key> it = additional.keyIterator(); 472 Collection.Key k; 473 while(it.hasNext()) { 474 k=it.next(); 475 htmlBox.appendRow(1,new SimpleDumpData(k.getString()),new SimpleDumpData(additional.get(k,"").toString())); 476 } 477 478 Array tagContext = getTagContext(pageContext.getConfig()); 479 // Context MUSTMUST 480 if(tagContext.size()>0) { 481 //Collection.Key[] keys=tagContext.keys(); 482 Iterator<Object> vit = tagContext.valueIterator(); 483 //Entry<Key, Object> te; 484 DumpTable context=new DumpTable("#ff9900","#FFCC00","#000000"); 485 //context.setTitle("The Error Occurred in"); 486 //context.appendRow(0,new SimpleDumpData("The Error Occurred in")); 487 context.appendRow(7, 488 new SimpleDumpData(""), 489 new SimpleDumpData("template"), 490 new SimpleDumpData("line")); 491 try { 492 boolean first=true; 493 while(vit.hasNext()) { 494 Struct struct=(Struct)vit.next(); 495 context.appendRow(1, 496 new SimpleDumpData(first?"called from ":"occurred in"), 497 new SimpleDumpData(struct.get(KeyConstants._template,"")+""), 498 new SimpleDumpData(Caster.toString(struct.get(KeyConstants._line,null)))); 499 first=false; 500 } 501 htmlBox.appendRow(1,new SimpleDumpData("Context"),context); 502 503 504 // Code 505 String strCode=((Struct)tagContext.get(1,null)).get(KeyConstants._codePrintPlain,"").toString(); 506 String[] arrCode = ListUtil.listToStringArray(strCode, '\n'); 507 arrCode=ListUtil.trim(arrCode); 508 DumpTable code=new DumpTable("#ff9900","#FFCC00","#000000"); 509 510 for(int i=0;i<arrCode.length;i++) { 511 code.appendRow(i==2?1:0,new SimpleDumpData(arrCode[i])); 512 } 513 htmlBox.appendRow(1,new SimpleDumpData("Code"),code); 514 515 } 516 catch (PageException e) {} 517 } 518 519 520 // Java Stacktrace 521 String strST=getStackTraceAsString(); 522 String[] arrST = ListUtil.listToStringArray(strST, '\n'); 523 arrST=ListUtil.trim(arrST); 524 DumpTable st=new DumpTable("#ff9900","#FFCC00","#000000"); 525 526 for(int i=0;i<arrST.length;i++) { 527 st.appendRow(i==0?1:0,new SimpleDumpData(arrST[i])); 528 } 529 htmlBox.appendRow(1,new SimpleDumpData("Java Stacktrace"),st); 530 531 return htmlBox; 532 } 533 534 @Override 535public String getStackTraceAsString() { 536 return getStackTraceAsString(ThreadLocalPageContext.get()); 537 } 538 539 public String getStackTraceAsString(PageContext pc) { 540 541 StringWriter sw=new StringWriter(); 542 PrintWriter pw=new PrintWriter(sw); 543 printStackTrace(pw); 544 pw.flush(); 545 return sw.toString(); 546 } 547 548 @Override 549 public void printStackTrace() { 550 printStackTrace(System.err); 551 } 552 553 public void printStackTrace(PageContext pc) { 554 printStackTrace(System.err,pc); 555 } 556 557 @Override 558 public void printStackTrace(PrintStream s) { 559 printStackTrace(s, ThreadLocalPageContext.get()); 560 } 561 562 public void printStackTrace(PrintStream s,PageContext pc) { 563 StackTraceElement[] traces = getStackTraceElements(this); 564 StackTraceElement trace; 565 566 s.println(getMessage()); 567 for(int i=0;i<traces.length;i++){ 568 trace=traces[i]; 569 s.println("\tat "+toString(pc,trace)+":"+trace.getLineNumber()); 570 } 571 } 572 573 574 @Override 575 public void printStackTrace(PrintWriter s) { 576 printStackTrace(s, ThreadLocalPageContext.get()); 577 } 578 579 public void printStackTrace(PrintWriter s,PageContext pc) { 580 StackTraceElement[] traces = getStackTraceElements(this); 581 StackTraceElement trace; 582 583 s.println(getMessage()); 584 for(int i=0;i<traces.length;i++){ 585 trace=traces[i]; 586 s.println("\tat "+toString(pc,trace)+":"+trace.getLineNumber()); 587 } 588 } 589 590 591 public static String toString(PageContext pc, StackTraceElement trace) { 592 Config config = ThreadLocalPageContext.getConfig(pc); 593 String path=null; 594 595 if(trace.getFileName()==null || trace.getFileName().endsWith(".java")) 596 return trace.toString(); 597 if(config!=null) { 598 Resource res = config.getResource( 599 trace.getFileName()); 600 if(res.exists()) path=trace.getFileName(); 601 602 // get path from source 603 if(path==null){ 604 SourceInfo si=MappingUtil.getMatch(pc,config,trace); 605 if(si!=null) { 606 String abs=si.absolutePath(pc); 607 if(!StringUtil.isEmpty(abs)) { 608 Resource r = config.getResource(abs); 609 if(r.exists()) path=abs; 610 } 611 if(path==null && si.relativePath!=null) path=si.relativePath; 612 } 613 if(path==null) path=trace.getFileName(); 614 } 615 } 616 return trace.getClassName() + "." + trace.getMethodName() + 617 (trace.isNativeMethod() ? "(Native Method)" : 618 (path != null && trace.getLineNumber() >= 0 ? 619 "(" + path + ":" + trace.getLineNumber() + ")" : 620 (path != null ? "("+path+")" : "(Unknown Source)"))); 621 622 } 623 624 625 private static StackTraceElement[] getStackTraceElements(Throwable t) { 626 StackTraceElement[] st=getStackTraceElements(t,true); 627 if(st==null) st= getStackTraceElements(t,false); 628 return st; 629 } 630 631 private static StackTraceElement[] getStackTraceElements(Throwable t, boolean onlyWithCML) { 632 StackTraceElement[] st; 633 Throwable cause=t.getCause(); 634 if(cause!=null){ 635 st = getStackTraceElements(cause,onlyWithCML); 636 if(st!=null) return st; 637 } 638 639 st=t.getStackTrace(); 640 if(!onlyWithCML || hasCFMLinStacktrace(st)){ 641 return st; 642 } 643 return null; 644 } 645 646 647 private static boolean hasCFMLinStacktrace(StackTraceElement[] traces) { 648 for(int i=0;i<traces.length;i++) { 649 if(traces[i].getFileName()!=null && !traces[i].getFileName().endsWith(".java")) return true; 650 } 651 return false; 652 } 653 /*ths code has produced duplettes 654 * private static void fillStackTraceElements(ArrayList<StackTraceElement> causes, Throwable t) { 655 if(t==null) return; 656 fillStackTraceElements(causes, t.getCause()); 657 StackTraceElement[] traces = t.getStackTrace(); 658 for(int i=0;i<traces.length;i++) { 659 //if(causes.contains(traces[i])) 660 causes.add(traces[i]); 661 } 662 }*/ 663 664 /** 665 * set a additional key value 666 * @param key 667 * @param value 668 */ 669 public void setAdditional(Collection.Key key, Object value) { 670 additional.setEL(key,StringUtil.toStringEmptyIfNull(value)); 671 } 672 673 674 @Override 675 public Throwable getRootCause() { 676 Throwable cause=this; 677 Throwable temp; 678 679 while((temp=cause.getCause())!=null)cause=temp; 680 return cause; 681 } 682 683 @Override 684 public int getTracePointer() { 685 return tracePointer; 686 } 687 @Override 688 public void setTracePointer(int tracePointer) { 689 this.tracePointer = tracePointer; 690 } 691 692 @Override 693 public boolean typeEqual(String type) { 694 if(type==null) return true; 695 type=StringUtil.toUpperCase(type); 696 // ANY 697 if(type.equals("ANY")) return true;// MUST check 698 // Type Compare 699 if(getTypeAsString().equalsIgnoreCase(type)) return true; 700 return getClass().getName().equalsIgnoreCase(type); 701 } 702 703 @Override 704 public String getTypeAsString() { 705 return type; 706 } 707 708 709 public String getType() { // for compatibility to ACF 710 return type; 711 } 712 713 @Override 714 public String getCustomTypeAsString() { 715 return customType==null?type:customType; 716 } 717 718 @Override 719 public Struct getAdditional() { 720 return additional; 721 }public Struct getAddional() { 722 return additional; 723 } 724 725 @Override 726 public StackTraceElement[] getStackTrace() { 727 return super.getStackTrace(); 728 } 729 public void setExposeMessage(boolean exposeMessage) { 730 this.exposeMessage=exposeMessage; 731 } 732 public boolean getExposeMessage() { 733 return exposeMessage; 734 } 735 736 /*public static void printStackTrace(PrintWriter s,Throwable t) { 737 738 //while((temp=cause.getCause())!=null)cause=temp; 739 740 StackTraceElement[] traces = t.getStackTrace(); 741 StackTraceElement trace; 742 743 s.println(t.getMessage()); 744 for(int i=0;i<traces.length;i++){ 745 trace=traces[i]; 746 s.println("\tat "+trace+":"+trace.getLineNumber()); 747 } 748 t=t.getCause(); 749 if(t!=null)printStackTrace(s,t); 750 }*/ 751 752 753 754}