001/* 002 * Licensed to the Apache Software Foundation (ASF) under one or more 003 * contributor license agreements. See the NOTICE file distributed with 004 * this work for additional information regarding copyright ownership. 005 * The ASF licenses this file to You under the Apache License, Version 2.0 006 * (the "License"); you may not use this file except in compliance with 007 * the License. You may obtain a copy of the License at 008 * 009 * http://www.apache.org/licenses/LICENSE-2.0 010 * 011 * Unless required by applicable law or agreed to in writing, software 012 * distributed under the License is distributed on an "AS IS" BASIS, 013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 014 * See the License for the specific language governing permissions and 015 * limitations under the License. 016 * 017 */ 018package org.apache.bcel.generic; 019 020import org.apache.bcel.Const; 021import org.apache.bcel.Repository; 022import org.apache.bcel.classfile.JavaClass; 023 024/** 025 * Denotes reference such as java.lang.String. 026 * 027 */ 028public class ObjectType extends ReferenceType { 029 030 private final String class_name; // Class name of type 031 032 /** 033 * @since 6.0 034 */ 035 public static ObjectType getInstance(final String class_name) { 036 return new ObjectType(class_name); 037 } 038 039 /** 040 * @param class_name fully qualified class name, e.g. java.lang.String 041 */ 042 public ObjectType(final String class_name) { 043 super(Const.T_REFERENCE, "L" + class_name.replace('.', '/') + ";"); 044 this.class_name = class_name.replace('/', '.'); 045 } 046 047 048 /** @return name of referenced class 049 */ 050 public String getClassName() { 051 return class_name; 052 } 053 054 055 /** @return a hash code value for the object. 056 */ 057 @Override 058 public int hashCode() { 059 return class_name.hashCode(); 060 } 061 062 063 /** @return true if both type objects refer to the same class. 064 */ 065 @Override 066 public boolean equals( final Object type ) { 067 return (type instanceof ObjectType) 068 ? ((ObjectType) type).class_name.equals(class_name) 069 : false; 070 } 071 072 073 /** 074 * If "this" doesn't reference a class, it references an interface 075 * or a non-existant entity. 076 * @deprecated (since 6.0) this method returns an inaccurate result 077 * if the class or interface referenced cannot 078 * be found: use referencesClassExact() instead 079 */ 080 @Deprecated 081 public boolean referencesClass() { 082 try { 083 final JavaClass jc = Repository.lookupClass(class_name); 084 return jc.isClass(); 085 } catch (final ClassNotFoundException e) { 086 return false; 087 } 088 } 089 090 091 /** 092 * If "this" doesn't reference an interface, it references a class 093 * or a non-existant entity. 094 * @deprecated (since 6.0) this method returns an inaccurate result 095 * if the class or interface referenced cannot 096 * be found: use referencesInterfaceExact() instead 097 */ 098 @Deprecated 099 public boolean referencesInterface() { 100 try { 101 final JavaClass jc = Repository.lookupClass(class_name); 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(class_name); 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(class_name); 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.class_name, superclass.class_name); 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(class_name); 157 if (jc.isPublic()) { 158 return true; 159 } 160 final JavaClass acc = Repository.lookupClass(accessor.class_name); 161 return acc.getPackageName().equals(jc.getPackageName()); 162 } 163}