1 package net.sourceforge.pmd.util.viewer.model;
2
3 import net.sourceforge.pmd.TargetJDK1_4;
4 import net.sourceforge.pmd.ast.ASTCompilationUnit;
5 import net.sourceforge.pmd.ast.ParseException;
6 import net.sourceforge.pmd.ast.SimpleNode;
7 import net.sourceforge.pmd.jaxen.DocumentNavigator;
8 import org.jaxen.BaseXPath;
9 import org.jaxen.JaxenException;
10 import org.jaxen.XPath;
11
12 import java.io.StringReader;
13 import java.util.List;
14 import java.util.Vector;
15
16 /***
17 * The model for the viewer gui
18 * <p/>
19 * <p/>
20 * <p/>
21 * <p/>
22 * <p/>
23 * This is the model part of MVC
24 * <p/>
25 * </p>
26 *
27 * @author Boris Gruschko ( boris at gruschko.org )
28 * @version $Id: ViewerModel.java,v 1.8 2005/08/23 17:17:49 tomcopeland Exp $
29 */
30 public class ViewerModel {
31 private Vector listeners;
32 private SimpleNode rootNode;
33 private List evaluationResults;
34
35 /***
36 * constructs the model
37 */
38 public ViewerModel() {
39 listeners = new Vector(5);
40 }
41
42 /***
43 * Retrieves AST's root node
44 *
45 * @return AST's root node
46 */
47 public SimpleNode getRootNode() {
48 return rootNode;
49 }
50
51 /***
52 * commits source code to the model.
53 * <p/>
54 * <p/>
55 * <p/>
56 * <p/>
57 * <p/>
58 * all existing source will be replaced
59 * <p/>
60 * </p>
61 *
62 * @param source source to be commited
63 */
64 public void commitSource(String source) {
65 ASTCompilationUnit compilationUnit = new TargetJDK1_4().createParser(new StringReader(source)).CompilationUnit();
66 rootNode = compilationUnit;
67 fireViewerModelEvent(new ViewerModelEvent(this, ViewerModelEvent.CODE_RECOMPILED));
68 }
69
70 /***
71 * determines wheteher the model has a compiled tree at it's disposal
72 *
73 * @return true if there is an AST, false otherwise
74 */
75 public boolean hasCompiledTree() {
76 return rootNode != null;
77 }
78
79 /***
80 * evaluates the given XPath expression against the current tree
81 *
82 * @param xPath XPath expression to be evaluated
83 * @param evaluator object which requests the evaluation
84 */
85 public void evaluateXPathExpression(String xPath, Object evaluator)
86 throws ParseException, JaxenException {
87 XPath xpath = new BaseXPath(xPath, new DocumentNavigator());
88 evaluationResults = xpath.selectNodes(rootNode);
89 fireViewerModelEvent(new ViewerModelEvent(evaluator, ViewerModelEvent.PATH_EXPRESSION_EVALUATED));
90 }
91
92 /***
93 * retrieves the results of last evaluation
94 *
95 * @return a list containing the nodes selected by the last XPath expression
96 * <p/>
97 * evaluation
98 */
99 public List getLastEvaluationResults() {
100 return evaluationResults;
101 }
102
103 /***
104 * selects the given node in the AST
105 *
106 * @param node node to be selected
107 * @param selector object which requests the selection
108 */
109 public void selectNode(SimpleNode node, Object selector) {
110 fireViewerModelEvent(new ViewerModelEvent(selector, ViewerModelEvent.NODE_SELECTED, node));
111 }
112
113 /***
114 * appends the given fragment to the XPath expression
115 *
116 * @param pathFragment fragment to be added
117 * @param appender object that is trying to append the fragment
118 */
119 public void appendToXPathExpression(String pathFragment, Object appender) {
120 fireViewerModelEvent(new ViewerModelEvent(appender, ViewerModelEvent.PATH_EXPRESSION_APPENDED, pathFragment));
121 }
122
123 /***
124 * adds a listener to the model
125 *
126 * @param l listener to be added
127 */
128 public void addViewerModelListener(ViewerModelListener l) {
129 listeners.add(l);
130 }
131
132 /***
133 * removes the lisetener from the model
134 *
135 * @param l listener to be removed
136 */
137 public void removeViewerModelListener(ViewerModelListener l) {
138 listeners.remove(l);
139 }
140
141 /***
142 * notifes all listener of a change in the model
143 *
144 * @param e change's reason
145 */
146 protected void fireViewerModelEvent(ViewerModelEvent e) {
147 for (int i = 0; i < listeners.size(); i++) {
148 ((ViewerModelListener) listeners.elementAt(i)).viewerModelChanged(e);
149 }
150 }
151 }