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; 023import org.apache.bcel.classfile.Utility; 024 025/** 026 * Denotes reference such as java.lang.String. 027 * 028 */ 029public class ObjectType extends ReferenceType { 030 031 /** 032 * @since 6.0 033 */ 034 public static ObjectType getInstance(final String className) { 035 return new ObjectType(className); 036 } 037 038 private final String className; // Class name of type 039 040 /** 041 * @param className fully qualified class name, e.g. java.lang.String 042 */ 043 public ObjectType(final String className) { 044 super(Const.T_REFERENCE, "L" + className.replace('.', '/') + ";"); 045 this.className = Utility.pathToPackage(className); 046 } 047 048 /** 049 * Java Virtual Machine Specification edition 2, � 5.4.4 Access Control 050 * 051 * @throws ClassNotFoundException if the class referenced by this type can't be found 052 */ 053 public boolean accessibleTo(final ObjectType accessor) throws ClassNotFoundException { 054 final JavaClass jc = Repository.lookupClass(className); 055 if (jc.isPublic()) { 056 return true; 057 } 058 final JavaClass acc = Repository.lookupClass(accessor.className); 059 return acc.getPackageName().equals(jc.getPackageName()); 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 && ((ObjectType) type).className.equals(className); 068 } 069 070 /** 071 * @return name of referenced class 072 */ 073 public String getClassName() { 074 return className; 075 } 076 077 /** 078 * @return a hash code value for the object. 079 */ 080 @Override 081 public int hashCode() { 082 return className.hashCode(); 083 } 084 085 /** 086 * If "this" doesn't reference a class, it references an interface or a non-existant entity. 087 * 088 * @deprecated (since 6.0) this method returns an inaccurate result if the class or interface referenced cannot be 089 * found: use referencesClassExact() instead 090 */ 091 @Deprecated 092 public boolean referencesClass() { 093 try { 094 final JavaClass jc = Repository.lookupClass(className); 095 return jc.isClass(); 096 } catch (final ClassNotFoundException e) { 097 return false; 098 } 099 } 100 101 /** 102 * Return true if this type references a class, false if it references an interface. 103 * 104 * @return true if the type references a class, false if it references an interface 105 * @throws ClassNotFoundException if the class or interface referenced by this type can't be found 106 */ 107 public boolean referencesClassExact() throws ClassNotFoundException { 108 final JavaClass jc = Repository.lookupClass(className); 109 return jc.isClass(); 110 } 111 112 /** 113 * If "this" doesn't reference an interface, it references a class or a non-existant entity. 114 * 115 * @deprecated (since 6.0) this method returns an inaccurate result if the class or interface referenced cannot be 116 * found: use referencesInterfaceExact() instead 117 */ 118 @Deprecated 119 public boolean referencesInterface() { 120 try { 121 final JavaClass jc = Repository.lookupClass(className); 122 return !jc.isClass(); 123 } catch (final ClassNotFoundException e) { 124 return false; 125 } 126 } 127 128 /** 129 * Return true if this type references an interface, false if it references a class. 130 * 131 * @return true if the type references an interface, false if it references a class 132 * @throws ClassNotFoundException if the class or interface referenced by this type can't be found 133 */ 134 public boolean referencesInterfaceExact() throws ClassNotFoundException { 135 final JavaClass jc = Repository.lookupClass(className); 136 return !jc.isClass(); 137 } 138 139 /** 140 * Return true if this type is a subclass of given ObjectType. 141 * 142 * @throws ClassNotFoundException if any of this class's superclasses can't be found 143 */ 144 public boolean subclassOf(final ObjectType superclass) throws ClassNotFoundException { 145 if (this.referencesInterfaceExact() || superclass.referencesInterfaceExact()) { 146 return false; 147 } 148 return Repository.instanceOf(this.className, superclass.className); 149 } 150}