001////////////////////////////////////////////////////////////////////////////////
002// checkstyle: Checks Java source code for adherence to a set of rules.
003// Copyright (C) 2001-2015 the original author or authors.
004//
005// This library is free software; you can redistribute it and/or
006// modify it under the terms of the GNU Lesser General Public
007// License as published by the Free Software Foundation; either
008// version 2.1 of the License, or (at your option) any later version.
009//
010// This library is distributed in the hope that it will be useful,
011// but WITHOUT ANY WARRANTY; without even the implied warranty of
012// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
013// Lesser General Public License for more details.
014//
015// You should have received a copy of the GNU Lesser General Public
016// License along with this library; if not, write to the Free Software
017// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
018////////////////////////////////////////////////////////////////////////////////
019
020package com.puppycrawl.tools.checkstyle.gui;
021
022import javax.swing.tree.TreePath;
023
024import antlr.ASTFactory;
025import antlr.collections.AST;
026
027import com.puppycrawl.tools.checkstyle.api.DetailAST;
028import com.puppycrawl.tools.checkstyle.api.TokenTypes;
029import com.puppycrawl.tools.checkstyle.utils.TokenUtils;
030
031/**
032 * The model that backs the parse tree in the GUI.
033 *
034 * @author Lars Kühne
035 */
036public class ParseTreeModel extends AbstractTreeTableModel {
037    /** Column names. */
038    private static final String[] COLUMN_NAMES = {
039        "Tree", "Type", "Line", "Column", "Text",
040    };
041
042    /**
043     * @param parseTree DetailAST parse tree.
044     */
045    public ParseTreeModel(DetailAST parseTree) {
046        super(createArtificialTreeRoot());
047        setParseTree(parseTree);
048    }
049
050    /**
051     * Creates artificial tree root.
052     * @return Artificial tree root.
053     */
054    private static DetailAST createArtificialTreeRoot() {
055        final ASTFactory factory = new ASTFactory();
056        factory.setASTNodeClass(DetailAST.class.getName());
057        return (DetailAST) factory.create(TokenTypes.EOF, "ROOT");
058    }
059
060    /**
061     * Sets parse tree.
062     * @param parseTree DetailAST parse tree.
063     */
064    final void setParseTree(DetailAST parseTree) {
065        final DetailAST root = (DetailAST) getRoot();
066        root.setFirstChild(parseTree);
067        final Object[] path = {root};
068        // no need to setup remaining info, as the call results in a
069        // table structure changed event anyway - we just pass nulls
070        fireTreeStructureChanged(this, path, null, (Object[]) null);
071    }
072
073    @Override
074    public int getColumnCount() {
075        return COLUMN_NAMES.length;
076    }
077
078    @Override
079    public String getColumnName(int column) {
080        return COLUMN_NAMES[column];
081    }
082
083    @Override
084    public Class<?> getColumnClass(int column) {
085        Class<?> columnClass;
086
087        switch (column) {
088            case 0:
089                columnClass = TreeTableModel.class;
090                break;
091            case 1:
092                columnClass = String.class;
093                break;
094            case 2:
095                columnClass = Integer.class;
096                break;
097            case 3:
098                columnClass = Integer.class;
099                break;
100            case 4:
101                columnClass = String.class;
102                break;
103            default:
104                columnClass = Object.class;
105        }
106        return columnClass;
107    }
108
109    @Override
110    public Object getValueAt(Object node, int column) {
111        final DetailAST ast = (DetailAST) node;
112        Object value;
113
114        switch (column) {
115            case 1:
116                value = TokenUtils.getTokenName(ast.getType());
117                break;
118            case 2:
119                value = ast.getLineNo();
120                break;
121            case 3:
122                value = ast.getColumnNo();
123                break;
124            case 4:
125                value = ast.getText();
126                break;
127            default:
128                value = null;
129        }
130        return value;
131    }
132
133    @Override
134    public Object getChild(Object parent, int index) {
135        final DetailAST ast = (DetailAST) parent;
136        int currentIndex = 0;
137        AST child = ast.getFirstChild();
138        while (currentIndex < index) {
139            child = child.getNextSibling();
140            currentIndex++;
141        }
142        return child;
143    }
144
145    @Override
146    public int getChildCount(Object parent) {
147        final DetailAST ast = (DetailAST) parent;
148        return ast.getChildCount();
149    }
150
151    @Override
152    public void valueForPathChanged(TreePath path, Object newValue) {
153        //No Code, as tree is read-only
154    }
155}