1 /*
   2  * reserved comment block
   3  * DO NOT REMOVE OR ALTER!
   4  */
   5 /*
   6  * Licensed to the Apache Software Foundation (ASF) under one or more
   7  * contributor license agreements.  See the NOTICE file distributed with
   8  * this work for additional information regarding copyright ownership.
   9  * The ASF licenses this file to You under the Apache License, Version 2.0
  10  * (the "License"); you may not use this file except in compliance with
  11  * the License.  You may obtain a copy of the License at
  12  *
  13  *      http://www.apache.org/licenses/LICENSE-2.0
  14  *
  15  * Unless required by applicable law or agreed to in writing, software
  16  * distributed under the License is distributed on an "AS IS" BASIS,
  17  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  18  * See the License for the specific language governing permissions and
  19  * limitations under the License.
  20  */
  21 
  22 package com.sun.org.apache.bcel.internal.generic;
  23 
  24 import com.sun.org.apache.bcel.internal.Const;
  25 import com.sun.org.apache.bcel.internal.Repository;
  26 import com.sun.org.apache.bcel.internal.classfile.JavaClass;
  27 
  28 /**
  29  * Denotes reference such as java.lang.String.
  30  *
  31  * @version $Id: ObjectType.java 1749603 2016-06-21 20:50:19Z ggregory $
  32  */
  33 public class ObjectType extends ReferenceType {
  34 
  35     private final String class_name; // Class name of type
  36 
  37     /**
  38      * @since 6.0
  39      */
  40     public static ObjectType getInstance(final String class_name) {
  41         return new ObjectType(class_name);
  42     }
  43 
  44     /**
  45      * @param class_name fully qualified class name, e.g. java.lang.String
  46      */
  47     public ObjectType(final String class_name) {
  48         super(Const.T_REFERENCE, "L" + class_name.replace('.', '/') + ";");
  49         this.class_name = class_name.replace('/', '.');
  50     }
  51 
  52 
  53     /** @return name of referenced class
  54      */
  55     public String getClassName() {
  56         return class_name;
  57     }
  58 
  59 
  60     /** @return a hash code value for the object.
  61      */
  62     @Override
  63     public int hashCode() {
  64         return class_name.hashCode();
  65     }
  66 
  67 
  68     /** @return true if both type objects refer to the same class.
  69      */
  70     @Override
  71     public boolean equals( final Object type ) {
  72         return (type instanceof ObjectType)
  73                 ? ((ObjectType) type).class_name.equals(class_name)
  74                 : false;
  75     }
  76 
  77 
  78     /**
  79      * If "this" doesn't reference a class, it references an interface
  80      * or a non-existant entity.
  81      * @deprecated (since 6.0) this method returns an inaccurate result
  82      *   if the class or interface referenced cannot
  83      *   be found: use referencesClassExact() instead
  84      */
  85     @Deprecated
  86     public boolean referencesClass() {
  87         try {
  88             final JavaClass jc = Repository.lookupClass(class_name);
  89             return jc.isClass();
  90         } catch (final ClassNotFoundException e) {
  91             return false;
  92         }
  93     }
  94 
  95 
  96     /**
  97      * If "this" doesn't reference an interface, it references a class
  98      * or a non-existant entity.
  99      * @deprecated (since 6.0) this method returns an inaccurate result
 100      *   if the class or interface referenced cannot
 101      *   be found: use referencesInterfaceExact() instead
 102      */
 103     @Deprecated
 104     public boolean referencesInterface() {
 105         try {
 106             final JavaClass jc = Repository.lookupClass(class_name);
 107             return !jc.isClass();
 108         } catch (final ClassNotFoundException e) {
 109             return false;
 110         }
 111     }
 112 
 113 
 114     /**
 115      * Return true if this type references a class,
 116      * false if it references an interface.
 117      * @return true if the type references a class, false if
 118      *   it references an interface
 119      * @throws ClassNotFoundException if the class or interface
 120      *   referenced by this type can't be found
 121      */
 122     public boolean referencesClassExact() throws ClassNotFoundException {
 123         final JavaClass jc = Repository.lookupClass(class_name);
 124         return jc.isClass();
 125     }
 126 
 127 
 128     /**
 129      * Return true if this type references an interface,
 130      * false if it references a class.
 131      * @return true if the type references an interface, false if
 132      *   it references a class
 133      * @throws ClassNotFoundException if the class or interface
 134      *   referenced by this type can't be found
 135      */
 136     public boolean referencesInterfaceExact() throws ClassNotFoundException {
 137         final JavaClass jc = Repository.lookupClass(class_name);
 138         return !jc.isClass();
 139     }
 140 
 141 
 142     /**
 143      * Return true if this type is a subclass of given ObjectType.
 144      * @throws ClassNotFoundException if any of this class's superclasses
 145      *  can't be found
 146      */
 147     public boolean subclassOf( final ObjectType superclass ) throws ClassNotFoundException {
 148         if (this.referencesInterfaceExact() || superclass.referencesInterfaceExact()) {
 149             return false;
 150         }
 151         return Repository.instanceOf(this.class_name, superclass.class_name);
 152     }
 153 
 154 
 155     /**
 156      * Java Virtual Machine Specification edition 2,  5.4.4 Access Control
 157      * @throws ClassNotFoundException if the class referenced by this type
 158      *   can't be found
 159      */
 160     public boolean accessibleTo( final ObjectType accessor ) throws ClassNotFoundException {
 161         final JavaClass jc = Repository.lookupClass(class_name);
 162         if (jc.isPublic()) {
 163             return true;
 164         }
 165         final JavaClass acc = Repository.lookupClass(accessor.class_name);
 166         return acc.getPackageName().equals(jc.getPackageName());
 167     }
 168 }