001 /*
002 * Licensed to the Apache Software Foundation (ASF) under one
003 * or more contributor license agreements. See the NOTICE file
004 * distributed with this work for additional information
005 * regarding copyright ownership. The ASF licenses this file
006 * to you under the Apache License, Version 2.0 (the "License");
007 * you may not use this file except in compliance with the License.
008 * You may obtain a copy of the License at
009 *
010 * http://www.apache.org/licenses/LICENSE-2.0
011 *
012 * Unless required by applicable law or agreed to in writing, software
013 * distributed under the License is distributed on an "AS IS" BASIS,
014 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
015 * See the License for the specific language governing permissions and
016 * limitations under the License.
017 */
018 /*
019 * $Id: ClonerToResultTree.java 468645 2006-10-28 06:57:24Z minchau $
020 */
021 package org.apache.xalan.transformer;
022
023 import javax.xml.transform.TransformerException;
024
025 import org.apache.xalan.serialize.SerializerUtils;
026 import org.apache.xml.dtm.DTM;
027 import org.apache.xml.serializer.SerializationHandler;
028 import org.apache.xml.utils.XMLString;
029
030 /**
031 * Class used to clone a node, possibly including its children to
032 * a result tree.
033 * @xsl.usage internal
034 */
035 public class ClonerToResultTree
036 {
037
038 // /**
039 // * Clone an element with or without children.
040 // * TODO: Fix or figure out node clone failure!
041 // * the error condition is severe enough to halt processing.
042 // *
043 // * @param node The node to clone
044 // * @param shouldCloneAttributes Flag indicating whether to
045 // * clone children attributes
046 // *
047 // * @throws TransformerException
048 // */
049 // public void cloneToResultTree(int node, boolean shouldCloneAttributes)
050 // throws TransformerException
051 // {
052 //
053 // try
054 // {
055 // XPathContext xctxt = m_transformer.getXPathContext();
056 // DTM dtm = xctxt.getDTM(node);
057 //
058 // int type = dtm.getNodeType(node);
059 // switch (type)
060 // {
061 // case DTM.TEXT_NODE :
062 // dtm.dispatchCharactersEvents(node, m_rth, false);
063 // break;
064 // case DTM.DOCUMENT_FRAGMENT_NODE :
065 // case DTM.DOCUMENT_NODE :
066 //
067 // // Can't clone a document, but refrain from throwing an error
068 // // so that copy-of will work
069 // break;
070 // case DTM.ELEMENT_NODE :
071 // {
072 // Attributes atts;
073 //
074 // if (shouldCloneAttributes)
075 // {
076 // m_rth.addAttributes(node);
077 // m_rth.processNSDecls(node, type, dtm);
078 // }
079 //
080 // String ns = dtm.getNamespaceURI(node);
081 // String localName = dtm.getLocalName(node);
082 //
083 // m_rth.startElement(ns, localName, dtm.getNodeNameX(node), null);
084 // }
085 // break;
086 // case DTM.CDATA_SECTION_NODE :
087 // m_rth.startCDATA();
088 // dtm.dispatchCharactersEvents(node, m_rth, false);
089 // m_rth.endCDATA();
090 // break;
091 // case DTM.ATTRIBUTE_NODE :
092 // m_rth.addAttribute(node);
093 // break;
094 // case DTM.COMMENT_NODE :
095 // XMLString xstr = dtm.getStringValue (node);
096 // xstr.dispatchAsComment(m_rth);
097 // break;
098 // case DTM.ENTITY_REFERENCE_NODE :
099 // 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 */
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 }