001 /* 002 * Licensed to the Apache Software Foundation (ASF) under one 003 * or more contributor license agreements. See the NOTICE file 004 * distributed with this work for additional information 005 * regarding copyright ownership. The ASF licenses this file 006 * to you under the Apache License, Version 2.0 (the "License"); 007 * you may not use this file except in compliance with the License. 008 * You may obtain a copy of the License at 009 * 010 * http://www.apache.org/licenses/LICENSE-2.0 011 * 012 * Unless required by applicable law or agreed to in writing, software 013 * distributed under the License is distributed on an "AS IS" BASIS, 014 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 015 * See the License for the specific language governing permissions and 016 * limitations under the License. 017 */ 018 /* 019 * $Id: CopyOf.java 468650 2006-10-28 07:03:30Z minchau $ 020 */ 021 022 package org.apache.xalan.xsltc.compiler; 023 024 import org.apache.bcel.generic.ConstantPoolGen; 025 import org.apache.bcel.generic.INVOKEINTERFACE; 026 import org.apache.bcel.generic.INVOKESTATIC; 027 import org.apache.bcel.generic.INVOKEVIRTUAL; 028 import org.apache.bcel.generic.InstructionList; 029 import org.apache.xalan.xsltc.compiler.util.ClassGenerator; 030 import org.apache.xalan.xsltc.compiler.util.ErrorMsg; 031 import org.apache.xalan.xsltc.compiler.util.MethodGenerator; 032 import org.apache.xalan.xsltc.compiler.util.NodeSetType; 033 import org.apache.xalan.xsltc.compiler.util.NodeType; 034 import org.apache.xalan.xsltc.compiler.util.ReferenceType; 035 import org.apache.xalan.xsltc.compiler.util.ResultTreeType; 036 import org.apache.xalan.xsltc.compiler.util.Type; 037 import org.apache.xalan.xsltc.compiler.util.TypeCheckError; 038 import org.apache.xalan.xsltc.compiler.util.Util; 039 040 /** 041 * @author Jacek Ambroziak 042 * @author Santiago Pericas-Geertsen 043 */ 044 final class CopyOf extends Instruction { 045 private Expression _select; 046 047 public void display(int indent) { 048 indent(indent); 049 Util.println("CopyOf"); 050 indent(indent + IndentIncrement); 051 Util.println("select " + _select.toString()); 052 } 053 054 public void parseContents(Parser parser) { 055 _select = parser.parseExpression(this, "select", null); 056 // make sure required attribute(s) have been set 057 if (_select.isDummy()) { 058 reportError(this, parser, ErrorMsg.REQUIRED_ATTR_ERR, "select"); 059 return; 060 } 061 } 062 063 public Type typeCheck(SymbolTable stable) throws TypeCheckError { 064 final Type tselect = _select.typeCheck(stable); 065 if (tselect instanceof NodeType || 066 tselect instanceof NodeSetType || 067 tselect instanceof ReferenceType || 068 tselect instanceof ResultTreeType) { 069 // falls through 070 } 071 else { 072 _select = new CastExpr(_select, Type.String); 073 } 074 return Type.Void; 075 } 076 077 public void translate(ClassGenerator classGen, MethodGenerator methodGen) { 078 final ConstantPoolGen cpg = classGen.getConstantPool(); 079 final InstructionList il = methodGen.getInstructionList(); 080 final Type tselect = _select.getType(); 081 082 final String CPY1_SIG = "("+NODE_ITERATOR_SIG+TRANSLET_OUTPUT_SIG+")V"; 083 final int cpy1 = cpg.addInterfaceMethodref(DOM_INTF, "copy", CPY1_SIG); 084 085 final String CPY2_SIG = "("+NODE_SIG+TRANSLET_OUTPUT_SIG+")V"; 086 final int cpy2 = cpg.addInterfaceMethodref(DOM_INTF, "copy", CPY2_SIG); 087 088 final String getDoc_SIG = "()"+NODE_SIG; 089 final int getDoc = cpg.addInterfaceMethodref(DOM_INTF, "getDocument", getDoc_SIG); 090 091 092 if (tselect instanceof NodeSetType) { 093 il.append(methodGen.loadDOM()); 094 095 // push NodeIterator 096 _select.translate(classGen, methodGen); 097 _select.startIterator(classGen, methodGen); 098 099 // call copy from the DOM 'library' 100 il.append(methodGen.loadHandler()); 101 il.append(new INVOKEINTERFACE(cpy1, 3)); 102 } 103 else if (tselect instanceof NodeType) { 104 il.append(methodGen.loadDOM()); 105 _select.translate(classGen, methodGen); 106 il.append(methodGen.loadHandler()); 107 il.append(new INVOKEINTERFACE(cpy2, 3)); 108 } 109 else if (tselect instanceof ResultTreeType) { 110 _select.translate(classGen, methodGen); 111 // We want the whole tree, so we start with the root node 112 il.append(DUP); //need a pointer to the DOM ; 113 il.append(new INVOKEINTERFACE(getDoc,1)); //ICONST_0); 114 il.append(methodGen.loadHandler()); 115 il.append(new INVOKEINTERFACE(cpy2, 3)); 116 } 117 else if (tselect instanceof ReferenceType) { 118 _select.translate(classGen, methodGen); 119 il.append(methodGen.loadHandler()); 120 il.append(methodGen.loadCurrentNode()); 121 il.append(methodGen.loadDOM()); 122 final int copy = cpg.addMethodref(BASIS_LIBRARY_CLASS, "copy", 123 "(" 124 + OBJECT_SIG 125 + TRANSLET_OUTPUT_SIG 126 + NODE_SIG 127 + DOM_INTF_SIG 128 + ")V"); 129 il.append(new INVOKESTATIC(copy)); 130 } 131 else { 132 il.append(classGen.loadTranslet()); 133 _select.translate(classGen, methodGen); 134 il.append(methodGen.loadHandler()); 135 il.append(new INVOKEVIRTUAL(cpg.addMethodref(TRANSLET_CLASS, 136 CHARACTERSW, 137 CHARACTERSW_SIG))); 138 } 139 140 } 141 }