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