1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47 package org.exolab.castor.xml.util;
48
49 import java.util.HashSet;
50
51 import org.exolab.castor.types.AnyNode;
52 import org.exolab.castor.xml.EventProducer;
53 import org.exolab.castor.xml.Namespaces;
54 import org.exolab.castor.xml.NamespacesStack;
55 import org.xml.sax.DocumentHandler;
56 import org.xml.sax.SAXException;
57 import org.xml.sax.helpers.AttributeListImpl;
58
59
60
61
62
63
64 public class AnyNode2SAX implements EventProducer {
65
66
67 private AnyNode _node;
68
69 private DocumentHandler _handler;
70
71 private HashSet _elements;
72
73
74
75
76 private NamespacesStack namespacesStack;
77
78
79
80
81 public AnyNode2SAX() {
82 this(null, null);
83 }
84
85
86
87
88
89 public AnyNode2SAX(final AnyNode node) {
90 this(node, null);
91 }
92
93
94
95
96
97
98 public AnyNode2SAX(final AnyNode node, final NamespacesStack namespacesStack) {
99 _elements = new HashSet();
100 _node = node;
101 this.namespacesStack = namespacesStack != null ? namespacesStack : new NamespacesStack();
102 }
103
104
105
106
107
108 public void setDocumentHandler(final DocumentHandler handler) {
109 if (handler == null) {
110 throw new IllegalArgumentException("AnyNode2SAX#setDocumentHandler 'null' value for handler");
111 }
112 _handler = handler;
113 }
114
115 public static void fireEvents(final AnyNode node, final DocumentHandler handler) throws SAXException {
116 fireEvents(node, handler, null);
117 }
118
119 public static void fireEvents(final AnyNode node,
120 final DocumentHandler handler, final NamespacesStack namespacesStack) throws SAXException {
121 AnyNode2SAX eventProducer = new AnyNode2SAX(node, namespacesStack);
122 eventProducer.setDocumentHandler(handler);
123 eventProducer.start();
124 }
125
126 public void start() throws org.xml.sax.SAXException {
127 if (_node == null || _handler == null) {
128 return;
129 }
130 processAnyNode(_node, _handler);
131 }
132
133 private void processAnyNode(final AnyNode node, final DocumentHandler handler)
134 throws SAXException {
135
136 if (node == null || handler == null) {
137 throw new IllegalArgumentException();
138 }
139
140
141 if (!_elements.add(node)) {
142 return;
143 }
144
145 if (node.getNodeType() == AnyNode.ELEMENT) {
146 String name = node.getLocalName();
147
148
149 AttributeListImpl atts = new AttributeListImpl();
150 AnyNode tempNode = node.getFirstAttribute();
151 String xmlName = null;
152 String value = null;
153 String attUri = null;
154 String attPrefix = null;
155
156 while (tempNode != null) {
157 xmlName = tempNode.getLocalName();
158
159 attUri = tempNode.getNamespaceURI();
160 if (attUri != null) {
161 attPrefix = namespacesStack.getNamespacePrefix(attUri);
162 }
163 if (attPrefix != null && attPrefix.length() > 0) {
164 xmlName = attPrefix + ':' + xmlName;
165 }
166 value = tempNode.getStringValue();
167 atts.addAttribute(xmlName, "CDATA", value);
168 tempNode = tempNode.getNextSibling();
169 }
170
171
172 namespacesStack.addNewNamespaceScope();
173 String nsPrefix = node.getNamespacePrefix();
174 String nsURI = node.getNamespaceURI();
175
176
177 tempNode = node.getFirstNamespace();
178 String prefix = null;
179 while (tempNode != null) {
180 prefix = tempNode.getNamespacePrefix();
181 value = tempNode.getNamespaceURI();
182 if (value != null && value.length() > 0) {
183 namespacesStack.addNamespace(prefix, value);
184 }
185 tempNode = tempNode.getNextSibling();
186 }
187
188 String qName = null;
189
190
191 if (nsURI != null && nsURI.length() > 0) {
192 String tempPrefix = namespacesStack.getNamespacePrefix(nsURI);
193 if (tempPrefix != null) {
194 nsPrefix = tempPrefix;
195 } else {
196 namespacesStack.addNamespace(nsPrefix, nsURI);
197 }
198 }
199
200 if (nsPrefix != null) {
201 int len = nsPrefix.length();
202 if (len > 0) {
203 StringBuffer sb = new StringBuffer(len+name.length()+1);
204 sb.append(nsPrefix);
205 sb.append(':');
206 sb.append(name);
207 qName = sb.toString();
208 } else {
209 qName = name;
210 }
211 } else {
212 qName = name;
213 }
214
215 try {
216 namespacesStack.declareAsAttributes(atts,true);
217 handler.startElement(qName, atts);
218 } catch (SAXException sx) {
219 throw new SAXException(sx);
220 }
221
222
223 tempNode = node.getFirstChild();
224 while (tempNode != null) {
225 processAnyNode(tempNode, handler);
226 tempNode = tempNode.getNextSibling();
227 }
228
229
230 try {
231 handler.endElement(qName);
232 namespacesStack.removeNamespaceScope();
233 } catch(org.xml.sax.SAXException sx) {
234 throw new SAXException(sx);
235 }
236 } else {
237
238 if (node.getNodeType() == AnyNode.TEXT) {
239 String value = node.getStringValue();
240 if (value != null && value.length() > 0) {
241 char[] chars = value.toCharArray();
242 try {
243 handler.characters(chars, 0, chars.length);
244 } catch(org.xml.sax.SAXException sx) {
245 throw new SAXException(sx);
246 }
247 }
248 }
249 }
250 }
251
252 }