1/*
2 * Licensed to the Apache Software Foundation (ASF) under one
3 * or more contributor license agreements. See the NOTICE file
4 * distributed with this work for additional information
5 * regarding copyright ownership. The ASF licenses this file
6 * to you under the Apache License, Version 2.0 (the  "License");
7 * you may not use this file except in compliance with the License.
8 * You may obtain a copy of the License at
9 *
10 *     http://www.apache.org/licenses/LICENSE-2.0
11 *
12 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an "AS IS" BASIS,
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License.
17 */
18/*
19 * $Id: ElemCopy.java 468643 2006-10-28 06:56:03Z minchau $
20 */
21package org.apache.xalan.templates;
22
23import javax.xml.transform.TransformerException;
24
25import org.apache.xalan.transformer.ClonerToResultTree;
26import org.apache.xalan.transformer.TransformerImpl;
27import org.apache.xml.dtm.DTM;
28import org.apache.xalan.serialize.SerializerUtils;
29import org.apache.xml.serializer.SerializationHandler;
30import org.apache.xpath.XPathContext;
31
32/**
33 * Implement xsl:copy.
34 * <pre>
35 * <!ELEMENT xsl:copy %template;>
36 * <!ATTLIST xsl:copy
37 *   %space-att;
38 *   use-attribute-sets %qnames; #IMPLIED
39 * >
40 * </pre>
41 * @see <a href="http://www.w3.org/TR/xslt#copying">copying in XSLT Specification</a>
42 * @xsl.usage advanced
43 */
44public class ElemCopy extends ElemUse
45{
46    static final long serialVersionUID = 5478580783896941384L;
47
48  /**
49   * Get an int constant identifying the type of element.
50   * @see org.apache.xalan.templates.Constants
51   *
52   * @return The token ID for this element
53   */
54  public int getXSLToken()
55  {
56    return Constants.ELEMNAME_COPY;
57  }
58
59  /**
60   * Return the node name.
61   *
62   * @return This element's name
63   */
64  public String getNodeName()
65  {
66    return Constants.ELEMNAME_COPY_STRING;
67  }
68
69  /**
70   * The xsl:copy element provides an easy way of copying the current node.
71   * Executing this function creates a copy of the current node into the
72   * result tree.
73   * <p>The namespace nodes of the current node are automatically
74   * copied as well, but the attributes and children of the node are not
75   * automatically copied. The content of the xsl:copy element is a
76   * template for the attributes and children of the created node;
77   * the content is instantiated only for nodes of types that can have
78   * attributes or children (i.e. root nodes and element nodes).</p>
79   * <p>The root node is treated specially because the root node of the
80   * result tree is created implicitly. When the current node is the
81   * root node, xsl:copy will not create a root node, but will just use
82   * the content template.</p>
83   *
84   * @param transformer non-null reference to the the current transform-time state.
85   *
86   * @throws TransformerException
87   */
88  public void execute(
89          TransformerImpl transformer)
90            throws TransformerException
91  {
92                XPathContext xctxt = transformer.getXPathContext();
93
94    try
95    {
96      int sourceNode = xctxt.getCurrentNode();
97      xctxt.pushCurrentNode(sourceNode);
98      DTM dtm = xctxt.getDTM(sourceNode);
99      short nodeType = dtm.getNodeType(sourceNode);
100
101      if ((DTM.DOCUMENT_NODE != nodeType) && (DTM.DOCUMENT_FRAGMENT_NODE != nodeType))
102      {
103        SerializationHandler rthandler = transformer.getSerializationHandler();
104
105        // TODO: Process the use-attribute-sets stuff
106        ClonerToResultTree.cloneToResultTree(sourceNode, nodeType, dtm,
107                                             rthandler, false);
108
109        if (DTM.ELEMENT_NODE == nodeType)
110        {
111          super.execute(transformer);
112          SerializerUtils.processNSDecls(rthandler, sourceNode, nodeType, dtm);
113          transformer.executeChildTemplates(this, true);
114
115          String ns = dtm.getNamespaceURI(sourceNode);
116          String localName = dtm.getLocalName(sourceNode);
117          transformer.getResultTreeHandler().endElement(ns, localName,
118                                                        dtm.getNodeName(sourceNode));
119        }
120      }
121      else
122      {
123        super.execute(transformer);
124        transformer.executeChildTemplates(this, true);
125      }
126    }
127    catch(org.xml.sax.SAXException se)
128    {
129      throw new TransformerException(se);
130    }
131    finally
132    {
133      xctxt.popCurrentNode();
134    }
135  }
136}
137