1 /*
   2  * reserved comment block
   3  * DO NOT REMOVE OR ALTER!
   4  */
   5 /*
   6  * Copyright 2001-2004 The Apache Software Foundation.
   7  *
   8  * Licensed under the Apache License, Version 2.0 (the "License");
   9  * you may not use this file except in compliance with the License.
  10  * You may obtain a copy of the License at
  11  *
  12  *     http://www.apache.org/licenses/LICENSE-2.0
  13  *
  14  * Unless required by applicable law or agreed to in writing, software
  15  * distributed under the License is distributed on an "AS IS" BASIS,
  16  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  17  * See the License for the specific language governing permissions and
  18  * limitations under the License.
  19  */
  20 /*
  21  * $Id: ObjectType.java,v 1.2.4.1 2005/09/12 11:45:54 pvedula Exp $
  22  */
  23 
  24 package com.sun.org.apache.xalan.internal.xsltc.compiler.util;
  25 
  26 import com.sun.org.apache.bcel.internal.generic.ALOAD;
  27 import com.sun.org.apache.bcel.internal.generic.ASTORE;
  28 import com.sun.org.apache.bcel.internal.generic.BranchHandle;
  29 import com.sun.org.apache.bcel.internal.generic.ConstantPoolGen;
  30 import com.sun.org.apache.bcel.internal.generic.GOTO;
  31 import com.sun.org.apache.bcel.internal.generic.IFNULL;
  32 import com.sun.org.apache.bcel.internal.generic.INVOKEVIRTUAL;
  33 import com.sun.org.apache.bcel.internal.generic.Instruction;
  34 import com.sun.org.apache.bcel.internal.generic.InstructionList;
  35 import com.sun.org.apache.bcel.internal.generic.PUSH;
  36 import com.sun.org.apache.xalan.internal.xsltc.compiler.Constants;
  37 import com.sun.org.apache.xalan.internal.utils.ObjectFactory;
  38 
  39 /**
  40  * @author Todd Miller
  41  * @author Santiago Pericas-Geertsen
  42  */
  43 public final class ObjectType extends Type {
  44 
  45     private String _javaClassName = "java.lang.Object";
  46     private Class  _clazz = java.lang.Object.class;
  47 
  48     /**
  49      * Used to represent a Java Class type such is required to support
  50      * non-static java functions.
  51      * @param javaClassName name of the class such as 'com.foo.Processor'
  52      */
  53     protected ObjectType(String javaClassName) {
  54         _javaClassName = javaClassName;
  55 
  56         try {
  57           _clazz = ObjectFactory.findProviderClass(javaClassName, true);
  58         }
  59         catch (ClassNotFoundException e) {
  60           _clazz = null;
  61         }
  62     }
  63 
  64     protected ObjectType(Class clazz) {
  65         _clazz = clazz;
  66         _javaClassName = clazz.getName();
  67     }
  68 
  69     /**
  70      * Must return the same value for all ObjectType instances. This is
  71      * needed in CastExpr to ensure the mapping table is used correctly.
  72      */
  73     public int hashCode() {
  74         return java.lang.Object.class.hashCode();
  75     }
  76 
  77     public boolean equals(Object obj) {
  78         return (obj instanceof ObjectType);
  79     }
  80 
  81     public String getJavaClassName() {
  82         return _javaClassName;
  83     }
  84 
  85     public Class getJavaClass() {
  86         return _clazz;
  87     }
  88 
  89     public String toString() {
  90         return _javaClassName;
  91     }
  92 
  93     public boolean identicalTo(Type other) {
  94         return this == other;
  95     }
  96 
  97     public String toSignature() {
  98         final StringBuffer result = new StringBuffer("L");
  99         result.append(_javaClassName.replace('.', '/')).append(';');
 100         return result.toString();
 101     }
 102 
 103     public com.sun.org.apache.bcel.internal.generic.Type toJCType() {
 104         return Util.getJCRefType(toSignature());
 105     }
 106 
 107     /**
 108      * Translates a void into an object of internal type <code>type</code>.
 109      * This translation is needed when calling external functions
 110      * that return void.
 111      *
 112      * @see     com.sun.org.apache.xalan.internal.xsltc.compiler.util.Type#translateTo
 113      */
 114     public void translateTo(ClassGenerator classGen, MethodGenerator methodGen,
 115                             Type type) {
 116         if (type == Type.String) {
 117             translateTo(classGen, methodGen, (StringType) type);
 118         }
 119         else {
 120             ErrorMsg err = new ErrorMsg(ErrorMsg.DATA_CONVERSION_ERR,
 121                                         toString(), type.toString());
 122             classGen.getParser().reportError(Constants.FATAL, err);
 123         }
 124     }
 125 
 126     /**
 127      * Expects an integer on the stack and pushes its string value by calling
 128      * <code>Integer.toString(int i)</code>.
 129      *
 130      * @see     com.sun.org.apache.xalan.internal.xsltc.compiler.util.Type#translateTo
 131      */
 132     public void translateTo(ClassGenerator classGen, MethodGenerator methodGen,
 133                             StringType type) {
 134         final ConstantPoolGen cpg = classGen.getConstantPool();
 135         final InstructionList il = methodGen.getInstructionList();
 136 
 137         il.append(DUP);
 138         final BranchHandle ifNull = il.append(new IFNULL(null));
 139         il.append(new INVOKEVIRTUAL(cpg.addMethodref(_javaClassName,
 140                                                     "toString",
 141                                                     "()" + STRING_SIG)));
 142         final BranchHandle gotobh = il.append(new GOTO(null));
 143         ifNull.setTarget(il.append(POP));
 144         il.append(new PUSH(cpg, ""));
 145         gotobh.setTarget(il.append(NOP));
 146     }
 147 
 148     /**
 149      * Translates an object of this type to the external (Java) type denoted
 150      * by <code>clazz</code>. This method is used to translate parameters
 151      * when external functions are called.
 152      */
 153     public void translateTo(ClassGenerator classGen, MethodGenerator methodGen,
 154                             Class clazz) {
 155         if (clazz.isAssignableFrom(_clazz))
 156             methodGen.getInstructionList().append(NOP);
 157         else {
 158             ErrorMsg err = new ErrorMsg(ErrorMsg.DATA_CONVERSION_ERR,
 159                                toString(), clazz.getClass().toString());
 160             classGen.getParser().reportError(Constants.FATAL, err);
 161         }
 162     }
 163 
 164     /**
 165      * Translates an external Java type into an Object type
 166      */
 167     public void translateFrom(ClassGenerator classGen,
 168                               MethodGenerator methodGen, Class clazz) {
 169         methodGen.getInstructionList().append(NOP);
 170     }
 171 
 172     public Instruction LOAD(int slot) {
 173         return new ALOAD(slot);
 174     }
 175 
 176     public Instruction STORE(int slot) {
 177         return new ASTORE(slot);
 178     }
 179 }