001: package net.sourceforge.pmd.util.viewer.model;
002:
003: import java.io.StringReader;
004: import java.util.ArrayList;
005: import java.util.List;
006:
007: import net.sourceforge.pmd.TargetJDKVersion;
008: import net.sourceforge.pmd.ast.ASTCompilationUnit;
009: import net.sourceforge.pmd.ast.ParseException;
010: import net.sourceforge.pmd.ast.SimpleNode;
011: import net.sourceforge.pmd.jaxen.DocumentNavigator;
012:
013: import org.jaxen.BaseXPath;
014: import org.jaxen.JaxenException;
015: import org.jaxen.XPath;
016:
017: public class ViewerModel {
018:
019: private List<ViewerModelListener> listeners;
020: private SimpleNode rootNode;
021: private List evaluationResults;
022:
023: public ViewerModel() {
024: listeners = new ArrayList<ViewerModelListener>(5);
025: }
026:
027: public SimpleNode getRootNode() {
028: return rootNode;
029: }
030:
031: /**
032: * commits source code to the model.
033: * all existing source will be replaced
034: */
035: public void commitSource(String source, TargetJDKVersion jdk) {
036: ASTCompilationUnit compilationUnit = jdk.createParser(
037: new StringReader(source)).CompilationUnit();
038: rootNode = compilationUnit;
039: fireViewerModelEvent(new ViewerModelEvent(this ,
040: ViewerModelEvent.CODE_RECOMPILED));
041: }
042:
043: /**
044: * determines whether the model has a compiled tree at it's disposal
045: *
046: * @return true if there is an AST, false otherwise
047: */
048: public boolean hasCompiledTree() {
049: return rootNode != null;
050: }
051:
052: /**
053: * evaluates the given XPath expression against the current tree
054: *
055: * @param xPath XPath expression to be evaluated
056: * @param evaluator object which requests the evaluation
057: */
058: public void evaluateXPathExpression(String xPath, Object evaluator)
059: throws ParseException, JaxenException {
060: XPath xpath = new BaseXPath(xPath, new DocumentNavigator());
061: evaluationResults = xpath.selectNodes(rootNode);
062: fireViewerModelEvent(new ViewerModelEvent(evaluator,
063: ViewerModelEvent.PATH_EXPRESSION_EVALUATED));
064: }
065:
066: /**
067: * retrieves the results of last evaluation
068: *
069: * @return a list containing the nodes selected by the last XPath expression
070: * <p/>
071: * evaluation
072: */
073: public List getLastEvaluationResults() {
074: return evaluationResults;
075: }
076:
077: /**
078: * selects the given node in the AST
079: *
080: * @param node node to be selected
081: * @param selector object which requests the selection
082: */
083: public void selectNode(SimpleNode node, Object selector) {
084: fireViewerModelEvent(new ViewerModelEvent(selector,
085: ViewerModelEvent.NODE_SELECTED, node));
086: }
087:
088: /**
089: * appends the given fragment to the XPath expression
090: *
091: * @param pathFragment fragment to be added
092: * @param appender object that is trying to append the fragment
093: */
094: public void appendToXPathExpression(String pathFragment,
095: Object appender) {
096: fireViewerModelEvent(new ViewerModelEvent(appender,
097: ViewerModelEvent.PATH_EXPRESSION_APPENDED, pathFragment));
098: }
099:
100: public void addViewerModelListener(ViewerModelListener l) {
101: listeners.add(l);
102: }
103:
104: public void removeViewerModelListener(ViewerModelListener l) {
105: listeners.remove(l);
106: }
107:
108: protected void fireViewerModelEvent(ViewerModelEvent e) {
109: for (int i = 0; i < listeners.size(); i++) {
110: listeners.get(i).viewerModelChanged(e);
111: }
112: }
113: }
|