001    /*
002     *  * mesopotamia @mesopotamia.version@
003     * Multilingual parser and repository. 
004     * Copyright (C) 2005  Hammurapi Group
005     *
006     * This program is free software; you can redistribute it and/or
007     * modify it under the terms of the GNU Lesser General Public
008     * License as published by the Free Software Foundation; either
009     * version 2 of the License, or (at your option) any later version.
010     *
011     * This program is distributed in the hope that it will be useful,
012     * but WITHOUT ANY WARRANTY; without even the implied warranty of
013     * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
014     * Lesser General Public License for more details.
015     *
016     * You should have received a copy of the GNU Lesser General Public
017     * License along with this library; if not, write to the Free Software
018     * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
019     *
020     * URL: http://http://www.hammurapi.biz
021     * e-Mail: support@hammurapi.biz
022     */
023    package org.mesopotamia.util;
024    
025    import gnu.trove.TIntHashSet;
026    
027    import java.io.Reader;
028    import java.io.StringReader;
029    import java.lang.reflect.Constructor;
030    import java.lang.reflect.Method;
031    import java.util.ArrayList;
032    import java.util.Collections;
033    import java.util.Date;
034    import java.util.Iterator;
035    import java.util.List;
036    import java.util.StringTokenizer;
037    
038    import javax.swing.JFrame;
039    
040    import antlr.ASTFactory;
041    import antlr.Parser;
042    import antlr.Token;
043    import antlr.TokenStream;
044    import antlr.TokenStreamException;
045    import antlr.collections.AST;
046    import biz.hammurapi.antlr.ASTFrame.JTreeASTModel;
047    
048    
049    /**
050     * @author Pavel Vlasov
051     * 
052     */
053    public class AstDebugger extends JFrame {
054    
055            private javax.swing.JPanel jContentPane = null;
056    
057            private javax.swing.JLabel jLabel = null;
058    
059            private javax.swing.JTextField lexerField = null;
060    
061            private javax.swing.JTree jTree = null;
062    
063            private javax.swing.JLabel jLabel1 = null;
064    
065            private javax.swing.JTextField parserField = null;
066    
067            private javax.swing.JLabel jLabel2 = null;
068    
069            private javax.swing.JTextPane jTextPane = null;
070    
071            private javax.swing.JLabel statusLabel = null; // @jve:visual-info
072                                                                                                            // decl-index=0
073                                                                                                            // visual-constraint="415,698"
074    
075            private javax.swing.JComboBox methodComboBox = null;
076    
077            private javax.swing.JSplitPane jSplitPane = null;
078    
079            private javax.swing.JPanel jPanel1 = null;
080    
081            private javax.swing.JScrollPane jScrollPane = null;
082    
083            private javax.swing.JLabel jLabel3 = null;
084    
085            private javax.swing.JTextField wsTokensField = null;
086    
087            /**
088             * This is the default constructor
089             */
090            public AstDebugger() {
091                    super();
092                    initialize();
093            }
094    
095            /**
096             * This method initializes this
097             * 
098             * @return void
099             */
100            private void initialize() {
101                    this.setContentPane(getJContentPane());
102                    this.setSize(841, 709);
103                    this.setDefaultCloseOperation(javax.swing.JFrame.EXIT_ON_CLOSE);
104                    this.setTitle("AST Debugger");
105            }
106    
107            /**
108             * This method initializes jContentPane
109             * 
110             * @return javax.swing.JPanel
111             */
112            private javax.swing.JPanel getJContentPane() {
113                    if (jContentPane == null) {
114                            jContentPane = new javax.swing.JPanel();
115                            java.awt.GridBagConstraints consGridBagConstraints12 = new java.awt.GridBagConstraints();
116                            java.awt.GridBagConstraints consGridBagConstraints31 = new java.awt.GridBagConstraints();
117                            consGridBagConstraints12.gridx = 0;
118                            consGridBagConstraints12.gridy = 4;
119                            consGridBagConstraints12.gridwidth = 5;
120                            consGridBagConstraints31.fill = java.awt.GridBagConstraints.BOTH;
121                            consGridBagConstraints31.weighty = 1.0;
122                            consGridBagConstraints31.weightx = 1.0;
123                            consGridBagConstraints31.gridy = 3;
124                            consGridBagConstraints31.gridx = 2;
125                            consGridBagConstraints31.gridwidth = 3;
126                            jContentPane.setLayout(new java.awt.GridBagLayout());
127                            jContentPane.add(getJSplitPane(), consGridBagConstraints31);
128                            jContentPane.add(getStatusLabel(), consGridBagConstraints12);
129                    }
130                    return jContentPane;
131            }
132    
133            /**
134             * This method initializes jLabel
135             * 
136             * @return javax.swing.JLabel
137             */
138            private javax.swing.JLabel getJLabel() {
139                    if (jLabel == null) {
140                            jLabel = new javax.swing.JLabel();
141                            jLabel.setText("Lexer ");
142                    }
143                    return jLabel;
144            }
145    
146            /**
147             * This method initializes wsTokensField
148             * 
149             * @return javax.swing.JTextField
150             */
151            private javax.swing.JTextField getLexerField() {
152                    if (lexerField == null) {
153                            lexerField = new javax.swing.JTextField();
154                            lexerField.addKeyListener(new java.awt.event.KeyAdapter() {
155                                    public void keyTyped(java.awt.event.KeyEvent e) {
156                                            lastUpdate = System.currentTimeMillis();
157                                    }
158                            });
159                    }
160                    return lexerField;
161            }
162    
163            /**
164             * This method initializes jTree
165             * 
166             * @return javax.swing.JTree
167             */
168            private javax.swing.JTree getJTree() {
169                    if (jTree == null) {
170                            jTree = new javax.swing.JTree();
171                    }
172                    return jTree;
173            }
174    
175            /**
176             * This method initializes jLabel1
177             * 
178             * @return javax.swing.JLabel
179             */
180            private javax.swing.JLabel getJLabel1() {
181                    if (jLabel1 == null) {
182                            jLabel1 = new javax.swing.JLabel();
183                            jLabel1.setText("WS tokens");
184                    }
185                    return jLabel1;
186            }
187    
188            /**
189             * This method initializes jTextField1
190             * 
191             * @return javax.swing.JTextField
192             */
193            private javax.swing.JTextField getParserField() {
194                    if (parserField == null) {
195                            parserField = new javax.swing.JTextField();
196                            parserField.addKeyListener(new java.awt.event.KeyAdapter() {
197                                    public void keyTyped(java.awt.event.KeyEvent e) {
198                                            lastUpdate = System.currentTimeMillis();
199                                            parserClassUpdated = true;
200                                    }
201                            });
202                    }
203                    return parserField;
204            }
205    
206            /**
207             * This method initializes jLabel2
208             * 
209             * @return javax.swing.JLabel
210             */
211            private javax.swing.JLabel getJLabel2() {
212                    if (jLabel2 == null) {
213                            jLabel2 = new javax.swing.JLabel();
214                            jLabel2.setText("Method ");
215                    }
216                    return jLabel2;
217            }
218    
219            /**
220             * This method initializes jTextPane
221             * 
222             * @return javax.swing.JTextPane
223             */
224            private javax.swing.JTextPane getJTextPane() {
225                    if (jTextPane == null) {
226                            jTextPane = new javax.swing.JTextPane();
227                            jTextPane.addKeyListener(new java.awt.event.KeyAdapter() {
228                                    public void keyTyped(java.awt.event.KeyEvent e) {
229                                            lastUpdate = System.currentTimeMillis();
230                                    }
231                            });
232                    }
233                    return jTextPane;
234            }
235    
236            /**
237             * This method initializes jLabel3
238             * 
239             * @return javax.swing.JLabel
240             */
241            private javax.swing.JLabel getStatusLabel() {
242                    if (statusLabel == null) {
243                            statusLabel = new javax.swing.JLabel();
244                            statusLabel.setText(" ");
245                    }
246                    return statusLabel;
247            }
248    
249            /**
250             * This method initializes jComboBox
251             * 
252             * @return javax.swing.JComboBox
253             */
254            private javax.swing.JComboBox getMethodComboBox() {
255                    if (methodComboBox == null) {
256                            methodComboBox = new javax.swing.JComboBox();
257                            methodComboBox.addActionListener(new java.awt.event.ActionListener() {
258                                    public void actionPerformed(java.awt.event.ActionEvent e) {
259                                            lastUpdate = System.currentTimeMillis();
260                                    }
261                            });
262                    }
263                    return methodComboBox;
264            }
265    
266            /**
267             * This method initializes jSplitPane
268             * 
269             * @return javax.swing.JSplitPane
270             */
271            private javax.swing.JSplitPane getJSplitPane() {
272                    if (jSplitPane == null) {
273                            jSplitPane = new javax.swing.JSplitPane();
274                            jSplitPane.setLeftComponent(getJPanel1());
275                            jSplitPane.setRightComponent(getJPanel());
276                            jSplitPane.setDividerLocation(400);
277                    }
278                    return jSplitPane;
279            }
280    
281            private static class MethodEntry implements Comparable {
282                    Method method;
283    
284                    /**
285                     * @param method
286                     */
287                    public MethodEntry(Method method) {
288                            super();
289                            // TODO Auto-generated constructor stub
290                            this.method = method;
291                    }
292    
293                    public String toString() {
294                            return method.getName();
295                    }
296    
297                    public int compareTo(Object o) {
298                            return toString().compareTo(((MethodEntry) o).toString());
299                    }
300    
301            }
302    
303            /**
304             * This method initializes jPanel1
305             * 
306             * @return javax.swing.JPanel
307             */
308            private javax.swing.JPanel getJPanel1() {
309                    if (jPanel1 == null) {
310                            jPanel1 = new javax.swing.JPanel();
311                            java.awt.GridBagConstraints consGridBagConstraints51 = new java.awt.GridBagConstraints();
312                            java.awt.GridBagConstraints consGridBagConstraints61 = new java.awt.GridBagConstraints();
313                            java.awt.GridBagConstraints consGridBagConstraints8 = new java.awt.GridBagConstraints();
314                            java.awt.GridBagConstraints consGridBagConstraints9 = new java.awt.GridBagConstraints();
315                            java.awt.GridBagConstraints consGridBagConstraints10 = new java.awt.GridBagConstraints();
316                            java.awt.GridBagConstraints consGridBagConstraints11 = new java.awt.GridBagConstraints();
317                            java.awt.GridBagConstraints consGridBagConstraints13 = new java.awt.GridBagConstraints();
318                            java.awt.GridBagConstraints consGridBagConstraints14 = new java.awt.GridBagConstraints();
319                            java.awt.GridBagConstraints consGridBagConstraints71 = new java.awt.GridBagConstraints();
320                            consGridBagConstraints13.gridy = 2;
321                            consGridBagConstraints13.gridx = 0;
322                            consGridBagConstraints14.fill = java.awt.GridBagConstraints.HORIZONTAL;
323                            consGridBagConstraints14.weightx = 1.0;
324                            consGridBagConstraints14.gridy = 3;
325                            consGridBagConstraints14.gridx = 2;
326                            consGridBagConstraints51.gridy = 0;
327                            consGridBagConstraints51.gridx = 0;
328                            consGridBagConstraints9.gridy = 4;
329                            consGridBagConstraints9.gridx = 0;
330                            consGridBagConstraints8.gridy = 3;
331                            consGridBagConstraints8.gridx = 0;
332                            consGridBagConstraints61.fill = java.awt.GridBagConstraints.HORIZONTAL;
333                            consGridBagConstraints61.weightx = 1.0;
334                            consGridBagConstraints61.gridy = 0;
335                            consGridBagConstraints61.gridx = 2;
336                            consGridBagConstraints10.fill = java.awt.GridBagConstraints.HORIZONTAL;
337                            consGridBagConstraints10.anchor = java.awt.GridBagConstraints.WEST;
338                            consGridBagConstraints10.weightx = 1.0;
339                            consGridBagConstraints10.gridy = 4;
340                            consGridBagConstraints10.gridx = 2;
341                            consGridBagConstraints11.fill = java.awt.GridBagConstraints.BOTH;
342                            consGridBagConstraints11.weighty = 1.0;
343                            consGridBagConstraints11.weightx = 1.0;
344                            consGridBagConstraints11.gridy = 5;
345                            consGridBagConstraints11.gridx = 0;
346                            consGridBagConstraints11.gridwidth = 3;
347                            consGridBagConstraints61.gridwidth = 2;
348                            consGridBagConstraints71.fill = java.awt.GridBagConstraints.HORIZONTAL;
349                            consGridBagConstraints71.weightx = 1.0;
350                            consGridBagConstraints71.gridy = 2;
351                            consGridBagConstraints71.gridx = 2;
352                            consGridBagConstraints71.gridwidth = 2;
353                            jPanel1.setLayout(new java.awt.GridBagLayout());
354                            jPanel1.add(getJLabel(), consGridBagConstraints51);
355                            jPanel1.add(getLexerField(), consGridBagConstraints61);
356                            jPanel1.add(getParserField(), consGridBagConstraints71);
357                            jPanel1.add(getJLabel1(), consGridBagConstraints8);
358                            jPanel1.add(getJLabel2(), consGridBagConstraints9);
359                            jPanel1.add(getMethodComboBox(), consGridBagConstraints10);
360                            jPanel1.add(getJScrollPane(), consGridBagConstraints11);
361                            jPanel1.add(getJLabel3(), consGridBagConstraints13);
362                            jPanel1.add(getWsTokensField(), consGridBagConstraints14);
363                    }
364                    return jPanel1;
365            }
366    
367            /**
368             * This method initializes jScrollPane
369             * 
370             * @return javax.swing.JScrollPane
371             */
372            private javax.swing.JScrollPane getJScrollPane() {
373                    if (jScrollPane == null) {
374                            jScrollPane = new javax.swing.JScrollPane();
375                            jScrollPane.setViewportView(getJTextPane());
376                    }
377                    return jScrollPane;
378            }
379    
380            /**
381             * This method initializes jLabel3
382             * 
383             * @return javax.swing.JLabel
384             */
385            private javax.swing.JLabel getJLabel3() {
386                    if (jLabel3 == null) {
387                            jLabel3 = new javax.swing.JLabel();
388                            jLabel3.setText("Parser");
389                    }
390                    return jLabel3;
391            }
392    
393            /**
394             * This method initializes wsTokensField
395             * 
396             * @return javax.swing.JTextField
397             */
398            private javax.swing.JTextField getWsTokensField() {
399                    if (wsTokensField == null) {
400                            wsTokensField = new javax.swing.JTextField();
401                            wsTokensField.addKeyListener(new java.awt.event.KeyAdapter() {
402                                    public void keyTyped(java.awt.event.KeyEvent e) {
403                                            lastUpdate = System.currentTimeMillis();
404                                    }
405                            });
406                    }
407                    return wsTokensField;
408            }
409    
410            private long lastUpdate;
411    
412            private boolean parserClassUpdated;
413    
414            private javax.swing.JPanel jPanel = null;
415            private javax.swing.JButton jButton = null;
416            private javax.swing.JButton jButton1 = null;
417            private javax.swing.JButton jButton2 = null;
418            {
419                    Thread performer = new Thread() {
420                            public void run() {
421                                    while (true) {
422                                            try {
423                                                    sleep(100);
424                                            } catch (InterruptedException e1) {
425                                                    return;
426                                            }
427    
428                                            if (lastUpdate != 0 && System.currentTimeMillis() - lastUpdate > 2000) {
429                                                    lastUpdate = 0;
430                                                    process();
431                                            }
432                                    }
433                            }
434    
435                            /**
436                             * 
437                             */
438                            private void process() {
439                                    getJTree().setModel(null);
440                                    status(" ");
441                                    try {
442                                            String lexerClassName = getLexerField().getText();
443                                            if (lexerClassName == null || lexerClassName.trim().length() == 0) {
444                                                    status("Enter lexer class name");
445                                                    return;
446                                            }
447    
448                                            Class lexerClass = Class.forName(lexerClassName);
449                                            if (!TokenStream.class.isAssignableFrom(lexerClass)) {
450                                                    status(lexerClass.getName() + " does not implement " + TokenStream.class);
451                                                    return;
452                                            }
453    
454                                            Constructor lc = lexerClass.getConstructor(new Class[] { Reader.class });
455    
456                                            String parserClassName = getParserField().getText();
457                                            if (parserClassName == null || parserClassName.trim().length() == 0) {
458                                                    status("Enter parser class name");
459                                                    return;
460                                            }
461    
462                                            Class parserClass = Class.forName(parserClassName);
463                                            if (!Parser.class.isAssignableFrom(parserClass)) {
464                                                    status(parserClass.getName() + " does is not a subclass of " + Parser.class);
465                                                    return;
466                                            }
467    
468                                            if (parserClassUpdated) {
469                                                    parserClassUpdated = false;
470                                                    methodComboBox.removeAllItems();
471                                                    List<MethodEntry> methods = new ArrayList<MethodEntry>();
472                                                    Method[] parserMethods = parserClass.getMethods();
473                                                    for (int i = 0; i < parserMethods.length; i++) {
474                                                            if (parserMethods[i].getParameterTypes().length == 0) {
475                                                                    methods.add(new MethodEntry(parserMethods[i]));
476                                                            }
477                                                    }
478    
479                                                    Collections.sort(methods);
480                                                    Iterator<MethodEntry> mit = methods.iterator();
481                                                    while (mit.hasNext()) {
482                                                            methodComboBox.addItem(mit.next());
483                                                    }
484                                            }
485    
486                                            if (methodComboBox.getSelectedItem() == null) {
487                                                    status("Select parse method");
488                                                    return;
489                                            }
490    
491                                            final TIntHashSet wsTokens = new TIntHashSet();
492                                            String[] tokenNames = (String[]) parserClass.getField("_tokenNames").get(null);
493                                            String wsTokensString = getWsTokensField().getText();
494                                            if (wsTokensString.trim().length() > 0) {
495                                                    StringTokenizer st = new StringTokenizer(wsTokensString, ", ");
496                                                    W: while (st.hasMoreTokens()) {
497                                                            String wsToken = st.nextToken().trim();
498                                                            for (int i = 0; i < tokenNames.length; i++) {
499                                                                    if (wsToken.equals(tokenNames[i])) {
500                                                                            wsTokens.add(i);
501                                                                            continue W;
502                                                                    }
503                                                            }
504                                                            status("Invalid token name: " + wsToken);
505                                                            return;
506                                                    }
507                                            }
508    
509                                            String text = getJTextPane().getText();
510                                            if (text.length() == 0) {
511                                                    status("Type text to parse");
512                                                    return;
513                                            }
514    
515                                            final Object lexer = lc.newInstance(new Object[] { new StringReader(text) });
516                                            Constructor pc = parserClass.getConstructor(new Class[] { TokenStream.class });
517                                            Object parser = pc.newInstance(new Object[] { new TokenStream() {
518    
519                                                    public Token nextToken() throws TokenStreamException {
520                                                            Token ret = ((TokenStream) lexer).nextToken();
521                                                            return wsTokens.contains(ret.getType()) ? nextToken() : ret;
522                                                    }
523    
524                                            } });
525    
526                                            Method selectedMethod = ((MethodEntry) methodComboBox.getSelectedItem()).method;
527                                            selectedMethod.invoke(parser);
528                                            AST ast = ((Parser) parser).getAST();
529    
530                                            ASTFactory astFactory = new ASTFactory();
531    
532                                            AST r = astFactory.create(0, selectedMethod.getName());
533                                            r.setFirstChild(ast);
534    
535                                            JTreeASTModel model = new JTreeASTModel(r, tokenNames);
536                                            getJTree().setModel(model);
537                                            status(new Date().toString());
538                                    } catch (Exception e) {
539                                            Throwable cause=e;
540                                            while (cause.getCause()!=null && cause.getCause()!=cause) {
541                                                    cause=cause.getCause();
542                                            }
543                                            status(cause.toString());
544                                            cause.printStackTrace();
545                                    }
546                            }
547                    };
548    
549                    performer.setName("Parsing thread");
550                    performer.setDaemon(true);
551                    performer.start();
552            }
553    
554            private void status(String status) {
555                    getStatusLabel().setText(status);
556            }
557    
558            public static void main(String[] args) {
559                    AstDebugger astDebugger = new AstDebugger();
560                    astDebugger.getJTree().setModel(null);
561                    astDebugger.setVisible(true);
562            }
563            /**
564             * This method initializes jPanel
565             * 
566             * @return javax.swing.JPanel
567             */
568            private javax.swing.JPanel getJPanel() {
569                    if(jPanel == null) {
570                            jPanel = new javax.swing.JPanel();
571                            java.awt.GridBagConstraints consGridBagConstraints3 = new java.awt.GridBagConstraints();
572                            java.awt.GridBagConstraints consGridBagConstraints4 = new java.awt.GridBagConstraints();
573                            java.awt.GridBagConstraints consGridBagConstraints5 = new java.awt.GridBagConstraints();
574                            java.awt.GridBagConstraints consGridBagConstraints6 = new java.awt.GridBagConstraints();
575                            consGridBagConstraints5.gridy = 1;
576                            consGridBagConstraints5.gridx = 2;
577                            consGridBagConstraints6.fill = java.awt.GridBagConstraints.BOTH;
578                            consGridBagConstraints6.weighty = 1.0;
579                            consGridBagConstraints6.weightx = 1.0;
580                            consGridBagConstraints6.gridy = 0;
581                            consGridBagConstraints6.gridx = 0;
582                            consGridBagConstraints6.gridwidth = 3;
583                            consGridBagConstraints3.gridy = 1;
584                            consGridBagConstraints3.gridx = 0;
585                            consGridBagConstraints4.gridy = 1;
586                            consGridBagConstraints4.gridx = 1;
587                            jPanel.setLayout(new java.awt.GridBagLayout());
588                            jPanel.add(getJButton(), consGridBagConstraints3);
589                            jPanel.add(getJButton1(), consGridBagConstraints4);
590                            jPanel.add(getJButton2(), consGridBagConstraints5);
591                            jPanel.add(getJTree(), consGridBagConstraints6);
592                    }
593                    return jPanel;
594            }
595            /**
596             * This method initializes jButton
597             * 
598             * @return javax.swing.JButton
599             */
600            private javax.swing.JButton getJButton() {
601                    if(jButton == null) {
602                            jButton = new javax.swing.JButton();
603                            jButton.setText("Expand all");
604                            jButton.addActionListener(new java.awt.event.ActionListener() { 
605                                    public void actionPerformed(java.awt.event.ActionEvent e) {    
606                                            System.out.println("actionPerformed()"); // TODO Auto-generated Event stub actionPerformed()
607                                    }
608                            });
609                    }
610                    return jButton;
611            }
612            /**
613             * This method initializes jButton1
614             * 
615             * @return javax.swing.JButton
616             */
617            private javax.swing.JButton getJButton1() {
618                    if(jButton1 == null) {
619                            jButton1 = new javax.swing.JButton();
620                            jButton1.setText("Collapse All");
621                            jButton1.setHorizontalAlignment(javax.swing.SwingConstants.RIGHT);
622                            jButton1.addActionListener(new java.awt.event.ActionListener() { 
623                                    public void actionPerformed(java.awt.event.ActionEvent e) {    
624                                            System.out.println("actionPerformed()"); // TODO Auto-generated Event stub actionPerformed()
625                                    }
626                            });
627                    }
628                    return jButton1;
629            }
630            /**
631             * This method initializes jButton2
632             * 
633             * @return javax.swing.JButton
634             */
635            private javax.swing.JButton getJButton2() {
636                    if(jButton2 == null) {
637                            jButton2 = new javax.swing.JButton();
638                            jButton2.setText("Print");
639                            jButton2.setHorizontalAlignment(javax.swing.SwingConstants.RIGHT);
640                            jButton2.addActionListener(new java.awt.event.ActionListener() { 
641                                    public void actionPerformed(java.awt.event.ActionEvent e) {    
642                                            new ComponentPrinter(getJTree()).print();
643                                    }
644                            });
645                    }
646                    return jButton2;
647            }
648    }  //  @jve:visual-info  decl-index=0 visual-constraint="10,10" @jve:visual-info decl-index=0 visual-constraint="4,5"