Clover coverage report - PMD - 3.7 Coverage timestamp: Wed May 31 2006 09:25:59 EDT FRAMES NO FRAMES |
file stats: | LOC: | 431 |  | Methods: | 22
| NCLOC: | 373 |  | Classes: | 4
Source file | Conditionals | Statements | Methods | TOTAL
Designer.java | 0% | 0% | 0% | 0% |

1 |  | /**
2 |  | * BSD-style license; for more info see http://pmd.sourceforge.net/license.html
3 |  | */
4 |  | package net.sourceforge.pmd.util.designer;
5 |  |
6 |  | import net.sourceforge.pmd.PMD;
7 |  | import net.sourceforge.pmd.RuleContext;
8 |  | import net.sourceforge.pmd.RuleSet;
9 |  | import net.sourceforge.pmd.SourceType;
10 |  | import net.sourceforge.pmd.TargetJDK1_3;
11 |  | import net.sourceforge.pmd.TargetJDK1_4;
12 |  | import net.sourceforge.pmd.TargetJDK1_5;
13 |  | import net.sourceforge.pmd.TargetJDKVersion;
14 |  | import net.sourceforge.pmd.ast.JavaParser;
15 |  | import net.sourceforge.pmd.ast.ParseException;
16 |  | import net.sourceforge.pmd.ast.SimpleNode;
17 |  | import net.sourceforge.pmd.jaxen.DocumentNavigator;
18 |  | import net.sourceforge.pmd.jaxen.MatchesFunction;
19 |  | import net.sourceforge.pmd.jsp.ast.JspCharStream;
20 |  | import net.sourceforge.pmd.jsp.ast.JspParser;
21 |  |
22 |  | import org.apache.xml.serialize.OutputFormat;
23 |  | import org.apache.xml.serialize.XMLSerializer;
24 |  | import org.jaxen.BaseXPath;
25 |  | import org.jaxen.JaxenException;
26 |  | import org.jaxen.XPath;
27 |  |
28 |  | import javax.swing.*;
29 |  | import java.awt.BorderLayout;
30 |  | import java.awt.Color;
31 |  | import java.awt.FlowLayout;
32 |  | import java.awt.Font;
33 |  | import java.awt.Toolkit;
34 |  | import java.awt.datatransfer.Clipboard;
35 |  | import java.awt.datatransfer.ClipboardOwner;
36 |  | import java.awt.datatransfer.StringSelection;
37 |  | import java.awt.datatransfer.Transferable;
38 |  | import java.awt.event.ActionEvent;
39 |  | import java.awt.event.ActionListener;
40 |  | import java.awt.event.KeyEvent;
41 |  | import java.io.IOException;
42 |  | import java.io.StringReader;
43 |  | import java.io.StringWriter;
44 |  | import java.lang.reflect.InvocationTargetException;
45 |  | import java.lang.reflect.Method;
46 |  | import java.util.Iterator;
47 |  | import java.util.List;
48 |  |
49 |  | public class Designer implements ClipboardOwner {
50 |  |
51 | 0 | private JavaParser createParser() {
52 | 0 | return getJDKVersion().createParser(new StringReader(codeEditorPane.getText()));
53 |  | }
54 |  |
55 | 0 | private JspParser createJspParser() {
56 | 0 | return new JspParser(new JspCharStream(new StringReader(codeEditorPane.getText())));
57 |  | }
58 |  |
59 |  |
60 | 0 | private SimpleNode getCompilationUnit() {
61 | 0 | if (getSourceType().equals(SourceType.JSP)) {
62 | 0 | return createJspParser().CompilationUnit();
63 |  | }
64 | 0 | return createParser().CompilationUnit();
65 |  | }
66 |  |
67 | 0 | private TargetJDKVersion getJDKVersion() {
68 | 0 | if (jdk14MenuItem.isSelected()) {
69 | 0 | return new TargetJDK1_4();
70 | 0 | } else if (jdk13MenuItem.isSelected()) {
71 | 0 | return new TargetJDK1_3();
72 |  | }
73 | 0 | return new TargetJDK1_5();
74 |  | }
75 |  |
76 | 0 | private SourceType getSourceType() {
77 | 0 | if (jspMenuItem.isSelected()) {
78 | 0 | return SourceType.JSP;
79 | 0 | } else if (jdk14MenuItem.isSelected()) {
80 | 0 | return SourceType.JAVA_14;
81 | 0 | } else if (jdk13MenuItem.isSelected()) {
82 | 0 | return SourceType.JAVA_13;
83 |  | }
84 | 0 | return SourceType.JAVA_15;
85 |  | }
86 |  |
87 |  | private class ShowListener implements ActionListener {
88 | 0 | public void actionPerformed(ActionEvent ae) {
89 | 0 | MyPrintStream ps = new MyPrintStream();
90 | 0 | System.setOut(ps);
91 | 0 | try {
92 | 0 | SimpleNode lastCompilationUnit = getCompilationUnit();
93 | 0 | lastCompilationUnit.dump("");
94 | 0 | astArea.setText(ps.getString());
95 |  | } catch (ParseException pe) {
96 | 0 | astArea.setText(pe.fillInStackTrace().getMessage());
97 |  | }
98 |  | }
99 |  | }
100 |  |
101 |  | private class DFAListener implements ActionListener {
102 | 0 | public void actionPerformed(ActionEvent ae) {
103 | 0 | try {
104 | 0 | DFAGraphRule dfaGraphRule = new DFAGraphRule();
105 | 0 | RuleSet rs = new RuleSet();
106 | 0 | SourceType sourceType = getSourceType();
107 | 0 | if(!sourceType.equals(SourceType.JSP)){
108 | 0 | rs.addRule(dfaGraphRule);
109 |  | }
110 | 0 | RuleContext ctx = new RuleContext();
111 | 0 | ctx.setSourceCodeFilename("[no filename]");
112 | 0 | StringReader reader = new StringReader(codeEditorPane.getText());
113 | 0 | PMD pmd = new PMD();
114 | 0 | pmd.setJavaVersion(getSourceType());
115 | 0 | pmd.processFile(reader, rs, ctx);
116 | 0 | List methods = dfaGraphRule.getMethods();
117 | 0 | if (methods != null && !methods.isEmpty()) {
118 | 0 | dfaPanel.resetTo(methods, codeEditorPane);
119 | 0 | dfaPanel.repaint();
120 |  | }
121 |  | } catch (Exception e) {
122 | 0 | e.printStackTrace();
123 |  | }
124 |  | }
125 |  |
126 |  | }
127 |  |
128 |  | private class XPathListener implements ActionListener {
129 | 0 | public void actionPerformed(ActionEvent ae) {
130 | 0 | xpathResults.clear();
131 | 0 | if (xpathQueryArea.getText().length() == 0) {
132 | 0 | xpathResults.addElement("XPath query field is empty");
133 | 0 | xpathResultList.repaint();
134 | 0 | codeEditorPane.requestFocus();
135 | 0 | return;
136 |  | }
137 | 0 | SimpleNode c = getCompilationUnit();
138 | 0 | try {
139 | 0 | XPath xpath = new BaseXPath(xpathQueryArea.getText(), new DocumentNavigator());
140 | 0 | for (Iterator iter = xpath.selectNodes(c).iterator(); iter.hasNext();) {
141 | 0 | StringBuffer sb = new StringBuffer();
142 | 0 | Object obj = iter.next();
143 | 0 | if (obj instanceof String) {
144 | 0 | System.out.println("Result was a string: " + ((String) obj));
145 | 0 | } else if (!(obj instanceof Boolean)) {
146 |  | // if it's a Boolean and it's 'false', what does that mean?
147 | 0 | SimpleNode node = (SimpleNode) obj;
148 | 0 | String name = node.getClass().getName().substring(node.getClass().getName().lastIndexOf('.') + 1);
149 | 0 | String line = " at line " + String.valueOf(node.getBeginLine());
150 | 0 | sb.append(name).append(line).append(System.getProperty("line.separator"));
151 | 0 | xpathResults.addElement(sb.toString().trim());
152 |  | }
153 |  | }
154 | 0 | if (xpathResults.isEmpty()) {
155 | 0 | xpathResults.addElement("No matching nodes " + System.currentTimeMillis());
156 |  | }
157 |  | } catch (ParseException pe) {
158 | 0 | xpathResults.addElement(pe.fillInStackTrace().getMessage());
159 |  | } catch (JaxenException je) {
160 | 0 | xpathResults.addElement(je.fillInStackTrace().getMessage());
161 |  | }
162 | 0 | xpathResultList.repaint();
163 | 0 | xpathQueryArea.requestFocus();
164 |  | }
165 |  | }
166 |  |
167 |  | private final CodeEditorTextPane codeEditorPane = new CodeEditorTextPane();
168 |  | private final JTextArea astArea = new JTextArea();
169 |  | private DefaultListModel xpathResults = new DefaultListModel();
170 |  | private final JList xpathResultList = new JList(xpathResults);
171 |  | private final JTextArea xpathQueryArea = new JTextArea(15, 30);
172 |  | private final JFrame frame = new JFrame("PMD Rule Designer");
173 |  | private final DFAPanel dfaPanel = new DFAPanel();
174 |  | private JRadioButtonMenuItem jdk13MenuItem;
175 |  | private JRadioButtonMenuItem jdk14MenuItem;
176 |  | private JRadioButtonMenuItem jdk15MenuItem;
177 |  | private JRadioButtonMenuItem jspMenuItem;
178 |  |
179 | 0 | public Designer() {
180 | 0 | MatchesFunction.registerSelfInSimpleContext();
181 |  |
182 | 0 | xpathQueryArea.setFont(new Font("Verdana", Font.PLAIN, 16));
183 | 0 | JSplitPane controlSplitPane = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, new JScrollPane(codeEditorPane), createXPathQueryPanel());
184 | 0 | JSplitPane resultsSplitPane = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, createASTPanel(), createXPathResultPanel());
185 |  |
186 | 0 | JTabbedPane tabbed = new JTabbedPane();
187 | 0 | tabbed.addTab("Abstract Syntax Tree / XPath", resultsSplitPane);
188 | 0 | tabbed.addTab("Data Flow Analysis", dfaPanel);
189 | 0 | try {
190 |  | // Remove when minimal runtime support is >= JDK 1.4
191 | 0 | Method setMnemonicAt = JTabbedPane.class.getMethod("setMnemonicAt", new Class[]{Integer.TYPE, Integer.TYPE});
192 | 0 | if (setMnemonicAt != null) {
193 |  | // // Compatible with >= JDK 1.4
194 |  | // tabbed.setMnemonicAt(0, KeyEvent.VK_A);
195 |  | // tabbed.setMnemonicAt(1, KeyEvent.VK_D);
196 | 0 | setMnemonicAt.invoke(tabbed, new Object[]{new Integer(0), new Integer(KeyEvent.VK_A)});
197 | 0 | setMnemonicAt.invoke(tabbed, new Object[]{new Integer(1), new Integer(KeyEvent.VK_D)});
198 |  | }
199 |  | } catch (NoSuchMethodException nsme) { // Runtime is < JDK 1.4
200 |  | } catch (IllegalAccessException e) { // Runtime is >= JDK 1.4 but there was an error accessing the function
201 | 0 | e.printStackTrace();
202 | 0 | throw new InternalError("Runtime reports to be >= JDK 1.4 yet String.split(java.lang.String) is broken.");
203 |  | } catch (IllegalArgumentException e) {
204 | 0 | e.printStackTrace();
205 | 0 | throw new InternalError("Runtime reports to be >= JDK 1.4 yet String.split(java.lang.String) is broken.");
206 |  | } catch (InvocationTargetException e) { // Runtime is >= JDK 1.4 but there was an error accessing the function
207 | 0 | e.printStackTrace();
208 | 0 | throw new InternalError("Runtime reports to be >= JDK 1.4 yet String.split(java.lang.String) is broken.");
209 |  | }
210 |  |
211 | 0 | JSplitPane containerSplitPane = new JSplitPane(JSplitPane.VERTICAL_SPLIT, controlSplitPane, tabbed);
212 | 0 | containerSplitPane.setContinuousLayout(true);
213 |  |
214 | 0 | JMenuBar menuBar = createMenuBar();
215 | 0 | frame.setJMenuBar(menuBar);
216 | 0 | frame.getContentPane().add(containerSplitPane);
217 | 0 | frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
218 |  |
219 | 0 | int screenHeight = Toolkit.getDefaultToolkit().getScreenSize().height;
220 | 0 | int screenWidth = Toolkit.getDefaultToolkit().getScreenSize().width;
221 | 0 | frame.setSize(screenHeight - (screenHeight / 4), screenHeight - (screenHeight / 4));
222 | 0 | frame.setLocation((screenWidth / 2) - frame.getWidth() / 2, (screenHeight / 2) - frame.getHeight() / 2);
223 | 0 | frame.setVisible(true);
224 | 0 | frame.pack();
225 | 0 | frame.show();
226 | 0 | resultsSplitPane.setDividerLocation(resultsSplitPane.getMaximumDividerLocation() - (resultsSplitPane.getMaximumDividerLocation() / 2));
227 |  | //containerSplitPane.setDividerLocation(containerSplitPane.getMaximumDividerLocation() / 2);
228 |  | }
229 |  |
230 | 0 | private JMenuBar createMenuBar() {
231 | 0 | JMenuBar menuBar = new JMenuBar();
232 | 0 | JMenu menu = new JMenu("JDK");
233 | 0 | ButtonGroup group = new ButtonGroup();
234 | 0 | jdk13MenuItem = new JRadioButtonMenuItem("JDK 1.3");
235 | 0 | jdk13MenuItem.setSelected(false);
236 | 0 | group.add(jdk13MenuItem);
237 | 0 | menu.add(jdk13MenuItem);
238 | 0 | jdk14MenuItem = new JRadioButtonMenuItem("JDK 1.4");
239 | 0 | jdk14MenuItem.setSelected(true);
240 | 0 | group.add(jdk14MenuItem);
241 | 0 | menu.add(jdk14MenuItem);
242 | 0 | jdk15MenuItem = new JRadioButtonMenuItem("JDK 1.5");
243 | 0 | jdk15MenuItem.setSelected(false);
244 | 0 | group.add(jdk15MenuItem);
245 | 0 | menu.add(jdk15MenuItem);
246 | 0 | jspMenuItem = new JRadioButtonMenuItem("JSP");
247 | 0 | jspMenuItem.setSelected(false);
248 | 0 | group.add(jspMenuItem);
249 | 0 | menu.add(jspMenuItem);
250 | 0 | menuBar.add(menu);
251 |  |
252 | 0 | JMenu actionsMenu = new JMenu("Actions");
253 | 0 | JMenuItem copyXMLItem = new JMenuItem("Copy xml to clipboard");
254 | 0 | copyXMLItem.addActionListener(new ActionListener() {
255 | 0 | public void actionPerformed(ActionEvent e) {
256 | 0 | copyXmlToClipboard();
257 |  | }
258 |  | });
259 | 0 | actionsMenu.add(copyXMLItem);
260 | 0 | JMenuItem createRuleXMLItem = new JMenuItem("Create rule XML");
261 | 0 | createRuleXMLItem.addActionListener(new ActionListener() {
262 | 0 | public void actionPerformed(ActionEvent e) {
263 | 0 | createRuleXML();
264 |  | }
265 |  | });
266 | 0 | actionsMenu.add(createRuleXMLItem);
267 | 0 | menuBar.add(actionsMenu);
268 |  |
269 | 0 | return menuBar;
270 |  | }
271 |  |
272 |  |
273 | 0 | private void createRuleXML() {
274 | 0 | JPanel rulenamePanel = new JPanel();
275 | 0 | rulenamePanel.setLayout(new FlowLayout());
276 | 0 | rulenamePanel.add(new JLabel("Rule name"));
277 | 0 | final JTextField rulenameField = new JTextField(30);
278 | 0 | rulenamePanel.add(rulenameField);
279 | 0 | JPanel rulemsgPanel = new JPanel();
280 | 0 | rulemsgPanel.setLayout(new FlowLayout());
281 | 0 | rulemsgPanel.add(new JLabel("Rule msg"));
282 | 0 | final JTextField rulemsgField = new JTextField(60);
283 | 0 | rulemsgPanel.add(rulemsgField);
284 | 0 | JPanel ruledescPanel = new JPanel();
285 | 0 | ruledescPanel.setLayout(new FlowLayout());
286 | 0 | ruledescPanel.add(new JLabel("Rule desc"));
287 | 0 | final JTextField ruledescField = new JTextField(60);
288 | 0 | ruledescPanel.add(ruledescField);
289 | 0 | JPanel ruleXMLPanel = new JPanel();
290 | 0 | final JTextArea ruleXMLArea = new JTextArea(30, 50);
291 | 0 | ruleXMLPanel.add(ruleXMLArea);
292 | 0 | JButton go = new JButton("Create rule XML");
293 | 0 | go.addActionListener(new ActionListener() {
294 | 0 | public void actionPerformed(ActionEvent e) {
295 | 0 | StringBuffer sb = new StringBuffer();
296 | 0 | sb.append("<rule name=\"" + rulenameField.getText() + "\"" + PMD.EOL);
297 | 0 | sb.append(" message=\"" + rulemsgField.getText() + "\"" + PMD.EOL);
298 | 0 | sb.append(" class=\"" + (xpathQueryArea.getText().length() == 0 ? "" : "net.sourceforge.pmd.rules.XPathRule") + "\">" + PMD.EOL);
299 | 0 | sb.append(" <description>" + PMD.EOL);
300 | 0 | sb.append(" " + ruledescField.getText() + PMD.EOL);
301 | 0 | sb.append(" </description>" + PMD.EOL);
302 | 0 | if (xpathQueryArea.getText().length() != 0) {
303 | 0 | sb.append(" <properties>" + PMD.EOL);
304 | 0 | sb.append(" <property name=\"xpath\">" + PMD.EOL);
305 | 0 | sb.append(" <value>" + PMD.EOL);
306 | 0 | sb.append("<![CDATA[" + PMD.EOL);
307 | 0 | sb.append(xpathQueryArea.getText() + PMD.EOL);
308 | 0 | sb.append("]]>" + PMD.EOL);
309 | 0 | sb.append(" </value>" + PMD.EOL);
310 | 0 | sb.append(" </property>" + PMD.EOL);
311 | 0 | sb.append(" </properties>" + PMD.EOL);
312 |  | }
313 | 0 | sb.append(" <priority>3</priority>" + PMD.EOL);
314 | 0 | sb.append(" <example>" + PMD.EOL);
315 | 0 | sb.append("<![CDATA[" + PMD.EOL);
316 | 0 | sb.append(codeEditorPane.getText());
317 | 0 | sb.append("]]>" + PMD.EOL);
318 | 0 | sb.append(" </example>" + PMD.EOL);
319 | 0 | sb.append("</rule>" + PMD.EOL);
320 |  |
321 | 0 | ruleXMLArea.setText(sb.toString());
322 |  | }
323 |  | });
324 |  |
325 | 0 | JPanel fieldsPanel = new JPanel();
326 | 0 | fieldsPanel.setLayout(new BorderLayout());
327 | 0 | fieldsPanel.add(rulenamePanel, BorderLayout.NORTH);
328 | 0 | fieldsPanel.add(rulemsgPanel, BorderLayout.CENTER);
329 | 0 | fieldsPanel.add(ruledescPanel, BorderLayout.SOUTH);
330 |  |
331 | 0 | JPanel fieldBtnPanel = new JPanel();
332 | 0 | fieldBtnPanel.setLayout(new BorderLayout());
333 | 0 | fieldBtnPanel.add(fieldsPanel, BorderLayout.NORTH);
334 | 0 | fieldBtnPanel.add(go, BorderLayout.SOUTH);
335 |  |
336 | 0 | JPanel outer = new JPanel(new BorderLayout());
337 | 0 | outer.add(fieldBtnPanel, BorderLayout.NORTH);
338 | 0 | outer.add(ruleXMLPanel, BorderLayout.SOUTH);
339 |  |
340 | 0 | JDialog d = new JDialog(frame);
341 | 0 | d.setSize(200, 300);
342 | 0 | d.getContentPane().add(outer);
343 | 0 | int screenHeight = Toolkit.getDefaultToolkit().getScreenSize().height;
344 | 0 | int screenWidth = Toolkit.getDefaultToolkit().getScreenSize().width;
345 | 0 | d.setLocation((screenWidth / 2) - frame.getWidth() / 2, (screenHeight / 2) - frame.getHeight() / 2);
346 | 0 | d.setVisible(true);
347 | 0 | d.pack();
348 | 0 | d.show();
349 |  | }
350 |  |
351 | 0 | private JComponent createASTPanel() {
352 | 0 | astArea.setRows(10);
353 | 0 | astArea.setColumns(20);
354 | 0 | JScrollPane astScrollPane = new JScrollPane(astArea);
355 | 0 | return astScrollPane;
356 |  | }
357 |  |
358 | 0 | private JComponent createXPathResultPanel() {
359 | 0 | xpathResults.addElement("No results yet");
360 | 0 | xpathResultList.setBorder(BorderFactory.createLineBorder(Color.black));
361 | 0 | xpathResultList.setFixedCellWidth(300);
362 | 0 | JScrollPane scrollPane = new JScrollPane();
363 | 0 | scrollPane.getViewport().setView(xpathResultList);
364 | 0 | return scrollPane;
365 |  | }
366 |  |
367 | 0 | private JPanel createXPathQueryPanel() {
368 | 0 | JPanel p = new JPanel();
369 | 0 | p.setLayout(new BorderLayout());
370 | 0 | xpathQueryArea.setBorder(BorderFactory.createLineBorder(Color.black));
371 | 0 | JScrollPane scrollPane = new JScrollPane(xpathQueryArea);
372 | 0 | scrollPane.setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_AS_NEEDED);
373 | 0 | scrollPane.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED);
374 | 0 | final JButton b = createGoButton();
375 |  |
376 | 0 | p.add(new JLabel("XPath Query (if any)"), BorderLayout.NORTH);
377 | 0 | p.add(scrollPane, BorderLayout.CENTER);
378 | 0 | p.add(b, BorderLayout.SOUTH);
379 |  |
380 | 0 | return p;
381 |  | }
382 |  |
383 | 0 | private JButton createGoButton() {
384 | 0 | JButton b = new JButton("Go");
385 | 0 | b.setMnemonic('g');
386 | 0 | b.addActionListener(new ShowListener());
387 | 0 | b.addActionListener(codeEditorPane);
388 | 0 | b.addActionListener(new XPathListener());
389 | 0 | b.addActionListener(new DFAListener());
390 | 0 | return b;
391 |  | }
392 |  |
393 | 0 | public static void main(String[] args) {
394 | 0 | new Designer();
395 |  | }
396 |  |
397 | 0 | private final void copyXmlToClipboard() {
398 | 0 | if (codeEditorPane.getText() != null && codeEditorPane.getText().trim().length() > 0) {
399 | 0 | String xml = "";
400 | 0 | SimpleNode cu = getCompilationUnit();
401 | 0 | if (cu != null) {
402 | 0 | try {
403 | 0 | xml = getXmlString(cu);
404 |  | } catch (IOException e) {
405 | 0 | e.printStackTrace();
406 | 0 | xml = "Error trying to construct XML representation";
407 |  | }
408 |  | }
409 | 0 | Toolkit.getDefaultToolkit().getSystemClipboard().setContents(new StringSelection(xml), this);
410 |  | }
411 |  | }
412 |  |
413 |  | /**
414 |  | * Returns an unformatted xml string (without the declaration)
415 |  | *
416 |  | * @param node
417 |  | * @return
418 |  | * @throws java.io.IOException
419 |  | */
420 | 0 | private String getXmlString(SimpleNode node) throws IOException {
421 | 0 | StringWriter writer = new StringWriter();
422 | 0 | XMLSerializer xmlSerializer = new XMLSerializer(writer, new OutputFormat("XML", "UTF-8", true));
423 | 0 | xmlSerializer.asDOMSerializer();
424 | 0 | xmlSerializer.serialize(node.asXml());
425 | 0 | return writer.toString();
426 |  | }
427 |  |
428 | 0 | public void lostOwnership(Clipboard clipboard, Transferable contents) {
429 |  | }
430 |  | }
431 |  |