package railo.runtime.orm.hibernate; import java.lang.reflect.Method; import railo.commons.io.res.util.ResourceUtil; import railo.loader.engine.CFMLEngineFactory; import railo.runtime.Component; import railo.runtime.db.DataSource; import railo.runtime.exp.PageException; import railo.runtime.orm.ORMSession; import railo.runtime.type.Collection.Key; public class ExceptionUtil { private static Method setAdditional; public static PageException createException(SessionFactoryData data, Component cfc, String msg, String detail) { PageException pe = createException((ORMSession)null,cfc,msg,detail); if(data!=null)setAddional(pe,data); return pe; } public static PageException createException(SessionFactoryData data, Component cfc, Throwable t) { PageException pe = createException((ORMSession)null,cfc,t); if(data!=null)setAddional(pe,data); return pe; } public static PageException createException(ORMSession session,Component cfc,Throwable t) { PageException pe = CFMLEngineFactory.getInstance().getExceptionUtil().createApplicationException(t.getMessage()); pe.setStackTrace(t.getStackTrace()); if(session!=null)setAddional(session,pe); if(cfc!=null)setContext(pe,cfc); return pe; } public static PageException createException(ORMSession session,Component cfc,String message,String detail) { PageException pe = CFMLEngineFactory.getInstance().getExceptionUtil().createApplicationException(message); if(session!=null)setAddional(session,pe); if(cfc!=null)setContext(pe,cfc); return pe; } private static void setContext(PageException pe,Component cfc) { if(cfc!=null && getPageDeep(pe)==0)pe.addContext(cfc.getPageSource(), 1, 1, null); } private static void setAddional(PageException pe,SessionFactoryData data) { String[] names = data.getEntityNames(); setAdditional(pe,CommonUtil.createKey("Entities"), CommonUtil.toList(names, ", ")); setAddional(data.getDataSource(),pe); } private static void setAddional(ORMSession session,PageException pe) { String[] names = session.getEntityNames(); setAdditional(pe, CommonUtil.createKey("Entities"), CommonUtil.toList(names, ", ")); setAddional(session.getDataSource(),pe); } private static void setAddional(DataSource ds,PageException pe) { if(ds!=null){ String dsn=ds.getName(); if(dsn!=null)setAdditional(pe, CommonUtil.createKey("_Datasource"), dsn); } } private static int getPageDeep(PageException pe) { StackTraceElement[] traces = getStackTraceElements(pe); String template="",tlast; StackTraceElement trace=null; int index=0; for(int i=0;i<traces.length;i++) { trace=traces[i]; tlast=template; template=trace.getFileName(); if(trace.getLineNumber()<=0 || template==null || ResourceUtil.getExtension(template,"").equals("java")) continue; if(!(tlast==null?"":tlast).equals(template))index++; } return index; } private static StackTraceElement[] getStackTraceElements(Throwable t) { StackTraceElement[] st=getStackTraceElements(t,true); if(st==null) st= getStackTraceElements(t,false); return st; } private static StackTraceElement[] getStackTraceElements(Throwable t, boolean onlyWithCML) { StackTraceElement[] st; Throwable cause=t.getCause(); if(cause!=null){ st = getStackTraceElements(cause,onlyWithCML); if(st!=null) return st; } st=t.getStackTrace(); if(!onlyWithCML || hasCFMLinStacktrace(st)){ return st; } return null; } private static boolean hasCFMLinStacktrace(StackTraceElement[] traces) { for(int i=0;i<traces.length;i++) { if(traces[i].getFileName()!=null && !traces[i].getFileName().endsWith(".java")) return true; } return false; } public static void setAdditional(PageException pe, Key name, Object value) { try{ if(setAdditional==null || setAdditional.getDeclaringClass()!=pe.getClass()) { setAdditional=pe.getClass().getMethod("setAdditional", new Class[]{Key.class,Object.class}); } setAdditional.invoke(pe, new Object[]{name,value}); } catch(Throwable t){} } }