/** * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ package net.sourceforge.pmd.util; import net.sourceforge.pmd.TargetJDK1_4; import net.sourceforge.pmd.ast.ASTCompilationUnit; import net.sourceforge.pmd.ast.JavaParser; import net.sourceforge.pmd.ast.ParseException; import net.sourceforge.pmd.ast.SimpleNode; import net.sourceforge.pmd.jaxen.DocumentNavigator; import org.jaxen.BaseXPath; import org.jaxen.JaxenException; import org.jaxen.XPath; import javax.swing.*; import java.awt.*; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.io.BufferedReader; import java.io.File; import java.io.FileReader; import java.io.FileWriter; import java.io.IOException; import java.io.PrintStream; import java.io.StringReader; import java.util.Iterator; public class ASTViewer { private static class JSmartPanel extends JPanel { private GridBagConstraints constraints = new GridBagConstraints(); public JSmartPanel() { super(new GridBagLayout()); } public void add(Component comp, int gridx, int gridy, int gridwidth, int gridheight, double weightx, double weighty, int anchor, int fill, Insets insets) { constraints.gridx = gridx; constraints.gridy = gridy; constraints.gridwidth = gridwidth; constraints.gridheight = gridheight; constraints.weightx = weightx; constraints.weighty = weighty; constraints.anchor = anchor; constraints.fill = fill; constraints.insets = insets; add(comp, constraints); } } private static class MyPrintStream extends PrintStream { public MyPrintStream() { super(System.out); } private StringBuffer buf = new StringBuffer(); public void println(String s) { super.println(s); buf.append(s); buf.append(System.getProperty("line.separator")); } public String getString() { return buf.toString(); } } private class ShowListener implements ActionListener { public void actionPerformed(ActionEvent ae) { StringReader sr = new StringReader(codeEditorPane.getText()); JavaParser parser = (new TargetJDK1_4()).createParser(sr); MyPrintStream ps = new MyPrintStream(); System.setOut(ps); try { ASTCompilationUnit c = parser.CompilationUnit(); c.dump(""); astArea.setText(ps.getString()); } catch (ParseException pe) { astArea.setText(pe.fillInStackTrace().getMessage()); } } } private class SaveListener implements ActionListener { public void actionPerformed(ActionEvent ae) { try { File f = new File(SETTINGS_FILE_NAME); FileWriter fw = new FileWriter(f); fw.write(codeEditorPane.getText()); fw.close(); } catch (IOException ioe) { } } } private class XPathListener implements ActionListener { public void actionPerformed(ActionEvent ae) { if (xpathQueryArea.getText().length() == 0) { xpathResultArea.setText("XPath query field is empty"); codeEditorPane.requestFocus(); return; } StringReader sr = new StringReader(codeEditorPane.getText()); JavaParser parser = (new TargetJDK1_4()).createParser(sr); try { XPath xpath = new BaseXPath(xpathQueryArea.getText(), new DocumentNavigator()); ASTCompilationUnit c = parser.CompilationUnit(); StringBuffer sb = new StringBuffer(); for (Iterator iter = xpath.selectNodes(c).iterator(); iter.hasNext();) { SimpleNode node = (SimpleNode) iter.next(); String name = node.getClass().getName().substring(node.getClass().getName().lastIndexOf('.')+1); String line = " at line " + String.valueOf(node.getBeginLine()); sb.append(name).append(line).append(System.getProperty("line.separator")); } xpathResultArea.setText(sb.toString()); if (sb.length() == 0) { xpathResultArea.setText("No results returned " + System.currentTimeMillis()); } } catch (ParseException pe) { xpathResultArea.setText(pe.fillInStackTrace().getMessage()); } catch (JaxenException je) { xpathResultArea.setText(je.fillInStackTrace().getMessage()); } xpathQueryArea.requestFocus(); } } private static final String SETTINGS_FILE_NAME = System.getProperty("user.home") + System.getProperty("file.separator") + ".pmd_astviewer"; private JTextPane codeEditorPane = new JTextPane(); private JTextArea astArea = new JTextArea(); private JTextArea xpathResultArea = new JTextArea(); private JTextArea xpathQueryArea = new JTextArea(8, 40); private JFrame frame = new JFrame("AST Viewer"); public ASTViewer() { JSmartPanel codePanel = new JSmartPanel(); JScrollPane codeScrollPane = new JScrollPane(codeEditorPane); codePanel.add(codeScrollPane, 0, 0, 1, 1, 1.0, 1.0, GridBagConstraints.NORTH, GridBagConstraints.BOTH, new Insets(0, 0, 0, 0)); JSmartPanel astPanel = new JSmartPanel(); astArea.setRows(20); astArea.setColumns(20); JScrollPane astScrollPane = new JScrollPane(astArea); astPanel.add(astScrollPane, 0, 0, 1, 1, 1.0, 1.0, GridBagConstraints.NORTH, GridBagConstraints.BOTH, new Insets(0, 0, 0, 0)); JSmartPanel xpathResultPanel = new JSmartPanel(); xpathResultArea.setRows(20); xpathResultArea.setColumns(20); JScrollPane xpathResultScrollPane = new JScrollPane(xpathResultArea); xpathResultPanel.add(xpathResultScrollPane, 0, 0, 1, 1, 1.0, 1.0, GridBagConstraints.NORTH, GridBagConstraints.BOTH, new Insets(0, 0, 0, 0)); JButton goButton = new JButton("Go"); goButton.setMnemonic('g'); goButton.addActionListener(new ShowListener()); goButton.addActionListener(new SaveListener()); goButton.addActionListener(new XPathListener()); JPanel controlPanel = new JPanel(); controlPanel.add(new JLabel("XPath Query (if any) ->")); xpathQueryArea.setBorder(BorderFactory.createLineBorder(Color.black)); controlPanel.add(new JScrollPane(xpathQueryArea)); controlPanel.add(goButton); JSplitPane resultsSplitPane = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, astPanel, xpathResultPanel); JSplitPane upperSplitPane = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, codePanel, resultsSplitPane); JSplitPane containerSplitPane = new JSplitPane(JSplitPane.VERTICAL_SPLIT, upperSplitPane, controlPanel); frame.getContentPane().add(containerSplitPane); frame.setSize(1000, 500); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); int screenHeight = Toolkit.getDefaultToolkit().getScreenSize().height; int screenWidth = Toolkit.getDefaultToolkit().getScreenSize().width; frame.setLocation((screenWidth/2) - frame.getWidth()/2, (screenHeight/2) - frame.getHeight()/2); frame.setVisible(true); frame.show(); containerSplitPane.setDividerLocation(containerSplitPane.getMaximumDividerLocation() - (containerSplitPane.getMaximumDividerLocation()/4)); upperSplitPane.setDividerLocation(upperSplitPane.getMaximumDividerLocation() / 3); codeEditorPane.setText(loadText()); codeEditorPane.setSize(upperSplitPane.getMaximumDividerLocation() / 3, containerSplitPane.getMaximumDividerLocation() - (containerSplitPane.getMaximumDividerLocation()/4)); } private String loadText() { try { BufferedReader br = new BufferedReader(new FileReader(new File(SETTINGS_FILE_NAME))); StringBuffer text = new StringBuffer(); String hold = null; while ( (hold = br.readLine()) != null) { text.append(hold); text.append(System.getProperty("line.separator")); } return text.toString(); } catch (IOException e) { e.printStackTrace(); return ""; } } public static void main(String[] args) { new ASTViewer(); } }