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

Quick Search    Search Deep

Source code: com/puppycrawl/tools/checkstyle/bcel/classfile/JavaClassDefinition.java


1   //Tested with BCEL-5.1
2   //http://jakarta.apache.org/builds/jakarta-bcel/release/v5.1/
3   
4   package com.puppycrawl.tools.checkstyle.bcel.classfile;
5   
6   import java.util.HashMap;
7   import java.util.HashSet;
8   import java.util.Map;
9   import java.util.Set;
10  
11  import org.apache.bcel.Repository;
12  import org.apache.bcel.classfile.Field;
13  import org.apache.bcel.classfile.JavaClass;
14  import org.apache.bcel.classfile.Method;
15  import org.apache.bcel.generic.Type;
16  
17  
18  /**
19   * Contains the definition of a org.apache.bcel.classfile.JavaClass and
20   * the definitions of Methods and Fields of the JavaClass
21   * @author Rick Giles
22   */
23  public class JavaClassDefinition
24  {
25      /** the JavaClass */
26      private JavaClass mJavaClass;
27  
28      /** the method definitions */
29      private MethodDefinition[] mMethodDefs;
30  
31      /** field definitions, keyed on field name */
32      private Map mFieldDefs;
33  
34      /**
35       * Creates a JavaClassDefinition from a JavaClass. The fields and
36       * methods of the JavaClassDefinition are those whose scopes are
37       * in restricted sets of Scopes.
38       * @param aJavaClass the JavaClass for the definition.
39       * @param aFieldScopes the restricted set of field scopes.
40       * @param aMethodScopes the restriced set of method scopes.
41       */
42      public JavaClassDefinition(
43          JavaClass aJavaClass,
44          Set aFieldScopes,
45          Set aMethodScopes)
46      {
47          mJavaClass = aJavaClass;
48  
49          // create method definitions, restricted by scope
50          final Method[] methods = aJavaClass.getMethods();
51          final Set methodSet = new HashSet();
52          mMethodDefs = new MethodDefinition[methods.length];
53          for (int i = 0; i < methods.length; i++) {
54              if (Utils.inScope(methods[i], aMethodScopes)) {
55                  methodSet.add(new MethodDefinition(methods[i]));
56              }
57          }
58          mMethodDefs =
59              (MethodDefinition[]) methodSet.toArray(
60                  new MethodDefinition[methodSet.size()]);
61  
62          // create field definitions, restricted by scope
63          final Field[] fields = aJavaClass.getFields();
64          mFieldDefs = new HashMap(fields.length);
65          for (int i = 0; i < fields.length; i++) {
66              if (Utils.inScope(fields[i], aFieldScopes)) {
67                  mFieldDefs.put(
68                      fields[i].getName(),
69                      new FieldDefinition(fields[i]));
70              }
71          }
72      }
73  
74     /**
75       * Gets the JavaClass for this definition.
76       * @return the JavaClass
77       */
78      public JavaClass getJavaClass()
79      {
80          return mJavaClass;
81      }
82  
83      /**
84       * Gets the method definitions for Methods of the JavaClass.
85       * @return the method definitions for Methods of the JavaClass.
86       */
87      public MethodDefinition[] getMethodDefs()
88      {
89          return mMethodDefs;
90      }
91  
92      /**
93       * Gets the field definitions for Fields of the JavaClass.
94       * @return the method definitions for Fields of the JavaClass.
95       */
96      public FieldDefinition[] getFieldDefs()
97      {
98          return (FieldDefinition[]) mFieldDefs.values().toArray(
99              new FieldDefinition[mFieldDefs.size()]);
100     }
101 
102     /**
103      * Finds the narrowest method that is compatible with a method.
104      * An invocation of the given method can be resolved as an invocation
105      * of the narrowest method.
106      * @param aClassName the class for the method.
107      * @param aMethodName the name of the method.
108      * @param aArgTypes the types for the method.
109      * @return the narrowest compatible method.
110      */
111     public MethodDefinition findNarrowestMethod(
112         String aClassName,
113         String aMethodName,
114         Type[] aArgTypes)
115     {
116         MethodDefinition result = null;
117         final String javaClassName = mJavaClass.getClassName();
118         if (Repository.instanceOf(aClassName, javaClassName)) {
119             // check all
120             for (int i = 0; i < mMethodDefs.length; i++) {
121                 // TODO: check access privileges
122                 if (mMethodDefs[i].isCompatible(aMethodName, aArgTypes)) {
123                     if (result == null) {
124                         result = mMethodDefs[i];
125                     }
126                     //else if (mMethodDefs[i].isAsNarrow(result)) {
127                     else if (result.isCompatible(mMethodDefs[i])) {
128                         result = mMethodDefs[i];
129                     }
130                 }
131             }
132         }
133         return result;
134     }
135 
136     /**
137      * Finds a field definition.
138      * @param aFieldName the name of the field.
139      * @return the field definition named aFieldName.
140      */
141     public FieldDefinition findFieldDef(String aFieldName)
142     {
143         return (FieldDefinition) mFieldDefs.get(aFieldName);
144     }
145 
146     /**
147      * Determines whether there is reference to a given Method in this JavaClass
148      * definition or a definition in a superclass.
149      * @param aMethodDef the Method to check.
150      * @param aReferenceDAO reference DAO.
151      * @return true if there is a reference to the method of aMethodDef in
152      * this JavaClass or a superclass.
153      */
154     public boolean hasReference(
155         MethodDefinition aMethodDef,
156         ReferenceDAO aReferenceDAO)
157     {
158         final String methodName = aMethodDef.getName();
159         final Type[] argTypes = aMethodDef.getArgumentTypes();
160 
161         // search the inheritance hierarchy
162         JavaClass currentJavaClass = getJavaClass();
163         while (currentJavaClass != null) {
164             final JavaClassDefinition javaClassDef =
165                 aReferenceDAO.findJavaClassDef(currentJavaClass);
166             if (javaClassDef != null) {
167                 final MethodDefinition methodDef =
168                     javaClassDef.findNarrowestMethod(
169                         getJavaClass().getClassName(),
170                         methodName,
171                         argTypes);
172                 if ((methodDef != null)
173                     && (methodDef.hasReference(getJavaClass())))
174                 {
175                     return true;
176                 }
177             }
178             currentJavaClass = currentJavaClass.getSuperClass();
179         }
180         return false;
181     }
182 
183     /** @see java.lang.Object#toString() */
184     public String toString()
185     {
186         return getJavaClass().toString();
187     }
188 }