Docjar: A Java Source and Docuemnt Enginecom.*    java.*    javax.*    org.*    all    new    plug-in

Quick Search    Search Deep

Source code: com/puppycrawl/tools/checkstyle/checks/ClassResolver.java


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;
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      public ClassResolver(ClassLoader aLoader, String aPkg, Set aImports)
49      {
50          mLoader = aLoader;
51          mPkg = aPkg;
52          mImports = aImports;
53      }
54  
55      /**
56       * Attempts to resolve the Class for a specified name. The algorithm is
57       * to check:
58       * - fully qualified name
59       * - explicit imports
60       * - enclosing package
61       * - star imports
62       * @param aName name of the class to resolve
63       * @return the resolved class
64       * @throws ClassNotFoundException if unable to resolve the class
65       */
66      public Class resolve(String aName) throws ClassNotFoundException
67      {
68          // See if the class is full qualified
69          if (isLoadable(aName)) {
70              return safeLoad(aName);
71          }
72  
73          // try matching explicit imports
74          Iterator it = mImports.iterator();
75          while (it.hasNext()) {
76              final String imp = (String) it.next();
77              if (imp.endsWith(aName) && isLoadable(imp)) {
78                  return safeLoad(imp);
79              }
80          }
81  
82          // See if in the package
83          if (mPkg != null) {
84              final String fqn = mPkg + "." + aName;
85              if (isLoadable(fqn)) {
86                  return safeLoad(fqn);
87              }
88          }
89  
90          // try "java.lang."
91          final String langClass = "java.lang." + aName;
92          if (isLoadable(langClass)) {
93              return safeLoad(langClass);
94          }
95  
96          // try star imports
97          it = mImports.iterator();
98          while (it.hasNext()) {
99              final String imp = (String) it.next();
100             if (imp.endsWith(".*")) {
101                 final String fqn = imp.substring(0, imp.lastIndexOf('.') + 1)
102                     + aName;
103                 if (isLoadable(fqn)) {
104                     return safeLoad(fqn);
105                 }
106             }
107         }
108 
109         // Giving up, the type is unknown, so load the class to generate an
110         // exception
111         return safeLoad(aName);
112     }
113 
114     /**
115      * @return whether a specified class is loadable with safeLoad().
116      * @param aName name of the class to check
117      */
118     public boolean isLoadable(String aName)
119     {
120         try {
121             safeLoad(aName);
122             return true;
123         }
124         catch (ClassNotFoundException e) {
125             return false;
126         }
127     }
128 
129     /**
130      * Will load a specified class is such a way that it will NOT be
131      * initialised.
132      * @param aName name of the class to load
133      * @return the <code>Class</code> for the specified class
134      * @throws ClassNotFoundException if an error occurs
135      */
136     public Class safeLoad(String aName)
137         throws ClassNotFoundException
138     {
139         // The next line will load the class using the specified class
140         // loader. The magic is having the "false" parameter. This means the
141         // class will not be initialised. Very, very important.
142         return Class.forName(aName, false, mLoader);
143     }
144 }