/** * The XEditor class is used for manipulating and tracing XAspect Objects * (file extension *.XA). The majority of String processing is done here. * * @author JSeifried * @version 0.9.0 */ package jseifried.xaspecteditor; import java.util.Vector; import jseifried.xaspecteditor.dj.XAspectLanguage; import jseifried.xaspecteditor.view.XView; import org.eclipse.jface.text.IDocument; import org.eclipse.ui.editors.text.TextEditor; public class XEditor extends TextEditor { /** Flag denoting wether or not the trace is active */ private boolean traceActive; /** The XView object associated with the trace process */ private XView xview; public XEditor() { super(); setSourceViewerConfiguration(new XSourceViewerConfig()); traceActive = false; } /** * Wrapper method for setting the XView variable * * @param XView the view to be used for trace output * @see jseifred.xaspecteditor.view.XView */ public void setXView(XView view) { xview = view; } /** * Wrapper method for setting the trace flag */ public void activateTrace() { traceActive = true; } /** * Captures current cursor position if trace is active, and passes control * to identifyLine() * * @see identifyLine() */ public void handleCursorPositionChanged() { super.handleCursorPositionChanged(); try { xview.refresh("", 0, 0, 0); if(isDirty()) { traceActive = false; } if(traceActive) { xview.refresh("Selector tracing active...", 0, 0, 200); int line = (new Integer(getCursorPosition().substring( 0,getCursorPosition().indexOf(":")).trim())).intValue()-1; int column = (new Integer(getCursorPosition().substring( getCursorPosition().indexOf(":")+ 2).trim())).intValue()-1; identifyLine(line, column); } } //used to catch multi-line selects catch (Exception e) {} } /** * Gets the String representation of the line corresponding to int line * * @param int the line number of the desired string * @return String representing the line at int line */ String getLine(int line) { IDocument doc = getDocumentProvider().getDocument(getEditorInput()); try { return doc.get(doc.getLineOffset(line),doc.getLineLength(line)); } //catch references to lines that do not exist catch (Exception e) {return null;} } /** * Identifies the type of line being selected and, if trace is active, * takes appropiate action to diplay the trace information * * @param int the line number of the cursor position * column the column number of the cursor position */ void identifyLine(int line, int column) { String string = getLine(line).trim(); if(!string.startsWith("declare")) return; String substring = string.substring(0,string.indexOf(":")); if(substring.endsWith("set")) { String cd = getClassDictionaryName(line); showTrace(traceNodeSet(line, cd)); } if(substring.endsWith("strategy")) { String cd = getClassDictionaryName(line); showTrace(traceStrategy(line, cd)); } } /** * Gathers trace information for a Strategy. Triggers getName(), * getStrategy(), and the traceStrategy method of XAspectLanguage. * * @param int the line number of the declare statement * cd String containing the name of the Class Dictionary used by the * Strategy being traced * * @return Vector containing the Nodes touched, active Class Dictionary, and * name of the Strategy. * * @see jseifried.xaspecteditor.dj.XAspectLanguage */ Vector traceStrategy(int line, String cd) { String contents = getDocumentProvider().getDocument(getEditorInput()).get(); String name = "Tracing Strategy "+ getName(line) + ":"; String strategy = getStrategy(line); Vector returnVal = XAspectLanguage.traceStrategy(contents, cd ,strategy); returnVal.add(name); return returnVal; } /** * Captures the String representing the Strategy * * @param int the line number of the declare statement * @return String representation of the Strategy */ String getStrategy(int line) { IDocument doc = getDocumentProvider().getDocument(getEditorInput()); int offsetBegin = 0, offsetEnd = 0; char current = '0'; try { offsetBegin = doc.getLineOffset(line); while(current!='"') { offsetBegin++; current = doc.getChar(offsetBegin); } current = '0'; offsetEnd = offsetBegin + 1; while(current!='"') { offsetEnd++; current = doc.getChar(offsetEnd); } return doc.get(offsetBegin+1, offsetEnd-offsetBegin-1); } //catches out-of-bounds errors with String indicies and line numbers catch (Exception e) {return null;} } /** * Gathers trace information for a Node Set. Triggers getName(), * getStrategy(), and the traceNodeSet method of XAspectLanguage. * * @param int the line number of the declare statement * cd String containing the name of the Class Dictionary used by the * Node Set being traced * * @return Vector containing the Nodes touched, active Class Dictionary, and * name of the Node Set. * * @see jseifried.xaspecteditor.dj.XAspectLanguage */ Vector traceNodeSet(int line, String cd) { String contents = getDocumentProvider().getDocument(getEditorInput()).get(); String name = "Tracing Node Set "+ getName(line) + ":"; String nodeset = getNodeSet(line); Vector returnVal = XAspectLanguage.traceStrategy(contents, cd ,"from * to *"); returnVal.add(name); return returnVal; } /** * Captures the String representing the Node Set * * @param int the line number of the declare statement * @return String representation of the Node Set */ String getNodeSet(int line) { IDocument doc = getDocumentProvider().getDocument(getEditorInput()); int offsetBegin = 0, offsetEnd = 0; char current = '0'; try { offsetBegin = doc.getLineOffset(line) + getLine(line).lastIndexOf(":"); offsetEnd = offsetBegin + 1; while(current!=';') { offsetEnd++; current = doc.getChar(offsetEnd); } return doc.get(offsetBegin+1, offsetEnd-offsetBegin-1).trim(); } //catches out-of-bounds errors with String indicies and line numbers catch (Exception e) {return null;} } /** * Captures the name of the Selector that is being traced * * @param int the line number of the declare statement * @return String representing the name of the Selector */ String getName(int line) { IDocument doc = getDocumentProvider().getDocument(getEditorInput()); int offsetBegin = 0, offsetEnd = 0; char current = '0'; try { offsetBegin = doc.getLineOffset(line); while(current!=':') { offsetBegin++; current = doc.getChar(offsetBegin); } current = '0'; offsetEnd = offsetBegin + 1; while(current!=':') { offsetEnd++; current = doc.getChar(offsetEnd); } return doc.get(offsetBegin+1, offsetEnd-offsetBegin-1).trim(); } //catches out-of-bounds errors with String indicies and line numbers catch (Exception e) {return null;} } /** * Captures the name of the Class Dictionary used by the Selector that * is being traced. * * @param int the line number of the declare statement * @return String representing the name of the Class Dictionary */ String getClassDictionaryName(int line) { String string = "", returnVal = null; int index = 0; while((!string.startsWith("declare")) || (!string.endsWith("dictionary"))) { line++; string = getLine(line).trim(); index = string.indexOf(":"); if(index!=-1) string = getLine(line).trim().substring(0,index); } returnVal = getLine(line).trim().substring( index+1,getLine(line).trim().indexOf(";")).trim(); return returnVal; } /** * Displays the results of the trace in the XView. * * @param Vector the resulting data of the trace * @see jseifried.xaspecteditor.view.XView */ void showTrace(Vector trace) { String string = trace.elementAt(2).toString() + "\n\n" + trace.elementAt(0).toString(); xview.refresh(string, 0, 0, 200); } /** * Clear trace data when the editor window is closed. */ public void dispose() { xview.refresh("",0,0,0); super.dispose(); } }