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.Constants;
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 * @version $Id: ObjectType.java 1152072 2011-07-29 01:54:05Z dbrosius $
28 * @author <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A>
29 */
30 public class ObjectType extends ReferenceType {
31
32 private static final long serialVersionUID = -2819379966444533294L;
33 private String class_name; // Class name of type
34
35
36 /**
37 * @param class_name fully qualified class name, e.g. java.lang.String
38 */
39 public ObjectType(String class_name) {
40 super(Constants.T_REFERENCE, "L" + class_name.replace('.', '/') + ";");
41 this.class_name = class_name.replace('/', '.');
42 }
43
44
45 /** @return name of referenced class
46 */
47 public String getClassName() {
48 return class_name;
49 }
50
51
52 /** @return a hash code value for the object.
53 */
54 @Override
55 public int hashCode() {
56 return class_name.hashCode();
57 }
58
59
60 /** @return true if both type objects refer to the same class.
61 */
62 @Override
63 public boolean equals( Object type ) {
64 return (type instanceof ObjectType)
65 ? ((ObjectType) type).class_name.equals(class_name)
66 : false;
67 }
68
69
70 /**
71 * If "this" doesn't reference a class, it references an interface
72 * or a non-existant entity.
73 * @deprecated this method returns an inaccurate result
74 * if the class or interface referenced cannot
75 * be found: use referencesClassExact() instead
76 */
77 @Deprecated
78 public boolean referencesClass() {
79 try {
80 JavaClass jc = Repository.lookupClass(class_name);
81 return jc.isClass();
82 } catch (ClassNotFoundException e) {
83 return false;
84 }
85 }
86
87
88 /**
89 * If "this" doesn't reference an interface, it references a class
90 * or a non-existant entity.
91 * @deprecated this method returns an inaccurate result
92 * if the class or interface referenced cannot
93 * be found: use referencesInterfaceExact() instead
94 */
95 @Deprecated
96 public boolean referencesInterface() {
97 try {
98 JavaClass jc = Repository.lookupClass(class_name);
99 return !jc.isClass();
100 } catch (ClassNotFoundException e) {
101 return false;
102 }
103 }
104
105
106 /**
107 * Return true if this type references a class,
108 * false if it references an interface.
109 * @return true if the type references a class, false if
110 * it references an interface
111 * @throws ClassNotFoundException if the class or interface
112 * referenced by this type can't be found
113 */
114 public boolean referencesClassExact() throws ClassNotFoundException {
115 JavaClass jc = Repository.lookupClass(class_name);
116 return jc.isClass();
117 }
118
119
120 /**
121 * Return true if this type references an interface,
122 * false if it references a class.
123 * @return true if the type references an interface, false if
124 * it references a class
125 * @throws ClassNotFoundException if the class or interface
126 * referenced by this type can't be found
127 */
128 public boolean referencesInterfaceExact() throws ClassNotFoundException {
129 JavaClass jc = Repository.lookupClass(class_name);
130 return !jc.isClass();
131 }
132
133
134 /**
135 * Return true if this type is a subclass of given ObjectType.
136 * @throws ClassNotFoundException if any of this class's superclasses
137 * can't be found
138 */
139 public boolean subclassOf( ObjectType superclass ) throws ClassNotFoundException {
140 if (this.referencesInterface() || superclass.referencesInterface()) {
141 return false;
142 }
143 return Repository.instanceOf(this.class_name, superclass.class_name);
144 }
145
146
147 /**
148 * Java Virtual Machine Specification edition 2, � 5.4.4 Access Control
149 * @throws ClassNotFoundException if the class referenced by this type
150 * can't be found
151 */
152 public boolean accessibleTo( ObjectType accessor ) throws ClassNotFoundException {
153 JavaClass jc = Repository.lookupClass(class_name);
154 if (jc.isPublic()) {
155 return true;
156 } else {
157 JavaClass acc = Repository.lookupClass(accessor.class_name);
158 return acc.getPackageName().equals(jc.getPackageName());
159 }
160 }
161 }