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