diff options
Diffstat (limited to 'src/share/classes/com/sun/org/apache/xalan/internal/xsltc/compiler/Copy.java')
-rw-r--r-- | src/share/classes/com/sun/org/apache/xalan/internal/xsltc/compiler/Copy.java | 159 |
1 files changed, 159 insertions, 0 deletions
diff --git a/src/share/classes/com/sun/org/apache/xalan/internal/xsltc/compiler/Copy.java b/src/share/classes/com/sun/org/apache/xalan/internal/xsltc/compiler/Copy.java new file mode 100644 index 0000000..860efe1 --- /dev/null +++ b/src/share/classes/com/sun/org/apache/xalan/internal/xsltc/compiler/Copy.java @@ -0,0 +1,159 @@ +/* + * reserved comment block + * DO NOT REMOVE OR ALTER! + */ +/* + * Copyright 2001-2004 The Apache Software Foundation. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * $Id: Copy.java,v 1.2.4.1 2005/09/01 12:14:32 pvedula Exp $ + */ + +package com.sun.org.apache.xalan.internal.xsltc.compiler; + +import com.sun.org.apache.bcel.internal.generic.ALOAD; +import com.sun.org.apache.bcel.internal.generic.ASTORE; +import com.sun.org.apache.bcel.internal.generic.BranchHandle; +import com.sun.org.apache.bcel.internal.generic.ConstantPoolGen; +import com.sun.org.apache.bcel.internal.generic.IFEQ; +import com.sun.org.apache.bcel.internal.generic.IFNULL; +import com.sun.org.apache.bcel.internal.generic.ILOAD; +import com.sun.org.apache.bcel.internal.generic.INVOKEINTERFACE; +import com.sun.org.apache.bcel.internal.generic.INVOKEVIRTUAL; +import com.sun.org.apache.bcel.internal.generic.ISTORE; +import com.sun.org.apache.bcel.internal.generic.InstructionHandle; +import com.sun.org.apache.bcel.internal.generic.InstructionList; +import com.sun.org.apache.bcel.internal.generic.LocalVariableGen; +import com.sun.org.apache.xalan.internal.xsltc.compiler.util.ClassGenerator; +import com.sun.org.apache.xalan.internal.xsltc.compiler.util.ErrorMsg; +import com.sun.org.apache.xalan.internal.xsltc.compiler.util.MethodGenerator; +import com.sun.org.apache.xalan.internal.xsltc.compiler.util.Type; +import com.sun.org.apache.xalan.internal.xsltc.compiler.util.TypeCheckError; +import com.sun.org.apache.xalan.internal.xsltc.compiler.util.Util; + +/** + * @author Jacek Ambroziak + * @author Santiago Pericas-Geertsen + */ +final class Copy extends Instruction { + private UseAttributeSets _useSets; + + public void parseContents(Parser parser) { + final String useSets = getAttribute("use-attribute-sets"); + if (useSets.length() > 0) { + if (!Util.isValidQNames(useSets)) { + ErrorMsg err = new ErrorMsg(ErrorMsg.INVALID_QNAME_ERR, useSets, this); + parser.reportError(Constants.ERROR, err); + } + _useSets = new UseAttributeSets(useSets, parser); + } + parseChildren(parser); + } + + public void display(int indent) { + indent(indent); + Util.println("Copy"); + indent(indent + IndentIncrement); + displayContents(indent + IndentIncrement); + } + + public Type typeCheck(SymbolTable stable) throws TypeCheckError { + if (_useSets != null) { + _useSets.typeCheck(stable); + } + typeCheckContents(stable); + return Type.Void; + } + + public void translate(ClassGenerator classGen, MethodGenerator methodGen) { + final ConstantPoolGen cpg = classGen.getConstantPool(); + final InstructionList il = methodGen.getInstructionList(); + + final LocalVariableGen name = + methodGen.addLocalVariable2("name", + Util.getJCRefType(STRING_SIG), + il.getEnd()); + final LocalVariableGen length = + methodGen.addLocalVariable2("length", + Util.getJCRefType("I"), + il.getEnd()); + + // Get the name of the node to copy and save for later + il.append(methodGen.loadDOM()); + il.append(methodGen.loadCurrentNode()); + il.append(methodGen.loadHandler()); + final int cpy = cpg.addInterfaceMethodref(DOM_INTF, + "shallowCopy", + "(" + + NODE_SIG + + TRANSLET_OUTPUT_SIG + + ")" + STRING_SIG); + il.append(new INVOKEINTERFACE(cpy, 3)); + il.append(DUP); + il.append(new ASTORE(name.getIndex())); + final BranchHandle ifBlock1 = il.append(new IFNULL(null)); + + // Get the length of the node name and save for later + il.append(new ALOAD(name.getIndex())); + final int lengthMethod = cpg.addMethodref(STRING_CLASS,"length","()I"); + il.append(new INVOKEVIRTUAL(lengthMethod)); + il.append(DUP); + il.append(new ISTORE(length.getIndex())); + + // Ignore attribute sets if current node is ROOT. DOM.shallowCopy() + // returns "" for ROOT, so skip attribute sets if length == 0 + final BranchHandle ifBlock4 = il.append(new IFEQ(null)); + + // Copy in attribute sets if specified + if (_useSets != null) { + // If the parent of this element will result in an element being + // output then we know that it is safe to copy out the attributes + final SyntaxTreeNode parent = getParent(); + if ((parent instanceof LiteralElement) || + (parent instanceof LiteralElement)) { + _useSets.translate(classGen, methodGen); + } + // If not we have to check to see if the copy will result in an + // element being output. + else { + // check if element; if not skip to translate body + il.append(new ILOAD(length.getIndex())); + final BranchHandle ifBlock2 = il.append(new IFEQ(null)); + // length != 0 -> element -> do attribute sets + _useSets.translate(classGen, methodGen); + // not an element; root + ifBlock2.setTarget(il.append(NOP)); + } + } + + // Instantiate body of xsl:copy + ifBlock4.setTarget(il.append(NOP)); + translateContents(classGen, methodGen); + + // Call the output handler's endElement() if we copied an element + // (The DOM.shallowCopy() method calls startElement().) + il.append(new ILOAD(length.getIndex())); + final BranchHandle ifBlock3 = il.append(new IFEQ(null)); + il.append(methodGen.loadHandler()); + il.append(new ALOAD(name.getIndex())); + il.append(methodGen.endElement()); + + final InstructionHandle end = il.append(NOP); + ifBlock1.setTarget(end); + ifBlock3.setTarget(end); + methodGen.removeLocalVariable(name); + methodGen.removeLocalVariable(length); + } +} |