Clover Coverage Report - Checkstyle
Coverage timestamp: Fri May 9 2008 10:48:13 EST
../../../../../img/srcFileCovDistChart10.png 0% of files have more coverage
46   190   21   9.2
30   95   0.46   5
5     4.2  
1    
 
  ClassResolver       Line # 32 97.5% 0.97530866
21.01 46 21 21 0.46
 
  ( 10 of 21)
 
1    ////////////////////////////////////////////////////////////////////////////////
2    // checkstyle: Checks Java source code for adherence to a set of rules.
3    // Copyright (C) 2001-2005 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;
20   
21    import java.util.Set;
22    import java.util.Iterator;
23   
24    /**
25    * Utility class to resolve a class name to an actual class. Note that loaded
26    * classes are not initialized.
27    * <p>Limitations: this does not handle inner classes very well.</p>
28    *
29    * @author Oliver Burn
30    * @version 1.0
31    */
 
32    public class ClassResolver
33    {
34    /** name of the package to check if the class belongs to **/
35    private final String mPkg;
36    /** set of imports to check against **/
37    private final Set mImports;
38    /** use to load classes **/
39    private final ClassLoader mLoader;
40   
41    /**
42    * Creates a new <code>ClassResolver</code> instance.
43    *
44    * @param aLoader the ClassLoader to load classes with.
45    * @param aPkg the name of the package the class may belong to
46    * @param aImports set of imports to check if the class belongs to
47    */
 
48  22 toggle public ClassResolver(ClassLoader aLoader, String aPkg, Set aImports)
49    {
50  22 mLoader = aLoader;
51  22 mPkg = aPkg;
52  22 mImports = aImports;
53  22 mImports.add("java.lang.*");
54    }
55   
56    /**
57    * Attempts to resolve the Class for a specified name. The algorithm is
58    * to check:
59    * - fully qualified name
60    * - explicit imports
61    * - enclosing package
62    * - star imports
63    * @param aName name of the class to resolve
64    * @param aCurrentClass name of current class (for inner classes).
65    * @return the resolved class
66    * @throws ClassNotFoundException if unable to resolve the class
67    */
 
68  175 toggle public Class resolve(String aName, String aCurrentClass)
69    throws ClassNotFoundException
70    {
71    // See if the class is full qualified
72  175 Class clazz = resolveQualifiedName(aName);
73  175 if (clazz != null) {
74  54 return clazz;
75    }
76   
77    // try matching explicit imports
78  121 Iterator it = mImports.iterator();
79  307 while (it.hasNext()) {
80  218 final String imp = (String) it.next();
81    // Very important to add the "." in the check below. Otherwise you
82    // when checking for "DataException", it will match on
83    // "SecurityDataException". This has been the cause of a very
84    // difficult bug to resolve!
85  218 if (imp.endsWith("." + aName)) {
86  32 clazz = resolveQualifiedName(imp);
87  32 if (clazz != null) {
88  32 return clazz;
89    }
90   
91    }
92    }
93   
94    // See if in the package
95  89 if (!"".equals(mPkg)) {
96  62 clazz = resolveQualifiedName(mPkg + "." + aName);
97  62 if (clazz != null) {
98  13 return clazz;
99    }
100    }
101   
102    //inner class of this class???
103  76 if (!"".equals(aCurrentClass)) {
104  71 final String innerClass = (!"".equals(mPkg) ? (mPkg + ".") : "")
105    + aCurrentClass + "$" + aName;
106  71 if (isLoadable(innerClass)) {
107  25 return safeLoad(innerClass);
108    }
109    }
110   
111    // try star imports
112  51 it = mImports.iterator();
113  65 while (it.hasNext()) {
114  62 final String imp = (String) it.next();
115  62 if (imp.endsWith(".*")) {
116  58 final String fqn = imp.substring(0, imp.lastIndexOf('.') + 1)
117    + aName;
118  58 clazz = resolveQualifiedName(fqn);
119  58 if (clazz != null) {
120  48 return clazz;
121    }
122    }
123    }
124   
125    // Giving up, the type is unknown, so load the class to generate an
126    // exception
127  3 return safeLoad(aName);
128    }
129   
130    /**
131    * @return whether a specified class is loadable with safeLoad().
132    * @param aName name of the class to check
133    */
 
134  468 toggle public boolean isLoadable(String aName)
135    {
136  468 try {
137  468 safeLoad(aName);
138  172 return true;
139    }
140    catch (final ClassNotFoundException e) {
141  296 return false;
142    }
143    }
144   
145    /**
146    * Will load a specified class is such a way that it will NOT be
147    * initialised.
148    * @param aName name of the class to load
149    * @return the <code>Class</code> for the specified class
150    * @throws ClassNotFoundException if an error occurs
151    */
 
152  643 toggle public Class safeLoad(String aName)
153    throws ClassNotFoundException
154    {
155    // The next line will load the class using the specified class
156    // loader. The magic is having the "false" parameter. This means the
157    // class will not be initialised. Very, very important.
158  643 return Class.forName(aName, false, mLoader);
159    }
160   
161    /**
162    * Tries to resolve a class for fully-specified name.
163    * @param aName a given name of class.
164    * @return Class object for the given name or null.
165    */
 
166  327 toggle private Class resolveQualifiedName(final String aName)
167    {
168  327 try {
169  327 if (isLoadable(aName)) {