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.xalan.internal.xsltc.compiler.util;
  23 
  24 import com.sun.org.apache.bcel.internal.generic.ALOAD;
  25 import com.sun.org.apache.bcel.internal.generic.ASTORE;
  26 import com.sun.org.apache.bcel.internal.generic.BranchHandle;
  27 import com.sun.org.apache.bcel.internal.generic.ConstantPoolGen;
  28 import com.sun.org.apache.bcel.internal.generic.GOTO;
  29 import com.sun.org.apache.bcel.internal.generic.IFNULL;
  30 import com.sun.org.apache.bcel.internal.generic.INVOKEVIRTUAL;
  31 import com.sun.org.apache.bcel.internal.generic.Instruction;
  32 import com.sun.org.apache.bcel.internal.generic.InstructionList;
  33 import com.sun.org.apache.bcel.internal.generic.PUSH;
  34 import com.sun.org.apache.xalan.internal.xsltc.compiler.Constants;
  35 import com.sun.org.apache.xalan.internal.utils.ObjectFactory;
  36 
  37 /**
  38  * @author Todd Miller
  39  * @author Santiago Pericas-Geertsen
  40  */
  41 public final class ObjectType extends Type {
  42 
  43     private String _javaClassName = "java.lang.Object";
  44     private Class  _clazz = java.lang.Object.class;
  45 
  46     /**
  47      * Used to represent a Java Class type such is required to support
  48      * non-static java functions.
  49      * @param javaClassName name of the class such as 'com.foo.Processor'
  50      */
  51     protected ObjectType(String javaClassName) {
  52         _javaClassName = javaClassName;
  53 
  54         try {
  55           _clazz = ObjectFactory.findProviderClass(javaClassName, true);
  56         }
  57         catch (ClassNotFoundException e) {
  58           _clazz = null;
  59         }
  60     }
  61 
  62     protected ObjectType(Class clazz) {
  63         _clazz = clazz;
  64         _javaClassName = clazz.getName();
  65     }
  66 
  67     /**
  68      * Must return the same value for all ObjectType instances. This is
  69      * needed in CastExpr to ensure the mapping table is used correctly.
  70      */
  71     public int hashCode() {
  72         return java.lang.Object.class.hashCode();
  73     }
  74 
  75     public boolean equals(Object obj) {
  76         return (obj instanceof ObjectType);
  77     }
  78 
  79     public String getJavaClassName() {
  80         return _javaClassName;
  81     }
  82 
  83     public Class getJavaClass() {
  84         return _clazz;
  85     }
  86 
  87     public String toString() {
  88         return _javaClassName;
  89     }
  90 
  91     public boolean identicalTo(Type other) {
  92         return this == other;
  93     }
  94 
  95     public String toSignature() {
  96         final StringBuffer result = new StringBuffer("L");
  97         result.append(_javaClassName.replace('.', '/')).append(';');
  98         return result.toString();
  99     }
 100 
 101     public com.sun.org.apache.bcel.internal.generic.Type toJCType() {
 102         return Util.getJCRefType(toSignature());
 103     }
 104 
 105     /**
 106      * Translates a void into an object of internal type <code>type</code>.
 107      * This translation is needed when calling external functions
 108      * that return void.
 109      *
 110      * @see     com.sun.org.apache.xalan.internal.xsltc.compiler.util.Type#translateTo
 111      */
 112     public void translateTo(ClassGenerator classGen, MethodGenerator methodGen,
 113                             Type type) {
 114         if (type == Type.String) {
 115             translateTo(classGen, methodGen, (StringType) type);
 116         }
 117         else {
 118             ErrorMsg err = new ErrorMsg(ErrorMsg.DATA_CONVERSION_ERR,
 119                                         toString(), type.toString());
 120             classGen.getParser().reportError(Constants.FATAL, err);
 121         }
 122     }
 123 
 124     /**
 125      * Expects an integer on the stack and pushes its string value by calling
 126      * <code>Integer.toString(int i)</code>.
 127      *
 128      * @see     com.sun.org.apache.xalan.internal.xsltc.compiler.util.Type#translateTo
 129      */
 130     public void translateTo(ClassGenerator classGen, MethodGenerator methodGen,
 131                             StringType type) {
 132         final ConstantPoolGen cpg = classGen.getConstantPool();
 133         final InstructionList il = methodGen.getInstructionList();
 134 
 135         il.append(DUP);
 136         final BranchHandle ifNull = il.append(new IFNULL(null));
 137         il.append(new INVOKEVIRTUAL(cpg.addMethodref(_javaClassName,
 138                                                     "toString",
 139                                                     "()" + STRING_SIG)));
 140         final BranchHandle gotobh = il.append(new GOTO(null));
 141         ifNull.setTarget(il.append(POP));
 142         il.append(new PUSH(cpg, ""));
 143         gotobh.setTarget(il.append(NOP));
 144     }
 145 
 146     /**
 147      * Translates an object of this type to the external (Java) type denoted
 148      * by <code>clazz</code>. This method is used to translate parameters
 149      * when external functions are called.
 150      */
 151     public void translateTo(ClassGenerator classGen, MethodGenerator methodGen,
 152                             Class clazz) {
 153         if (clazz.isAssignableFrom(_clazz))
 154             methodGen.getInstructionList().append(NOP);
 155         else {
 156             ErrorMsg err = new ErrorMsg(ErrorMsg.DATA_CONVERSION_ERR,
 157                                toString(), clazz.getClass().toString());
 158             classGen.getParser().reportError(Constants.FATAL, err);
 159         }
 160     }
 161 
 162     /**
 163      * Translates an external Java type into an Object type
 164      */
 165     public void translateFrom(ClassGenerator classGen,
 166                               MethodGenerator methodGen, Class clazz) {
 167         methodGen.getInstructionList().append(NOP);
 168     }
 169 
 170     public Instruction LOAD(int slot) {
 171         return new ALOAD(slot);
 172     }
 173 
 174     public Instruction STORE(int slot) {
 175         return new ASTORE(slot);
 176     }
 177 }