1 |
| |
2 |
| |
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.TargetJDK1_6; |
14 |
| import net.sourceforge.pmd.ast.Node; |
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 |
| import net.sourceforge.pmd.util.NumericConstants; |
22 |
| import net.sourceforge.pmd.util.StringUtil; |
23 |
| import org.jaxen.BaseXPath; |
24 |
| import org.jaxen.JaxenException; |
25 |
| import org.jaxen.XPath; |
26 |
| |
27 |
| import javax.swing.*; |
28 |
| import javax.swing.event.*; |
29 |
| import javax.swing.text.JTextComponent; |
30 |
| import javax.swing.tree.DefaultTreeCellRenderer; |
31 |
| import javax.swing.tree.DefaultTreeModel; |
32 |
| import javax.swing.tree.TreeNode; |
33 |
| import javax.swing.tree.TreePath; |
34 |
| import javax.swing.undo.*; |
35 |
| import java.awt.BorderLayout; |
36 |
| import java.awt.Color; |
37 |
| import java.awt.Component; |
38 |
| import java.awt.Dimension; |
39 |
| import java.awt.Font; |
40 |
| import java.awt.FontMetrics; |
41 |
| import java.awt.Graphics; |
42 |
| import java.awt.Toolkit; |
43 |
| import java.awt.datatransfer.Clipboard; |
44 |
| import java.awt.datatransfer.ClipboardOwner; |
45 |
| import java.awt.datatransfer.StringSelection; |
46 |
| import java.awt.datatransfer.Transferable; |
47 |
| import java.awt.event.ActionEvent; |
48 |
| import java.awt.event.ActionListener; |
49 |
| import java.awt.event.ComponentEvent; |
50 |
| import java.awt.event.KeyEvent; |
51 |
| import java.io.IOException; |
52 |
| import java.io.StringReader; |
53 |
| import java.io.StringWriter; |
54 |
| import java.lang.reflect.InvocationTargetException; |
55 |
| import java.lang.reflect.Method; |
56 |
| import java.util.Enumeration; |
57 |
| import java.util.Iterator; |
58 |
| import java.util.List; |
59 |
| import java.util.Vector; |
60 |
| |
61 |
| public class Designer implements ClipboardOwner { |
62 |
| |
63 |
| private static final char LABEL_IMAGE_SEPARATOR = ':'; |
64 |
| private static final Color IMAGE_TEXT_COLOR = Color.BLUE; |
65 |
| |
66 |
| private interface Parser { public SimpleNode parse(StringReader sr); }; |
67 |
| |
68 |
| private static final Parser jdkParser1_3 = new Parser() { |
69 |
0
| public SimpleNode parse(StringReader sr) { return new TargetJDK1_3().createParser(sr).CompilationUnit(); };
|
70 |
| }; |
71 |
| |
72 |
| private static final Parser jdkParser1_4 = new Parser() { |
73 |
0
| public SimpleNode parse(StringReader sr) { return new TargetJDK1_4().createParser(sr).CompilationUnit(); };
|
74 |
| }; |
75 |
| |
76 |
| private static final Parser jdkParser1_5 = new Parser() { |
77 |
0
| public SimpleNode parse(StringReader sr) { return new TargetJDK1_5().createParser(sr).CompilationUnit(); };
|
78 |
| }; |
79 |
| |
80 |
| private static final Parser jdkParser1_6 = new Parser() { |
81 |
0
| public SimpleNode parse(StringReader sr) { return new TargetJDK1_6().createParser(sr).CompilationUnit(); };
|
82 |
| }; |
83 |
| |
84 |
| private static final Parser jspParser = new Parser() { |
85 |
0
| public SimpleNode parse(StringReader sr) { return new JspParser(new JspCharStream(sr)).CompilationUnit(); };
|
86 |
| }; |
87 |
| |
88 |
| private static final Object[][] sourceTypeSets = new Object[][] { |
89 |
| { "JDK 1.3", SourceType.JAVA_13, jdkParser1_3 }, |
90 |
| { "JDK 1.4", SourceType.JAVA_14, jdkParser1_4 }, |
91 |
| { "JDK 1.5", SourceType.JAVA_15, jdkParser1_5 }, |
92 |
| { "JDK 1.6", SourceType.JAVA_16, jdkParser1_6 }, |
93 |
| { "JSP", SourceType.JSP, jspParser } |
94 |
| }; |
95 |
| |
96 |
| private static final int defaultSourceTypeSelectionIndex = 1; |
97 |
| |
98 |
| |
99 |
0
| private SimpleNode getCompilationUnit() {
|
100 |
| |
101 |
0
| Parser parser = (Parser)sourceTypeSets[selectedSourceTypeIndex()][2];
|
102 |
0
| return parser.parse(new StringReader(codeEditorPane.getText()));
|
103 |
| } |
104 |
| |
105 |
0
| private SourceType getSourceType() {
|
106 |
| |
107 |
0
| return (SourceType)sourceTypeSets[selectedSourceTypeIndex()][1];
|
108 |
| } |
109 |
| |
110 |
0
| private int selectedSourceTypeIndex() {
|
111 |
0
| for (int i=0; i<sourceTypeMenuItems.length; i++) {
|
112 |
0
| if (sourceTypeMenuItems[i].isSelected()) return i;
|
113 |
| } |
114 |
0
| throw new RuntimeException("Initial default source type not specified");
|
115 |
| } |
116 |
| |
117 |
| private class ExceptionNode implements TreeNode { |
118 |
| |
119 |
| private Object item; |
120 |
| private ExceptionNode[] kids; |
121 |
| |
122 |
0
| public ExceptionNode(Object theItem) {
|
123 |
0
| item = theItem;
|
124 |
| |
125 |
0
| if (item instanceof ParseException) createKids();
|
126 |
| } |
127 |
| |
128 |
| |
129 |
0
| private void createKids() {
|
130 |
| |
131 |
0
| String message = ((ParseException)item).getMessage();
|
132 |
0
| String[] lines = StringUtil.substringsOf(message, PMD.EOL);
|
133 |
| |
134 |
0
| kids = new ExceptionNode[lines.length];
|
135 |
0
| for (int i=0; i<lines.length; i++) {
|
136 |
0
| kids[i] = new ExceptionNode(lines[i]);
|
137 |
| } |
138 |
| } |
139 |
| |
140 |
0
| public int getChildCount() { return kids == null ? 0 : kids.length; }
|
141 |
0
| public boolean getAllowsChildren() {return false; }
|
142 |
0
| public boolean isLeaf() { return kids == null; }
|
143 |
0
| public TreeNode getParent() { return null; }
|
144 |
0
| public TreeNode getChildAt(int childIndex) { return kids[childIndex]; }
|
145 |
0
| public String label() { return item.toString(); }
|
146 |
| |
147 |
0
| public Enumeration children() {
|
148 |
0
| Enumeration e = new Enumeration() {
|
149 |
| int i = 0; |
150 |
0
| public boolean hasMoreElements() {
|
151 |
0
| return kids != null && i < kids.length;
|
152 |
| } |
153 |
| |
154 |
0
| public Object nextElement() { return kids[i++]; }
|
155 |
| }; |
156 |
0
| return e;
|
157 |
| } |
158 |
| |
159 |
0
| public int getIndex(TreeNode node) {
|
160 |
0
| for (int i=0; i<kids.length; i++) {
|
161 |
0
| if (kids[i] == node) return i;
|
162 |
| } |
163 |
0
| return -1;
|
164 |
| } |
165 |
| } |
166 |
| |
167 |
| |
168 |
| |
169 |
| private class ASTTreeNode implements TreeNode { |
170 |
| |
171 |
| private Node node; |
172 |
| private ASTTreeNode parent; |
173 |
| private ASTTreeNode[] kids; |
174 |
| |
175 |
0
| public ASTTreeNode(Node theNode) {
|
176 |
0
| node = theNode;
|
177 |
| |
178 |
0
| Node prnt = node.jjtGetParent();
|
179 |
0
| if (prnt != null) parent = new ASTTreeNode(prnt);
|
180 |
| } |
181 |
| |
182 |
0
| public int getChildCount() { return node.jjtGetNumChildren(); }
|
183 |
0
| public boolean getAllowsChildren() { return false; }
|
184 |
0
| public boolean isLeaf() { return node.jjtGetNumChildren() == 0; }
|
185 |
0
| public TreeNode getParent() { return parent; }
|
186 |
| |
187 |
0
| public Enumeration children() {
|
188 |
| |
189 |
0
| if (getChildCount() > 0) getChildAt(0);
|
190 |
| |
191 |
0
| Enumeration e = new Enumeration() {
|
192 |
| int i = 0; |
193 |
0
| public boolean hasMoreElements() {
|
194 |
0
| return kids != null && i < kids.length;
|
195 |
| } |
196 |
0
| public Object nextElement() { return kids[i++]; }
|
197 |
| }; |
198 |
0
| return e;
|
199 |
| } |
200 |
| |
201 |
0
| public TreeNode getChildAt(int childIndex) {
|
202 |
| |
203 |
0
| if (kids == null) {
|
204 |
0
| kids = new ASTTreeNode[node.jjtGetNumChildren()];
|
205 |
0
| for (int i=0; i<kids.length; i++) {
|
206 |
0
| kids[i] = new ASTTreeNode(node.jjtGetChild(i));
|
207 |
| } |
208 |
| } |
209 |
0
| return kids[childIndex];
|
210 |
| } |
211 |
| |
212 |
0
| public int getIndex(TreeNode node) {
|
213 |
| |
214 |
0
| for (int i=0; i<kids.length; i++) {
|
215 |
0
| if (kids[i] == node) return i;
|
216 |
| } |
217 |
0
| return -1;
|
218 |
| } |
219 |
| |
220 |
0
| public String label() {
|
221 |
0
| if (node instanceof SimpleNode) {
|
222 |
0
| SimpleNode sn = (SimpleNode)node;
|
223 |
0
| if (sn.getLabel() != null) {
|
224 |
0
| return node.toString() + LABEL_IMAGE_SEPARATOR + sn.getLabel();
|
225 |
| } |
226 |
0
| if (sn.getImage() == null) {
|
227 |
0
| return node.toString();
|
228 |
| } |
229 |
0
| return node.toString() + LABEL_IMAGE_SEPARATOR + sn.getImage();
|
230 |
| } |
231 |
0
| return node.toString();
|
232 |
| } |
233 |
| } |
234 |
| |
235 |
| |
236 |
| |
237 |
| |
238 |
| |
239 |
| private class ASTCellRenderer extends DefaultTreeCellRenderer { |
240 |
| |
241 |
| private ASTTreeNode node; |
242 |
| |
243 |
0
| public Icon getIcon() { return null; };
|
244 |
| |
245 |
0
| public Component getTreeCellRendererComponent(JTree tree, Object value, boolean sel,boolean expanded,boolean leaf, int row, boolean hasFocus) {
|
246 |
| |
247 |
0
| if (value instanceof ASTTreeNode) {
|
248 |
0
| node = (ASTTreeNode)value;
|
249 |
| } |
250 |
0
| return super.getTreeCellRendererComponent(tree, value, sel, expanded, leaf, row, hasFocus);
|
251 |
| } |
252 |
| |
253 |
| |
254 |
0
| public void paint(Graphics g) {
|
255 |
| |
256 |
0
| super.paint(g);
|
257 |
| |
258 |
0
| if (node == null) return;
|
259 |
| |
260 |
0
| String text = node.label();
|
261 |
0
| int separatorPos = text.indexOf(LABEL_IMAGE_SEPARATOR);
|
262 |
0
| if (separatorPos < 0) return;
|
263 |
| |
264 |
0
| String label = text.substring(0, separatorPos+1);
|
265 |
0
| String image = text.substring(separatorPos+1);
|
266 |
| |
267 |
0
| FontMetrics fm = g.getFontMetrics();
|
268 |
0
| int width = SwingUtilities.computeStringWidth(fm, label);
|
269 |
| |
270 |
0
| g.setColor(IMAGE_TEXT_COLOR);
|
271 |
0
| g.drawString(image, width, fm.getMaxAscent());
|
272 |
| } |
273 |
| } |
274 |
| |
275 |
| |
276 |
| |
277 |
| |
278 |
| private class ASTTreeWidget extends JTree { |
279 |
| |
280 |
0
| public ASTTreeWidget(Vector items) {
|
281 |
0
| super(items);
|
282 |
| } |
283 |
| |
284 |
0
| public String convertValueToText(Object value, boolean selected, boolean expanded, boolean leaf, int row, boolean hasFocus) {
|
285 |
0
| if (value == null) return "";
|
286 |
0
| if (value instanceof ASTTreeNode) {
|
287 |
0
| return ((ASTTreeNode)value).label();
|
288 |
| } |
289 |
0
| if (value instanceof ExceptionNode) {
|
290 |
0
| return ((ExceptionNode)value).label();
|
291 |
| } |
292 |
0
| return value.toString();
|
293 |
| } |
294 |
| |
295 |
0
| public void expandAll(boolean expand) {
|
296 |
0
| TreeNode root = (TreeNode)getModel().getRoot();
|
297 |
0
| expandAll(new TreePath(root), expand);
|
298 |
| } |
299 |
| |
300 |
0
| private void expandAll(TreePath parent, boolean expand) {
|
301 |
| |
302 |
0
| TreeNode node = (TreeNode)parent.getLastPathComponent();
|
303 |
0
| if (node.getChildCount() >= 0) {
|
304 |
0
| for (Enumeration e=node.children(); e.hasMoreElements(); ) {
|
305 |
0
| TreeNode n = (TreeNode)e.nextElement();
|
306 |
0
| TreePath path = parent.pathByAddingChild(n);
|
307 |
0
| expandAll(path, expand);
|
308 |
| } |
309 |
| } |
310 |
| |
311 |
0
| if (expand) {
|
312 |
0
| expandPath(parent);
|
313 |
| } else { |
314 |
0
| collapsePath(parent);
|
315 |
| } |
316 |
| } |
317 |
| } |
318 |
| |
319 |
0
| private void loadTreeData(TreeNode rootNode) {
|
320 |
0
| astWidget.setModel(new DefaultTreeModel(rootNode));
|
321 |
0
| astWidget.expandAll(true);
|
322 |
| } |
323 |
| |
324 |
| private class ShowListener implements ActionListener { |
325 |
0
| public void actionPerformed(ActionEvent ae) {
|
326 |
0
| MyPrintStream ps = new MyPrintStream();
|
327 |
0
| System.setOut(ps);
|
328 |
0
| TreeNode tn;
|
329 |
0
| try {
|
330 |
0
| SimpleNode lastCompilationUnit = getCompilationUnit();
|
331 |
0
| tn = new ASTTreeNode(lastCompilationUnit);
|
332 |
| } catch (ParseException pe) { |
333 |
0
| tn = new ExceptionNode(pe);
|
334 |
| } |
335 |
| |
336 |
0
| loadTreeData(tn);
|
337 |
| } |
338 |
| } |
339 |
| |
340 |
| private class DFAListener implements ActionListener { |
341 |
0
| public void actionPerformed(ActionEvent ae) {
|
342 |
| |
343 |
0
| DFAGraphRule dfaGraphRule = new DFAGraphRule();
|
344 |
0
| RuleSet rs = new RuleSet();
|
345 |
0
| SourceType sourceType = getSourceType();
|
346 |
0
| if (!sourceType.equals(SourceType.JSP)){
|
347 |
0
| rs.addRule(dfaGraphRule);
|
348 |
| } |
349 |
0
| RuleContext ctx = new RuleContext();
|
350 |
0
| ctx.setSourceCodeFilename("[no filename]");
|
351 |
0
| StringReader reader = new StringReader(codeEditorPane.getText());
|
352 |
0
| PMD pmd = new PMD();
|
353 |
0
| pmd.setJavaVersion(sourceType);
|
354 |
| |
355 |
0
| try {
|
356 |
0
| pmd.processFile(reader, rs, ctx);
|
357 |
| |
358 |
| |
359 |
| } catch (Exception e) { |
360 |
0
| e.printStackTrace();
|
361 |
| } |
362 |
| |
363 |
0
| List methods = dfaGraphRule.getMethods();
|
364 |
0
| if (methods != null && !methods.isEmpty()) {
|
365 |
0
| dfaPanel.resetTo(methods, codeEditorPane);
|
366 |
0
| dfaPanel.repaint();
|
367 |
| } |
368 |
| } |
369 |
| } |
370 |
| |
371 |
| private class XPathListener implements ActionListener { |
372 |
0
| public void actionPerformed(ActionEvent ae) {
|
373 |
0
| xpathResults.clear();
|
374 |
0
| if (xpathQueryArea.getText().length() == 0) {
|
375 |
0
| xpathResults.addElement("XPath query field is empty");
|
376 |
0
| xpathResultList.repaint();
|
377 |
0
| codeEditorPane.requestFocus();
|
378 |
0
| return;
|
379 |
| } |
380 |
0
| SimpleNode c = getCompilationUnit();
|
381 |
0
| try {
|
382 |
0
| XPath xpath = new BaseXPath(xpathQueryArea.getText(), new DocumentNavigator());
|
383 |
0
| for (Iterator iter = xpath.selectNodes(c).iterator(); iter.hasNext();) {
|
384 |
0
| StringBuffer sb = new StringBuffer();
|
385 |
0
| Object obj = iter.next();
|
386 |
0
| if (obj instanceof String) {
|
387 |
0
| System.out.println("Result was a string: " + ((String) obj));
|
388 |
0
| } else if (!(obj instanceof Boolean)) {
|
389 |
| |
390 |
0
| SimpleNode node = (SimpleNode) obj;
|
391 |
0
| String name = node.getClass().getName().substring(node.getClass().getName().lastIndexOf('.') + 1);
|
392 |
0
| String line = " at line " + node.getBeginLine();
|
393 |
0
| sb.append(name).append(line).append(PMD.EOL);
|
394 |
0
| xpathResults.addElement(sb.toString().trim());
|
395 |
| } |
396 |
| } |
397 |
0
| if (xpathResults.isEmpty()) {
|
398 |
0
| xpathResults.addElement("No matching nodes " + System.currentTimeMillis());
|
399 |
| } |
400 |
| } catch (ParseException pe) { |
401 |
0
| xpathResults.addElement(pe.fillInStackTrace().getMessage());
|
402 |
| } catch (JaxenException je) { |
403 |
0
| xpathResults.addElement(je.fillInStackTrace().getMessage());
|
404 |
| } |
405 |
0
| xpathResultList.repaint();
|
406 |
0
| xpathQueryArea.requestFocus();
|
407 |
| } |
408 |
| } |
409 |
| |
410 |
| private final CodeEditorTextPane codeEditorPane = new CodeEditorTextPane(); |
411 |
| private final ASTTreeWidget astWidget = new ASTTreeWidget(new Vector()); |
412 |
| private DefaultListModel xpathResults = new DefaultListModel(); |
413 |
| private final JList xpathResultList = new JList(xpathResults); |
414 |
| private final JTextArea xpathQueryArea = new JTextArea(15, 30); |
415 |
| private final JFrame frame = new JFrame("PMD Rule Designer"); |
416 |
| private final DFAPanel dfaPanel = new DFAPanel(); |
417 |
| private final JRadioButtonMenuItem[] sourceTypeMenuItems = new JRadioButtonMenuItem[sourceTypeSets.length]; |
418 |
| |
419 |
0
| public Designer() {
|
420 |
0
| MatchesFunction.registerSelfInSimpleContext();
|
421 |
| |
422 |
0
| xpathQueryArea.setFont(new Font("Verdana", Font.PLAIN, 16));
|
423 |
0
| makeTextComponentUndoable(codeEditorPane);
|
424 |
0
| JSplitPane controlSplitPane = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, new JScrollPane(codeEditorPane), createXPathQueryPanel());
|
425 |
0
| JSplitPane resultsSplitPane = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, createASTPanel(), createXPathResultPanel());
|
426 |
| |
427 |
0
| JTabbedPane tabbed = new JTabbedPane();
|
428 |
0
| tabbed.addTab("Abstract Syntax Tree / XPath", resultsSplitPane);
|
429 |
0
| tabbed.addTab("Data Flow Analysis", dfaPanel);
|
430 |
0
| try {
|
431 |
| |
432 |
0
| Method setMnemonicAt = JTabbedPane.class.getMethod("setMnemonicAt", new Class[]{Integer.TYPE, Integer.TYPE});
|
433 |
0
| if (setMnemonicAt != null) {
|
434 |
| |
435 |
| |
436 |
| |
437 |
0
| setMnemonicAt.invoke(tabbed, new Object[]{NumericConstants.ZERO, new Integer(KeyEvent.VK_A)});
|
438 |
0
| setMnemonicAt.invoke(tabbed, new Object[]{NumericConstants.ONE, new Integer(KeyEvent.VK_D)});
|
439 |
| } |
440 |
| } catch (NoSuchMethodException nsme) { |
441 |
| } catch (IllegalAccessException e) { |
442 |
0
| e.printStackTrace();
|
443 |
0
| throw new InternalError("Runtime reports to be >= JDK 1.4 yet String.split(java.lang.String) is broken.");
|
444 |
| } catch (IllegalArgumentException e) { |
445 |
0
| e.printStackTrace();
|
446 |
0
| throw new InternalError("Runtime reports to be >= JDK 1.4 yet String.split(java.lang.String) is broken.");
|
447 |
| } catch (InvocationTargetException e) { |
448 |
0
| e.printStackTrace();
|
449 |
0
| throw new InternalError("Runtime reports to be >= JDK 1.4 yet String.split(java.lang.String) is broken.");
|
450 |
| } |
451 |
| |
452 |
0
| JSplitPane containerSplitPane = new JSplitPane(JSplitPane.VERTICAL_SPLIT, controlSplitPane, tabbed);
|
453 |
0
| containerSplitPane.setContinuousLayout(true);
|
454 |
| |
455 |
0
| JMenuBar menuBar = createMenuBar();
|
456 |
0
| frame.setJMenuBar(menuBar);
|
457 |
0
| frame.getContentPane().add(containerSplitPane);
|
458 |
0
| frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
|
459 |
| |
460 |
0
| Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
|
461 |
0
| int screenHeight = screenSize.height;
|
462 |
0
| int screenWidth = screenSize.width;
|
463 |
| |
464 |
0
| frame.pack();
|
465 |
0
| frame.setSize((screenWidth*3/4),(screenHeight*3/4));
|
466 |
0
| frame.setLocation((screenWidth -frame.getWidth()) / 2, (screenHeight - frame.getHeight()) / 2);
|
467 |
0
| frame.setVisible(true);
|
468 |
0
| resultsSplitPane.setDividerLocation(resultsSplitPane.getMaximumDividerLocation() - (resultsSplitPane.getMaximumDividerLocation() / 2));
|
469 |
0
| containerSplitPane.setDividerLocation(containerSplitPane.getMaximumDividerLocation() / 2);
|
470 |
| } |
471 |
| |
472 |
0
| private JMenuBar createMenuBar() {
|
473 |
0
| JMenuBar menuBar = new JMenuBar();
|
474 |
0
| JMenu menu = new JMenu("JDK");
|
475 |
0
| ButtonGroup group = new ButtonGroup();
|
476 |
| |
477 |
0
| for (int i=0; i<sourceTypeSets.length; i++) {
|
478 |
0
| JRadioButtonMenuItem button = new JRadioButtonMenuItem(sourceTypeSets[i][0].toString());
|
479 |
0
| sourceTypeMenuItems[i] = button;
|
480 |
0
| group.add(button);
|
481 |
0
| menu.add(button);
|
482 |
| } |
483 |
0
| sourceTypeMenuItems[defaultSourceTypeSelectionIndex].setSelected(true);
|
484 |
0
| menuBar.add(menu);
|
485 |
| |
486 |
0
| JMenu actionsMenu = new JMenu("Actions");
|
487 |
0
| JMenuItem copyXMLItem = new JMenuItem("Copy xml to clipboard");
|
488 |
0
| copyXMLItem.addActionListener(new ActionListener() {
|
489 |
0
| public void actionPerformed(ActionEvent e) {
|
490 |
0
| copyXmlToClipboard();
|
491 |
| } |
492 |
| }); |
493 |
0
| actionsMenu.add(copyXMLItem);
|
494 |
0
| JMenuItem createRuleXMLItem = new JMenuItem("Create rule XML");
|
495 |
0
| createRuleXMLItem.addActionListener(new ActionListener() {
|
496 |
0
| public void actionPerformed(ActionEvent e) {
|
497 |
0
| createRuleXML();
|
498 |
| } |
499 |
| }); |
500 |
0
| actionsMenu.add(createRuleXMLItem);
|
501 |
0
| menuBar.add(actionsMenu);
|
502 |
| |
503 |
0
| return menuBar;
|
504 |
| } |
505 |
| |
506 |
0
| private void createRuleXML() {
|
507 |
0
| CreateXMLRulePanel rulePanel = new CreateXMLRulePanel(xpathQueryArea, codeEditorPane);
|
508 |
0
| JFrame xmlframe = new JFrame("Create XML Rule");
|
509 |
0
| xmlframe.setContentPane(rulePanel);
|
510 |
0
| xmlframe.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
|
511 |
0
| xmlframe.setSize(new Dimension(600, 700));
|
512 |
0
| xmlframe.addComponentListener(new java.awt.event.ComponentAdapter() {
|
513 |
0
| public void componentResized(ComponentEvent e) {
|
514 |
0
| JFrame tmp = (JFrame)e.getSource();
|
515 |
0
| if (tmp.getWidth()<600 || tmp.getHeight()<700) {
|
516 |
0
| tmp.setSize(600, 700);
|
517 |
| } |
518 |
| } |
519 |
| }); |
520 |
0
| int screenHeight = Toolkit.getDefaultToolkit().getScreenSize().height;
|
521 |
0
| int screenWidth = Toolkit.getDefaultToolkit().getScreenSize().width;
|
522 |
0
| xmlframe.pack();
|
523 |
0
| xmlframe.setLocation((screenWidth - xmlframe.getWidth()) / 2, (screenHeight - xmlframe.getHeight()) / 2);
|
524 |
0
| xmlframe.setVisible(true);
|
525 |
| } |
526 |
| |
527 |
0
| private JComponent createASTPanel() {
|
528 |
0
| astWidget.setCellRenderer(new ASTCellRenderer());
|
529 |
0
| return new JScrollPane(astWidget);
|
530 |
| } |
531 |
| |
532 |
0
| private JComponent createXPathResultPanel() {
|
533 |
0
| xpathResults.addElement("No results yet");
|
534 |
0
| xpathResultList.setBorder(BorderFactory.createLineBorder(Color.black));
|
535 |
0
| xpathResultList.setFixedCellWidth(300);
|
536 |
0
| JScrollPane scrollPane = new JScrollPane();
|
537 |
0
| scrollPane.getViewport().setView(xpathResultList);
|
538 |
0
| return scrollPane;
|
539 |
| } |
540 |
| |
541 |
0
| private JPanel createXPathQueryPanel() {
|
542 |
0
| JPanel p = new JPanel();
|
543 |
0
| p.setLayout(new BorderLayout());
|
544 |
0
| xpathQueryArea.setBorder(BorderFactory.createLineBorder(Color.black));
|
545 |
0
| makeTextComponentUndoable(xpathQueryArea);
|
546 |
0
| JScrollPane scrollPane = new JScrollPane(xpathQueryArea);
|
547 |
0
| scrollPane.setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_AS_NEEDED);
|
548 |
0
| scrollPane.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED);
|
549 |
0
| final JButton b = createGoButton();
|
550 |
| |
551 |
0
| p.add(new JLabel("XPath Query (if any)"), BorderLayout.NORTH);
|
552 |
0
| p.add(scrollPane, BorderLayout.CENTER);
|
553 |
0
| p.add(b, BorderLayout.SOUTH);
|
554 |
| |
555 |
0
| return p;
|
556 |
| } |
557 |
| |
558 |
0
| private JButton createGoButton() {
|
559 |
0
| JButton b = new JButton("Go");
|
560 |
0
| b.setMnemonic('g');
|
561 |
0
| b.addActionListener(new ShowListener());
|
562 |
0
| b.addActionListener(codeEditorPane);
|
563 |
0
| b.addActionListener(new XPathListener());
|
564 |
0
| b.addActionListener(new DFAListener());
|
565 |
0
| return b;
|
566 |
| } |
567 |
| |
568 |
0
| private static void makeTextComponentUndoable(JTextComponent textConponent) {
|
569 |
0
| final UndoManager undoManager = new UndoManager();
|
570 |
0
| textConponent.getDocument().addUndoableEditListener(new UndoableEditListener() {
|
571 |
0
| public void undoableEditHappened(
|
572 |
| UndoableEditEvent evt) { |
573 |
0
| undoManager.addEdit(evt.getEdit());
|
574 |
| } |
575 |
| }); |
576 |
0
| ActionMap actionMap = textConponent.getActionMap();
|
577 |
0
| InputMap inputMap = textConponent.getInputMap();
|
578 |
0
| actionMap.put("Undo", new AbstractAction("Undo") {
|
579 |
0
| public void actionPerformed(ActionEvent evt) {
|
580 |
0
| try {
|
581 |
0
| if (undoManager.canUndo()) {
|
582 |
0
| undoManager.undo();
|
583 |
| } |
584 |
| } catch (CannotUndoException e) { |
585 |
| } |
586 |
| } |
587 |
| }); |
588 |
0
| inputMap.put(KeyStroke.getKeyStroke("control Z"), "Undo");
|
589 |
| |
590 |
0
| actionMap.put("Redo", new AbstractAction("Redo") {
|
591 |
0
| public void actionPerformed(ActionEvent evt) {
|
592 |
0
| try {
|
593 |
0
| if (undoManager.canRedo()) {
|
594 |
0
| undoManager.redo();
|
595 |
| } |
596 |
| } catch (CannotRedoException e) { |
597 |
| } |
598 |
| } |
599 |
| }); |
600 |
0
| inputMap.put(KeyStroke.getKeyStroke("control Y"), "Redo");
|
601 |
| } |
602 |
| |
603 |
0
| public static void main(String[] args) {
|
604 |
0
| new Designer();
|
605 |
| } |
606 |
| |
607 |
0
| private final void copyXmlToClipboard() {
|
608 |
0
| if (codeEditorPane.getText() != null && codeEditorPane.getText().trim().length() > 0) {
|
609 |
0
| String xml = "";
|
610 |
0
| SimpleNode cu = getCompilationUnit();
|
611 |
0
| if (cu != null) {
|
612 |
0
| try {
|
613 |
0
| xml = getXmlString(cu);
|
614 |
| } catch (IOException e) { |
615 |
0
| e.printStackTrace();
|
616 |
0
| xml = "Error trying to construct XML representation";
|
617 |
| } |
618 |
| } |
619 |
0
| Toolkit.getDefaultToolkit().getSystemClipboard().setContents(new StringSelection(xml), this);
|
620 |
| } |
621 |
| } |
622 |
| |
623 |
| |
624 |
| |
625 |
| |
626 |
| |
627 |
| |
628 |
| |
629 |
| |
630 |
0
| private String getXmlString(SimpleNode node) throws IOException {
|
631 |
| |
632 |
| |
633 |
| |
634 |
| |
635 |
| |
636 |
| |
637 |
| |
638 |
0
| return "FIXME";
|
639 |
| } |
640 |
| |
641 |
0
| public void lostOwnership(Clipboard clipboard, Transferable contents) {
|
642 |
| } |
643 |
| } |
644 |
| |