/* * Copyright (C) 2000 - 2012 TagServlet Ltd * * This file is part of Open BlueDragon (OpenBD) CFML Server Engine. * * OpenBD is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * Free Software Foundation,version 3. * * OpenBD is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with OpenBD. If not, see http://www.gnu.org/licenses/ * * Additional permission under GNU GPL version 3 section 7 * * If you modify this Program, or any covered work, by linking or combining * it with any of the JARS listed in the README.txt (or a modified version of * (that library), containing parts covered by the terms of that JAR, the * licensors of this Program grant you additional permission to convey the * resulting work. * README.txt @ http://www.openbluedragon.org/license/README.txt * * http://www.openbluedragon.org/ * $Id: VisionLiveSession.java 2496 2015-02-01 02:19:29Z alan $ */ package com.bluedragon.vision.engine; import java.util.Iterator; import java.util.List; import org.bson.Document; import com.mongodb.client.MongoCollection; import com.naryx.tagfusion.cfm.engine.cfArrayData; import com.naryx.tagfusion.cfm.engine.cfComponentData; import com.naryx.tagfusion.cfm.engine.cfData; import com.naryx.tagfusion.cfm.engine.cfNumberData; import com.naryx.tagfusion.cfm.engine.cfSession; import com.naryx.tagfusion.cfm.engine.cfStringData; import com.naryx.tagfusion.cfm.engine.cfStructData; import com.naryx.tagfusion.cfm.engine.cfmRunTimeException; import com.naryx.tagfusion.cfm.file.cfFile; import com.naryx.tagfusion.cfm.parser.CFExpression; import com.naryx.tagfusion.cfm.parser.script.CFParsedStatement; import com.naryx.tagfusion.cfm.parser.script.userDefinedFunction; import com.naryx.tagfusion.cfm.sql.cfSQLQueryData; import com.naryx.tagfusion.cfm.sql.preparedData; import com.naryx.tagfusion.cfm.sql.resultSetHolder; import com.naryx.tagfusion.cfm.tag.cfCOMPONENT; import com.naryx.tagfusion.cfm.tag.cfFUNCTION; import com.naryx.tagfusion.cfm.tag.cfTag; import com.naryx.tagfusion.util.debugRecorder; import com.naryx.tagfusion.util.debuggerListener; public class VisionLiveSession implements debuggerListener, debugRecorder { private cfSession session; private boolean bCurrentlyStopped = false, bRunToEnd = false, bStepToBreakPoint = true, bOnException = false, bStepOver = false; private cfTag currentTag = null; private String currentFile = null; private cfArrayData queryStack; private int currentLine = 0; private cfTag pCurrentTag = null; private cfData pcfData = null; private boolean bTerminate = false; private int statsTotalTags=0, statsTotalStatements=0; private long startTime; public VisionLiveSession( cfSession session ){ this.session = session; this.session.registerDebugger( this ); this.session.registerDebugRecorder( this ); this.queryStack = cfArrayData.createArray(1); this.startTime = System.currentTimeMillis(); } public cfSession getCFSession(){ return session; } public long getExecTime(){ return System.currentTimeMillis() - startTime; } public cfTag getProfileCurrentTag(){ return pCurrentTag; } public cfData getProfileData(){ return pcfData; } public final void endFile(cfFile thisFile) {} public final void endSession() {} public final void write(int ch) {} public final void write(byte[] arrayCh) {} public final void writtenBytes(int total) {} public final void registerSession(cfSession thisSession) {} public final void runExpression(CFExpression expr){} public final void startFunction(cfFUNCTION cfFUNCTION) {} public final void endFunction(cfFUNCTION cfFUNCTION) {} public final void setHTTPHeader(String name, String value) {} public final void setHTTPStatus(int sc, String value) {} public final void startFile(cfFile thisFile) {} public void endTag(cfTag thisTag) { pCurrentTag = null; if ( bTerminate ) session.abortPageProcessing(); } private void pauseEngine(){ synchronized( this ){ try { bStepToBreakPoint = false; bStepOver = false; bCurrentlyStopped = true; wait(); } catch (InterruptedException e) { } finally { bCurrentlyStopped = false; currentTag = null; } } } public void startScriptStatement(CFParsedStatement statement) { if ( bTerminate ){ session.abortPageProcessing(); return; } statsTotalStatements++; if ( bRunToEnd ) return; if ( statement.getHostTag() == null ) return; int linePos = statement.getLine() + statement.getHostTag().posLine - 1; if ( bStepToBreakPoint ){ if ( CoreServer.thisInst.fileBreakPoints.size() == 0 ) return; String uri = statement.getHostTag().getFile().getPath(); if ( !CoreServer.thisInst.fileBreakPoints.containsKey( uri + "@" + linePos ) ) return; } else if ( bStepOver ){ if ( !getActiveFile(statement.getHostTag()).equals( currentFile ) ) return; } currentTag = statement.getHostTag(); currentLine = linePos; pauseEngine(); } public void startTag(cfTag thisTag) { pCurrentTag = thisTag; statsTotalTags++; if ( bRunToEnd ) return; if ( bStepToBreakPoint ){ String uri = thisTag.getFile().getPath(); if ( !CoreServer.thisInst.fileBreakPoints.containsKey( uri + "@" + thisTag.posLine ) ) return; } else if ( bStepOver ){ if ( !getActiveFile(thisTag).equals( currentFile ) ) return; } currentTag = thisTag; currentLine = thisTag.posLine; pauseEngine(); } public void step(){ synchronized( this ){ notify(); } } public void stepToBreakPoint(){ bStepToBreakPoint = true; step(); } public void stepToEnd(){ bRunToEnd = true; step(); } public void stepOver(){ bStepOver = true; currentFile = getActiveFile(); step(); } public void exceptionThrown(cfmRunTimeException cfException, cfFile f, cfTag thisTag) { if ( bRunToEnd || !CoreServer.thisInst.bStopOnException ) return; try { session.setData( "cfcatch", cfException.getCatchData() ); } catch (cfmRunTimeException e1) {} currentTag = thisTag; currentLine = thisTag.posLine; pauseEngine(); } public void queryRan(String template, String qname, cfSQLQueryData query, List<preparedData> preparedDataList) { try { cfStructData data = new cfStructData(); data.setData( "querytype", new cfStringData( "query" ) ); data.setData( "f", new cfStringData( template.replace('\\', '/') ) ); data.setData( "name", new cfStringData( qname ) ); data.setData( "rows", new cfNumberData( query.getSize() ) ); data.setData( "time", new cfNumberData( query.getExecuteTime() ) ); data.setData( "ds", new cfStringData( query.getDataSourceName() ) ); data.setData( "dstype", new cfStringData( query.getDataTypeName() ) ); data.setData( "columns", new cfStringData( query.getColumns() ) ); data.setData( "sql", new cfStringData( query.getQueryString() ) ); if ( preparedDataList != null && preparedDataList.size() > 0 ){ StringBuilder sb = new StringBuilder( 32 ); Iterator<preparedData> it = preparedDataList.iterator(); while ( it.hasNext() ){ preparedData pData = it.next(); sb.append( pData.toString() ); sb.append( ";" ); } data.setData( "prepared", new cfStringData( sb.toString() ) ); }else data.setData( "prepared", cfStringData.EMPTY_STRING ); queryStack.addElement( data ); } catch (cfmRunTimeException e) {} } public void storedProcRan(String template, String datasrc, String procName, long execTime, List<preparedData> preparedDataList, List<resultSetHolder> results) { try { cfStructData data = new cfStructData(); data.setData( "querytype", new cfStringData( "proc" ) ); data.setData( "f", new cfStringData( template.replace('\\', '/') ) ); data.setData( "name", new cfStringData( procName ) ); data.setData( "time", new cfNumberData( execTime ) ); data.setData( "ds", new cfStringData( datasrc ) ); if ( preparedDataList != null && preparedDataList.size() > 0 ){ StringBuilder sb = new StringBuilder( 32 ); Iterator<preparedData> it = preparedDataList.iterator(); while ( it.hasNext() ){ preparedData pData = it.next(); sb.append( pData.toString() ); sb.append( ";" ); } data.setData( "prepared", new cfStringData( sb.toString() ) ); }else data.setData( "prepared", cfStringData.EMPTY_STRING ); queryStack.addElement( data ); } catch (cfmRunTimeException e) {} } public void onRunTimeException(cfmRunTimeException cfException) {} public void insertRan(String template, String datasrc, String sql) {} public void updateRan(String template, String datasrc, String sql) {} public debugRecorder copy() {return this; } public void dump(cfSession session) {} public void recordTimer(String timing) {} public void recordTracepoint(String tracePoint) {} public void setShow(boolean show) {} public void startRequest() {} public void endRequest() {} public boolean getShow() {return false;} public boolean getShowDBActivity() {return true;} public cfData getQueryStack() {return queryStack; } public int getCurrentLine(){return currentLine;} public boolean isStopped(){ return bCurrentlyStopped;} public boolean isTerminating(){ return bTerminate;} public boolean isOnException(){return bOnException;} public cfTag getStoppedTag(){return currentTag;} public int getStatsTags(){ return statsTotalTags; } public int getStatsStatements(){ return statsTotalStatements; } public String getActiveFile(){ return getActiveFile( currentTag ); } public String getActiveFile( cfTag tag ){ if ( tag != null ) return tag.getFile().getPath().replace('\\','/'); /* If we are running the CFCOMPONENT/CFFUNCTION then the active file is actually wrong; we have to look for it else where */ if ( tag instanceof cfFUNCTION || tag instanceof cfCOMPONENT ){ cfComponentData c = session.getActiveComponentData(); if ( c != null ){ return c.getComponentPath().replace('\\','/'); } } /* If we still don't have it, then lets just use this one */ return session.activeFile().getPath().replace('\\','/'); } public void execOnStart(cfData data) { pcfData = data; } public void execOnEnd(cfData data) { pcfData = null; } public void terminate() { bTerminate = true; } @Override public void execStoredProc(String datasourceName, String callString, String procName, long execTime) {} public void execMongo( MongoCollection<Document> col, String action, Document qry, long execTime ){} public final void startScriptFunction(userDefinedFunction userDefinedFunction) {} public final void endScriptFunction(userDefinedFunction userDefinedFunction) {} }