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.Constants;
  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  * @author  <A HREF="mailto:markus.dahm@berlin.de">M. Dahm</A>
  32  */
  33 public final class ObjectType extends ReferenceType {
  34   private String class_name; // Class name of type
  35 
  36   /**
  37    * @param class_name fully qualified class name, e.g. java.lang.String
  38    */
  39   public ObjectType(String class_name) {
  40     super(Constants.T_REFERENCE, "L" + class_name.replace('.', '/') + ";");
  41     this.class_name = class_name.replace('/', '.');
  42   }
  43 
  44   /** @return name of referenced class
  45    */
  46   public String getClassName() { return class_name; }
  47 
  48   /** @return a hash code value for the object.
  49    */
  50   public int hashCode()  { return class_name.hashCode(); }
  51 
  52   /** @return true if both type objects refer to the same class.
  53    */
  54   public boolean equals(Object type) {
  55     return (type instanceof ObjectType)?
  56       ((ObjectType)type).class_name.equals(class_name) : false;
  57   }
  58 
  59   /**
  60    * If "this" doesn't reference a class, it references an interface
  61    * or a non-existant entity.
  62    */
  63   public boolean referencesClass(){
  64     JavaClass jc = Repository.lookupClass(class_name);
  65     if (jc == null)
  66       return false;
  67     else
  68       return jc.isClass();
  69   }
  70 
  71   /**
  72    * If "this" doesn't reference an interface, it references a class
  73    * or a non-existant entity.
  74    */
  75   public boolean referencesInterface(){
  76     JavaClass jc = Repository.lookupClass(class_name);
  77     if (jc == null)
  78       return false;
  79     else
  80       return !jc.isClass();
  81   }
  82 
  83   public boolean subclassOf(ObjectType superclass){
  84     if (this.referencesInterface() || superclass.referencesInterface())
  85       return false;
  86 
  87     return Repository.instanceOf(this.class_name, superclass.class_name);
  88   }
  89 
  90   /**
  91    * Java Virtual Machine Specification edition 2, 5.4.4 Access Control
  92    */
  93   public boolean accessibleTo(ObjectType accessor) {
  94     JavaClass jc = Repository.lookupClass(class_name);
  95 
  96     if(jc.isPublic()) {
  97       return true;
  98     } else {
  99       JavaClass acc = Repository.lookupClass(accessor.class_name);
 100       return acc.getPackageName().equals(jc.getPackageName());
 101     }
 102   }
 103 }