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; 23 24 import com.sun.org.apache.bcel.internal.generic.ConstantPoolGen; 25 import com.sun.org.apache.bcel.internal.generic.INVOKEINTERFACE; 26 import com.sun.org.apache.bcel.internal.generic.INVOKESTATIC; 27 import com.sun.org.apache.bcel.internal.generic.INVOKEVIRTUAL; 28 import com.sun.org.apache.bcel.internal.generic.InstructionList; 29 import com.sun.org.apache.xalan.internal.xsltc.compiler.util.ClassGenerator; 30 import com.sun.org.apache.xalan.internal.xsltc.compiler.util.ErrorMsg; 31 import com.sun.org.apache.xalan.internal.xsltc.compiler.util.MethodGenerator; 32 import com.sun.org.apache.xalan.internal.xsltc.compiler.util.NodeSetType; 33 import com.sun.org.apache.xalan.internal.xsltc.compiler.util.NodeType; 34 import com.sun.org.apache.xalan.internal.xsltc.compiler.util.ReferenceType; 35 import com.sun.org.apache.xalan.internal.xsltc.compiler.util.ResultTreeType; 36 import com.sun.org.apache.xalan.internal.xsltc.compiler.util.Type; 37 import com.sun.org.apache.xalan.internal.xsltc.compiler.util.TypeCheckError; 38 import com.sun.org.apache.xalan.internal.xsltc.compiler.util.Util; 39 40 /** 41 * @author Jacek Ambroziak 42 * @author Santiago Pericas-Geertsen 43 */ 44 final class CopyOf extends Instruction { 45 private Expression _select; 46 47 public void display(int indent) { 48 indent(indent); 49 Util.println("CopyOf"); 50 indent(indent + IndentIncrement); 51 Util.println("select " + _select.toString()); 52 } 53 54 public void parseContents(Parser parser) { 55 _select = parser.parseExpression(this, "select", null); 56 // make sure required attribute(s) have been set 57 if (_select.isDummy()) { 58 reportError(this, parser, ErrorMsg.REQUIRED_ATTR_ERR, "select"); 59 return; 60 } 61 } 62 63 public Type typeCheck(SymbolTable stable) throws TypeCheckError { 64 final Type tselect = _select.typeCheck(stable); 65 if (tselect instanceof NodeType || 66 tselect instanceof NodeSetType || 67 tselect instanceof ReferenceType || 68 tselect instanceof ResultTreeType) { 69 // falls through 70 } 71 else { 72 _select = new CastExpr(_select, Type.String); 73 } 74 return Type.Void; 75 } 76 77 public void translate(ClassGenerator classGen, MethodGenerator methodGen) { 78 final ConstantPoolGen cpg = classGen.getConstantPool(); 79 final InstructionList il = methodGen.getInstructionList(); 80 final Type tselect = _select.getType(); 81 82 final String CPY1_SIG = "("+NODE_ITERATOR_SIG+TRANSLET_OUTPUT_SIG+")V"; 83 final int cpy1 = cpg.addInterfaceMethodref(DOM_INTF, "copy", CPY1_SIG); 84 85 final String CPY2_SIG = "("+NODE_SIG+TRANSLET_OUTPUT_SIG+")V"; 86 final int cpy2 = cpg.addInterfaceMethodref(DOM_INTF, "copy", CPY2_SIG); 87 88 final String getDoc_SIG = "()"+NODE_SIG; 89 final int getDoc = cpg.addInterfaceMethodref(DOM_INTF, "getDocument", getDoc_SIG); 90 91 92 if (tselect instanceof NodeSetType) { 93 il.append(methodGen.loadDOM()); 94 95 // push NodeIterator 96 _select.translate(classGen, methodGen); 97 _select.startIterator(classGen, methodGen); 98 99 // 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 }