jaxp/src/com/sun/org/apache/xalan/internal/xsltc/compiler/Copy.java
changeset 12457 c348e06f0e82
parent 6 7f561c08de6b
child 12458 d601e4bba306
equal deleted inserted replaced
12324:1d7e6da6adc8 12457:c348e06f0e82
       
     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: Copy.java,v 1.2.4.1 2005/09/01 12:14:32 pvedula Exp $
       
    22  */
       
    23 
       
    24 package com.sun.org.apache.xalan.internal.xsltc.compiler;
       
    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.IFEQ;
       
    31 import com.sun.org.apache.bcel.internal.generic.IFNULL;
       
    32 import com.sun.org.apache.bcel.internal.generic.ILOAD;
       
    33 import com.sun.org.apache.bcel.internal.generic.INVOKEINTERFACE;
       
    34 import com.sun.org.apache.bcel.internal.generic.INVOKEVIRTUAL;
       
    35 import com.sun.org.apache.bcel.internal.generic.ISTORE;
       
    36 import com.sun.org.apache.bcel.internal.generic.InstructionHandle;
       
    37 import com.sun.org.apache.bcel.internal.generic.InstructionList;
       
    38 import com.sun.org.apache.bcel.internal.generic.LocalVariableGen;
       
    39 import com.sun.org.apache.xalan.internal.xsltc.compiler.util.ClassGenerator;
       
    40 import com.sun.org.apache.xalan.internal.xsltc.compiler.util.ErrorMsg;
       
    41 import com.sun.org.apache.xalan.internal.xsltc.compiler.util.MethodGenerator;
       
    42 import com.sun.org.apache.xalan.internal.xsltc.compiler.util.Type;
       
    43 import com.sun.org.apache.xalan.internal.xsltc.compiler.util.TypeCheckError;
       
    44 import com.sun.org.apache.xalan.internal.xsltc.compiler.util.Util;
       
    45 
       
    46 /**
       
    47  * @author Jacek Ambroziak
       
    48  * @author Santiago Pericas-Geertsen
       
    49  */
       
    50 final class Copy extends Instruction {
       
    51     private UseAttributeSets _useSets;
       
    52 
       
    53     public void parseContents(Parser parser) {
       
    54         final String useSets = getAttribute("use-attribute-sets");
       
    55         if (useSets.length() > 0) {
       
    56             if (!Util.isValidQNames(useSets)) {
       
    57                 ErrorMsg err = new ErrorMsg(ErrorMsg.INVALID_QNAME_ERR, useSets, this);
       
    58                 parser.reportError(Constants.ERROR, err);
       
    59             }
       
    60             _useSets = new UseAttributeSets(useSets, parser);
       
    61         }
       
    62         parseChildren(parser);
       
    63     }
       
    64 
       
    65     public void display(int indent) {
       
    66         indent(indent);
       
    67         Util.println("Copy");
       
    68         indent(indent + IndentIncrement);
       
    69         displayContents(indent + IndentIncrement);
       
    70     }
       
    71 
       
    72     public Type typeCheck(SymbolTable stable) throws TypeCheckError {
       
    73         if (_useSets != null) {
       
    74             _useSets.typeCheck(stable);
       
    75         }
       
    76         typeCheckContents(stable);
       
    77         return Type.Void;
       
    78     }
       
    79 
       
    80     public void translate(ClassGenerator classGen, MethodGenerator methodGen) {
       
    81         final ConstantPoolGen cpg = classGen.getConstantPool();
       
    82         final InstructionList il = methodGen.getInstructionList();
       
    83 
       
    84         final LocalVariableGen name =
       
    85             methodGen.addLocalVariable2("name",
       
    86                                         Util.getJCRefType(STRING_SIG),
       
    87                                         il.getEnd());
       
    88         final LocalVariableGen length =
       
    89             methodGen.addLocalVariable2("length",
       
    90                                         Util.getJCRefType("I"),
       
    91                                         il.getEnd());
       
    92 
       
    93         // Get the name of the node to copy and save for later
       
    94         il.append(methodGen.loadDOM());
       
    95         il.append(methodGen.loadCurrentNode());
       
    96         il.append(methodGen.loadHandler());
       
    97         final int cpy = cpg.addInterfaceMethodref(DOM_INTF,
       
    98                                                   "shallowCopy",
       
    99                                                   "("
       
   100                                                   + NODE_SIG
       
   101                                                   + TRANSLET_OUTPUT_SIG
       
   102                                                   + ")" + STRING_SIG);
       
   103         il.append(new INVOKEINTERFACE(cpy, 3));
       
   104         il.append(DUP);
       
   105         il.append(new ASTORE(name.getIndex()));
       
   106         final BranchHandle ifBlock1 = il.append(new IFNULL(null));
       
   107 
       
   108         // Get the length of the node name and save for later
       
   109         il.append(new ALOAD(name.getIndex()));
       
   110         final int lengthMethod = cpg.addMethodref(STRING_CLASS,"length","()I");
       
   111         il.append(new INVOKEVIRTUAL(lengthMethod));
       
   112         il.append(DUP);
       
   113         il.append(new ISTORE(length.getIndex()));
       
   114 
       
   115         // Ignore attribute sets if current node is ROOT. DOM.shallowCopy()
       
   116         // returns "" for ROOT, so skip attribute sets if length == 0
       
   117         final BranchHandle ifBlock4 = il.append(new IFEQ(null));
       
   118 
       
   119         // Copy in attribute sets if specified
       
   120         if (_useSets != null) {
       
   121             // If the parent of this element will result in an element being
       
   122             // output then we know that it is safe to copy out the attributes
       
   123             final SyntaxTreeNode parent = getParent();
       
   124             if ((parent instanceof LiteralElement) ||
       
   125                 (parent instanceof LiteralElement)) {
       
   126                 _useSets.translate(classGen, methodGen);
       
   127             }
       
   128             // If not we have to check to see if the copy will result in an
       
   129             // element being output.
       
   130             else {
       
   131                 // check if element; if not skip to translate body
       
   132                 il.append(new ILOAD(length.getIndex()));
       
   133                 final BranchHandle ifBlock2 = il.append(new IFEQ(null));
       
   134                 // length != 0 -> element -> do attribute sets
       
   135                 _useSets.translate(classGen, methodGen);
       
   136                 // not an element; root
       
   137                 ifBlock2.setTarget(il.append(NOP));
       
   138             }
       
   139         }
       
   140 
       
   141         // Instantiate body of xsl:copy
       
   142         ifBlock4.setTarget(il.append(NOP));
       
   143         translateContents(classGen, methodGen);
       
   144 
       
   145         // Call the output handler's endElement() if we copied an element
       
   146         // (The DOM.shallowCopy() method calls startElement().)
       
   147         il.append(new ILOAD(length.getIndex()));
       
   148         final BranchHandle ifBlock3 = il.append(new IFEQ(null));
       
   149         il.append(methodGen.loadHandler());
       
   150         il.append(new ALOAD(name.getIndex()));
       
   151         il.append(methodGen.endElement());
       
   152 
       
   153         final InstructionHandle end = il.append(NOP);
       
   154         ifBlock1.setTarget(end);
       
   155         ifBlock3.setTarget(end);
       
   156         methodGen.removeLocalVariable(name);
       
   157         methodGen.removeLocalVariable(length);
       
   158     }
       
   159 }