View Javadoc
1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one or more
3    * contributor license agreements.  See the NOTICE file distributed with
4    * this work for additional information regarding copyright ownership.
5    * The ASF licenses this file to You under the Apache License, Version 2.0
6    * (the "License"); you may not use this file except in compliance with
7    * the License.  You may obtain a copy of the License at
8    *
9    *      http://www.apache.org/licenses/LICENSE-2.0
10   *
11   *  Unless required by applicable law or agreed to in writing, software
12   *  distributed under the License is distributed on an "AS IS" BASIS,
13   *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14   *  See the License for the specific language governing permissions and
15   *  limitations under the License.
16   *
17   */
18  package org.apache.bcel.generic;
19  
20  import org.apache.bcel.Const;
21  import org.apache.bcel.Repository;
22  import org.apache.bcel.classfile.JavaClass;
23  
24  /**
25   * Denotes reference such as java.lang.String.
26   *
27   */
28  public class ObjectType extends ReferenceType {
29  
30      private final String className; // Class name of type
31  
32      /**
33       * @since 6.0
34       */
35      public static ObjectType getInstance(final String className) {
36          return new ObjectType(className);
37      }
38  
39      /**
40       * @param className fully qualified class name, e.g. java.lang.String
41       */
42      public ObjectType(final String className) {
43          super(Const.T_REFERENCE, "L" + className.replace('.', '/') + ";");
44          this.className = className.replace('/', '.');
45      }
46  
47  
48      /** @return name of referenced class
49       */
50      public String getClassName() {
51          return className;
52      }
53  
54  
55      /** @return a hash code value for the object.
56       */
57      @Override
58      public int hashCode() {
59          return className.hashCode();
60      }
61  
62  
63      /** @return true if both type objects refer to the same class.
64       */
65      @Override
66      public boolean equals( final Object type ) {
67          return (type instanceof ObjectType)
68                  ? ((ObjectType) type).className.equals(className)
69                  : false;
70      }
71  
72  
73      /**
74       * If "this" doesn't reference a class, it references an interface
75       * or a non-existant entity.
76       * @deprecated (since 6.0) this method returns an inaccurate result
77       *   if the class or interface referenced cannot
78       *   be found: use referencesClassExact() instead
79       */
80      @Deprecated
81      public boolean referencesClass() {
82          try {
83              final JavaClass jc = Repository.lookupClass(className);
84              return jc.isClass();
85          } catch (final ClassNotFoundException e) {
86              return false;
87          }
88      }
89  
90  
91      /**
92       * If "this" doesn't reference an interface, it references a class
93       * or a non-existant entity.
94       * @deprecated (since 6.0) this method returns an inaccurate result
95       *   if the class or interface referenced cannot
96       *   be found: use referencesInterfaceExact() instead
97       */
98      @Deprecated
99      public boolean referencesInterface() {
100         try {
101             final JavaClass jc = Repository.lookupClass(className);
102             return !jc.isClass();
103         } catch (final ClassNotFoundException e) {
104             return false;
105         }
106     }
107 
108 
109     /**
110      * Return true if this type references a class,
111      * false if it references an interface.
112      * @return true if the type references a class, false if
113      *   it references an interface
114      * @throws ClassNotFoundException if the class or interface
115      *   referenced by this type can't be found
116      */
117     public boolean referencesClassExact() throws ClassNotFoundException {
118         final JavaClass jc = Repository.lookupClass(className);
119         return jc.isClass();
120     }
121 
122 
123     /**
124      * Return true if this type references an interface,
125      * false if it references a class.
126      * @return true if the type references an interface, false if
127      *   it references a class
128      * @throws ClassNotFoundException if the class or interface
129      *   referenced by this type can't be found
130      */
131     public boolean referencesInterfaceExact() throws ClassNotFoundException {
132         final JavaClass jc = Repository.lookupClass(className);
133         return !jc.isClass();
134     }
135 
136 
137     /**
138      * Return true if this type is a subclass of given ObjectType.
139      * @throws ClassNotFoundException if any of this class's superclasses
140      *  can't be found
141      */
142     public boolean subclassOf( final ObjectType superclass ) throws ClassNotFoundException {
143         if (this.referencesInterfaceExact() || superclass.referencesInterfaceExact()) {
144             return false;
145         }
146         return Repository.instanceOf(this.className, superclass.className);
147     }
148 
149 
150     /**
151      * Java Virtual Machine Specification edition 2, � 5.4.4 Access Control
152      * @throws ClassNotFoundException if the class referenced by this type
153      *   can't be found
154      */
155     public boolean accessibleTo( final ObjectType accessor ) throws ClassNotFoundException {
156         final JavaClass jc = Repository.lookupClass(className);
157         if (jc.isPublic()) {
158             return true;
159         }
160         final JavaClass acc = Repository.lookupClass(accessor.className);
161         return acc.getPackageName().equals(jc.getPackageName());
162     }
163 }