KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > puppycrawl > tools > checkstyle > checks > usage > transmogrify > ASTManager


1 ////////////////////////////////////////////////////////////////////////////////
2
// checkstyle: Checks Java source code for adherence to a set of rules.
3
// Copyright (C) 2001-2003 Oliver Burn
4
//
5
// This library is free software; you can redistribute it and/or
6
// modify it under the terms of the GNU Lesser General Public
7
// License as published by the Free Software Foundation; either
8
// version 2.1 of the License, or (at your option) any later version.
9
//
10
// This library is distributed in the hope that it will be useful,
11
// but WITHOUT ANY WARRANTY; without even the implied warranty of
12
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13
// Lesser General Public License for more details.
14
//
15
// You should have received a copy of the GNU Lesser General Public
16
// License along with this library; if not, write to the Free Software
17
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18
////////////////////////////////////////////////////////////////////////////////
19
package com.puppycrawl.tools.checkstyle.checks.usage.transmogrify;
20
21 import java.io.File JavaDoc;
22 import java.util.HashMap JavaDoc;
23 import java.util.HashSet JavaDoc;
24 import java.util.Iterator JavaDoc;
25 import java.util.Map JavaDoc;
26 import java.util.Set JavaDoc;
27
28 import antlr.collections.AST;
29
30 import com.puppycrawl.tools.checkstyle.checks.usage.AbstractUsageCheck;
31
32 /**
33  * Manages AST trees and nodes. Capable of managing multiple parse trees, which
34  * is useful for inter-file checks.
35  * @author Rick Giles
36  */

37 public final class ASTManager
38 {
39     /** singleton */
40     private static final ASTManager INSTANCE = new ASTManager();
41
42     /**
43      * Maps DetailASTs to SymTabASTs.
44      * A HashMap is acceptable provided DetailAST method hashCode() returns
45      * distinct integers for distinct objects.
46      * If not, a structure such as IdentityHashMap must be employed.
47      */

48     private Map JavaDoc mMap = new HashMap JavaDoc();
49
50     /** root with subtrees for a set of files */
51     private SymTabAST mCompleteTree = null;
52
53     /** Map for parse trees, keyed on File name */
54     private Map JavaDoc mTrees = new HashMap JavaDoc();
55
56     /** Set of checks and their nodes to check */
57     private Map JavaDoc mCheckNodes = new HashMap JavaDoc();
58
59     /** prevent client creation */
60     private ASTManager()
61     {
62     }
63
64     /**
65      * Returns the singleon ASTManager.
66      * @return the singleon ASTManager.
67      */

68     public static ASTManager getInstance()
69     {
70         return INSTANCE;
71     }
72
73     /**
74      * Add the parse tree for a file to the set of parse trees.
75      * Postcondition: since all checks are local to one source file,
76      * all managed elements are cleared.
77      * @param aFileName the name of the file.
78      * @param aRoot the root of the AST.
79      */

80     public void addTree(String JavaDoc aFileName, AST aRoot)
81     {
82         clear();
83         mTrees.put(aFileName, aRoot);
84     }
85
86     /**
87      * Clears all managed elements.
88      */

89     private void clear() {
90         mCheckNodes.clear();
91         mTrees.clear();
92         mMap.clear();
93         mCompleteTree = null;
94     }
95
96     /**
97      * Builds the complete tree for all added parse trees.
98      * @throws SymbolTableException if there is an error.
99      */

100     private void buildTree()
101         throws SymbolTableException
102     {
103         mCompleteTree = SymTabASTFactory.create(0, "AST Root");
104         final Set JavaDoc keys = mTrees.keySet();
105         final Iterator JavaDoc it = keys.iterator();
106         while (it.hasNext()) {
107             final String JavaDoc fileName = (String JavaDoc) it.next();
108             final File JavaDoc file = new File JavaDoc(fileName);
109             final AST rootAST = (AST) mTrees.get(fileName);
110             addToCompleteTree(file, rootAST);
111         }
112
113         // Walk of the complete tree.
114
// TODO: This is a hack. Find a better way.
115
new TableMaker(mCompleteTree).getTable();
116     }
117
118     /**
119      * Adds a file and a DetailAST to the root SymTabAST tree. Normally, the
120      * DetailAST will be the parse tree for the file.
121      * @param aFile the file to add.
122      * @param aAST the DetailAST to add.
123     */

124     private void addToCompleteTree(File JavaDoc aFile, AST aAST)
125     {
126         // add aFile to the root
127
final SymTabAST fileNode =
128             SymTabASTFactory.create(0, aFile.getAbsolutePath());
129         fileNode.setFile(aFile);
130         mCompleteTree.addChild(fileNode);
131         fileNode.setParent(mCompleteTree);
132
133         // add aAST to aFile
134
final SymTabAST child = SymTabASTFactory.create(aAST);
135         child.setFile(aFile);
136         fileNode.addChild(child);
137         child.setParent(fileNode);
138         fileNode.finishDefinition(aFile, mCompleteTree);
139     }
140
141     /**
142      * Registers a node for checking.
143      * @param aCheck the check to apply.
144      * @param aNode the node to check.
145      */

146     public void registerCheckNode(AbstractUsageCheck aCheck, AST aNode)
147     {
148         Set JavaDoc nodeSet = (Set JavaDoc) mCheckNodes.get(aCheck);
149         if (nodeSet == null) {
150             nodeSet = new HashSet JavaDoc();
151             nodeSet.add(aNode);
152             mCheckNodes.put(aCheck, nodeSet);
153         }
154         else {
155             nodeSet.add(aNode);
156         }
157     }
158
159     /**
160      * Gets the nodes to check with a usage check.
161      * @param aCheck the usage check.
162      * @return the nodes to check with aCheck.
163      * @throws SymbolTableException if there is an error.
164      */

165     public Set JavaDoc getCheckNodes(AbstractUsageCheck aCheck)
166         throws SymbolTableException
167     {
168         // lazy initialization
169
if (mCompleteTree == null) {
170             buildTree();
171         }
172         Set JavaDoc result = (Set JavaDoc) mCheckNodes.get(aCheck);
173         if (result == null) {
174             result = new HashSet JavaDoc();
175         }
176         return result;
177     }
178
179     /**
180      * Maps a AST to its associated SymTabAST.
181      * @param aAST the AST.
182      * @param aSymTabAST the SymTabAST associated with aAST.
183      */

184     public void put(AST aAST, SymTabAST aSymTabAST)
185     {
186         mMap.put(aAST, aSymTabAST);
187     }
188
189     /**
190      * Gets the SymTabAST associated with a AST.
191      * @param aAST the AST.
192      * @return the the SymTabAST associated with aAST.
193      */

194     public SymTabAST get(AST aAST)
195     {
196         return (SymTabAST) mMap.get(aAST);
197     }
198
199     /**
200      * Clears all associations from DetailsASTs to SymTabASTs.
201      */

202     public void clearDetailsMap()
203     {
204         mMap.clear();
205     }
206
207     /**
208      * Determines whether the map from DetailsASTs to SymTabASTs is empty.
209      * @return true if the map is empty.
210      */

211     public boolean isEmptyDetailsMap()
212     {
213         return mMap.isEmpty();
214     }
215
216     /**
217      * Removes a check and its check nodes. Clears all managed elements if
218      * last check removed.
219      * @param aCheck the check to remove.
220      */

221     public void removeCheck(AbstractUsageCheck aCheck)
222     {
223         mCheckNodes.remove(aCheck);
224         if (mCheckNodes.isEmpty()) {
225             clear();
226         }
227     }
228 }
229
Popular Tags