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: ClonerToResultTree.java 468645 2006-10-28 06:57:24Z minchau $
20  */
21 package org.apache.xalan.transformer;
22 
23 import javax.xml.transform.TransformerException;
24 
25 import org.apache.xalan.serialize.SerializerUtils;
26 import org.apache.xml.dtm.DTM;
27 import org.apache.xml.serializer.SerializationHandler;
28 import org.apache.xml.utils.XMLString;
29 
30 /**
31  * Class used to clone a node, possibly including its children to
32  * a result tree.
33  * @xsl.usage internal
34  */
35 public class ClonerToResultTree
36 {
37 
38 //  /**
39 //   * Clone an element with or without children.
40 //   * TODO: Fix or figure out node clone failure!
41 //   * the error condition is severe enough to halt processing.
42 //   *
43 //   * @param node The node to clone
44 //   * @param shouldCloneAttributes Flag indicating whether to
45 //   * clone children attributes
46 //   *
47 //   * @throws TransformerException
48 //   */
49 //  public void cloneToResultTree(int node, boolean shouldCloneAttributes)
50 //    throws TransformerException
51 //  {
52 //
53 //    try
54 //    {
55 //      XPathContext xctxt = m_transformer.getXPathContext();
56 //      DTM dtm = xctxt.getDTM(node);
57 //
58 //      int type = dtm.getNodeType(node);
59 //      switch (type)
60 //      {
61 //      case DTM.TEXT_NODE :
62 //        dtm.dispatchCharactersEvents(node, m_rth, false);
63 //        break;
64 //      case DTM.DOCUMENT_FRAGMENT_NODE :
65 //      case DTM.DOCUMENT_NODE :
66 //
67 //        // Can't clone a document, but refrain from throwing an error
68 //        // so that copy-of will work
69 //        break;
70 //      case DTM.ELEMENT_NODE :
71 //        {
72 //          Attributes atts;
73 //
74 //          if (shouldCloneAttributes)
75 //          {
76 //            m_rth.addAttributes(node);
77 //            m_rth.processNSDecls(node, type, dtm);
78 //          }
79 //
80 //          String ns = dtm.getNamespaceURI(node);
81 //          String localName = dtm.getLocalName(node);
82 //
83 //          m_rth.startElement(ns, localName, dtm.getNodeNameX(node), null);
84 //        }
85 //        break;
86 //      case DTM.CDATA_SECTION_NODE :
87 //        m_rth.startCDATA();
88 //        dtm.dispatchCharactersEvents(node, m_rth, false);
89 //        m_rth.endCDATA();
90 //        break;
91 //      case DTM.ATTRIBUTE_NODE :
92 //        m_rth.addAttribute(node);
93 //        break;
94 //      case DTM.COMMENT_NODE :
95 //        XMLString xstr = dtm.getStringValue (node);
96 //        xstr.dispatchAsComment(m_rth);
97 //        break;
98 //      case DTM.ENTITY_REFERENCE_NODE :
99 //        m_rth.entityReference(dtm.getNodeNameX(node));
100 //        break;
101 //      case DTM.PROCESSING_INSTRUCTION_NODE :
102 //        {
103 //          // %REVIEW% Is the node name the same as the "target"?
104 //          m_rth.processingInstruction(dtm.getNodeNameX(node),
105 //                                      dtm.getNodeValue(node));
106 //        }
107 //        break;
108 //      default :
109 //        //"Can not create item in result tree: "+node.getNodeName());
110 //        m_transformer.getMsgMgr().error(null,
111 //                         XSLTErrorResources.ER_CANT_CREATE_ITEM,
112 //                         new Object[]{ dtm.getNodeName(node) });
113 //      }
114 //    }
115 //    catch(org.xml.sax.SAXException se)
116 //    {
117 //      throw new TransformerException(se);
118 //    }
119 //  }  // end cloneToResultTree function
120 
121   /**
122    * Clone an element with or without children.
123    * TODO: Fix or figure out node clone failure!
124    * the error condition is severe enough to halt processing.
125    *
126    * @param node The node to clone
127    * @param shouldCloneAttributes Flag indicating whether to
128    * clone children attributes
129    *
130    * @throws TransformerException
131    */
cloneToResultTree(int node, int nodeType, DTM dtm, SerializationHandler rth, boolean shouldCloneAttributes)132   public static void cloneToResultTree(int node, int nodeType, DTM dtm,
133                                              SerializationHandler rth,
134                                              boolean shouldCloneAttributes)
135     throws TransformerException
136   {
137 
138     try
139     {
140       switch (nodeType)
141       {
142       case DTM.TEXT_NODE :
143         dtm.dispatchCharactersEvents(node, rth, false);
144         break;
145       case DTM.DOCUMENT_FRAGMENT_NODE :
146       case DTM.DOCUMENT_NODE :
147         // Can't clone a document, but refrain from throwing an error
148         // so that copy-of will work
149         break;
150       case DTM.ELEMENT_NODE :
151         {
152           // Note: SAX apparently expects "no namespace" to be
153           // represented as "" rather than null.
154           String ns = dtm.getNamespaceURI(node);
155           if (ns==null) ns="";
156           String localName = dtm.getLocalName(node);
157       //  rth.startElement(ns, localName, dtm.getNodeNameX(node), null);
158       //  don't call a real SAX startElement (as commented out above),
159       //  call a SAX-like startElement, to be able to add attributes after this call
160           rth.startElement(ns, localName, dtm.getNodeNameX(node));
161 
162 	  // If outputting attrs as separate events, they must
163 	  // _follow_ the startElement event. (Think of the
164 	  // xsl:attribute directive.)
165           if (shouldCloneAttributes)
166           {
167             SerializerUtils.addAttributes(rth, node);
168             SerializerUtils.processNSDecls(rth, node, nodeType, dtm);
169           }
170         }
171         break;
172       case DTM.CDATA_SECTION_NODE :
173         rth.startCDATA();
174         dtm.dispatchCharactersEvents(node, rth, false);
175         rth.endCDATA();
176         break;
177       case DTM.ATTRIBUTE_NODE :
178         SerializerUtils.addAttribute(rth, node);
179         break;
180 			case DTM.NAMESPACE_NODE:
181 				// %REVIEW% Normally, these should have been handled with element.
182 				// It's possible that someone may write a stylesheet that tries to
183 				// clone them explicitly. If so, we need the equivalent of
184 				// rth.addAttribute().
185   			    SerializerUtils.processNSDecls(rth,node,DTM.NAMESPACE_NODE,dtm);
186 				break;
187       case DTM.COMMENT_NODE :
188         XMLString xstr = dtm.getStringValue (node);
189         xstr.dispatchAsComment(rth);
190         break;
191       case DTM.ENTITY_REFERENCE_NODE :
192         rth.entityReference(dtm.getNodeNameX(node));
193         break;
194       case DTM.PROCESSING_INSTRUCTION_NODE :
195         {
196           // %REVIEW% Is the node name the same as the "target"?
197           rth.processingInstruction(dtm.getNodeNameX(node),
198                                       dtm.getNodeValue(node));
199         }
200         break;
201       default :
202         //"Can not create item in result tree: "+node.getNodeName());
203         throw new  TransformerException(
204                          "Can't clone node: "+dtm.getNodeName(node));
205       }
206     }
207     catch(org.xml.sax.SAXException se)
208     {
209       throw new TransformerException(se);
210     }
211   }  // end cloneToResultTree function
212 }
213