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 package org.exolab.castor.xml.util;
37
38 import java.util.HashSet;
39 import java.util.Set;
40
41 import org.exolab.castor.types.AnyNode;
42 import org.exolab.castor.xml.Namespaces;
43 import org.exolab.castor.xml.NamespacesStack;
44 import org.xml.sax.ContentHandler;
45 import org.xml.sax.SAXException;
46 import org.xml.sax.helpers.AttributesImpl;
47
48
49
50
51
52
53
54
55
56 public class AnyNode2SAX2 {
57
58
59 private AnyNode _node;
60
61 private ContentHandler _handler;
62
63 private Set<AnyNode> _elements;
64
65 private NamespacesStack namespacesStack;
66
67
68
69
70 public AnyNode2SAX2() {
71 this(null, null);
72 }
73
74
75
76
77
78
79 public AnyNode2SAX2(final AnyNode node) {
80 this(node, null);
81 }
82
83
84
85
86
87
88
89 public AnyNode2SAX2(final AnyNode node, final NamespacesStack namespacesStack) {
90 _elements = new HashSet<AnyNode>();
91 _node = node;
92 this.namespacesStack = namespacesStack != null ? namespacesStack : new NamespacesStack();
93 }
94
95
96
97
98
99
100 public void setContentHandler(final ContentHandler handler) {
101 if (handler == null) {
102 throw new IllegalArgumentException("AnyNode2SAX2#setContentHandler 'null' value for handler");
103 }
104 _handler = handler;
105 }
106
107 public static void fireEvents(final AnyNode node, final ContentHandler handler)
108 throws SAXException {
109 fireEvents(node, handler, null);
110 }
111
112 public static void fireEvents(final AnyNode node, final ContentHandler handler,
113 final NamespacesStack namespacesStack) throws SAXException {
114 AnyNode2SAX2 eventProducer = new AnyNode2SAX2(node, namespacesStack);
115 eventProducer.setContentHandler(handler);
116
117
118 if (node != null && namespacesStack != null && node.getNamespacePrefix() != null
119 && namespacesStack.getNamespaceURI(node.getNamespacePrefix()) == null) {
120 handler.startPrefixMapping(node.getNamespacePrefix(), node.getNamespaceURI());
121 }
122
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 ContentHandler handler)
134 throws SAXException {
135 if (_node == null || _handler == null) {
136 throw new IllegalArgumentException();
137 }
138
139
140 if (!_elements.add(node)) {
141 return;
142 }
143
144 if (node.getNodeType() == AnyNode.ELEMENT) {
145
146 String name = node.getLocalName();
147
148
149 AnyNode tempNode = node.getFirstNamespace();
150 String prefix = null;
151 while (tempNode != null) {
152 prefix = tempNode.getNamespacePrefix();
153 if (prefix == null) {
154 prefix = "";
155 }
156 String value = tempNode.getNamespaceURI();
157 if (value == null) {
158 value = "";
159 }
160 handler.startPrefixMapping(prefix, value);
161 if (value != null && value.length() > 0) {
162 namespacesStack.addNamespace(prefix, value);
163 }
164 tempNode = tempNode.getNextSibling();
165 }
166
167
168 AttributesImpl atts = new AttributesImpl();
169 tempNode = node.getFirstAttribute();
170 String xmlName = null;
171 String value = null;
172 String attUri = null;
173 String attPrefix = null;
174 while (tempNode != null) {
175 xmlName = tempNode.getLocalName();
176 String localName = xmlName;
177
178 attUri = tempNode.getNamespaceURI();
179 if (attUri != null) {
180 attPrefix = namespacesStack.getNamespacePrefix(attUri);
181 } else {
182 attUri = "";
183 }
184
185 if (attPrefix != null && attPrefix.length() > 0) {
186 xmlName = attPrefix + ':' + xmlName;
187 }
188
189 value = tempNode.getStringValue();
190 atts.addAttribute(attUri, localName, xmlName, "CDATA", value);
191 tempNode = tempNode.getNextSibling();
192 }
193
194
195
196 String nsPrefix = node.getNamespacePrefix();
197 String nsURI = node.getNamespaceURI();
198
199 String qName = null;
200
201
202 if (nsURI != null && nsURI.length() > 0) {
203 String tempPrefix = namespacesStack.getNamespacePrefix(nsURI);
204 if (tempPrefix != null) {
205 nsPrefix = tempPrefix;
206 } else {
207 namespacesStack.addNamespace(nsPrefix, nsURI);
208 }
209 } else {
210 nsURI = "";
211 }
212
213 if (nsPrefix != null) {
214 int len = nsPrefix.length();
215 if (len > 0) {
216 qName = nsPrefix + ':' + name;
217 } else {
218 qName = name;
219 }
220 } else {
221 qName = name;
222 }
223
224 try {
225
226 handler.startElement(nsURI, name, qName, atts);
227 } catch (SAXException sx) {
228 throw new SAXException(sx);
229 }
230
231
232 tempNode = node.getFirstChild();
233 while (tempNode != null) {
234 namespacesStack.addNewNamespaceScope();
235 processAnyNode(tempNode, handler);
236 tempNode = tempNode.getNextSibling();
237 }
238
239
240 try {
241 handler.endElement(nsURI, name, qName);
242 namespacesStack.removeNamespaceScope();
243
244
245 tempNode = node.getFirstNamespace();
246 while (tempNode != null) {
247 prefix = tempNode.getNamespacePrefix();
248 if (prefix == null) {
249 prefix = "";
250 }
251 handler.endPrefixMapping(prefix);
252 tempNode = tempNode.getNextSibling();
253 }
254 } catch (org.xml.sax.SAXException sx) {
255 throw new SAXException(sx);
256 }
257 } else {
258
259 if (node.getNodeType() == AnyNode.TEXT) {
260 String value = node.getStringValue();
261 if ((value != null) && (value.length() > 0)) {
262 char[] chars = value.toCharArray();
263 try {
264 handler.characters(chars, 0, chars.length);
265 } catch (org.xml.sax.SAXException sx) {
266 throw new SAXException(sx);
267 }
268 }
269 }
270 }
271 }
272
273 }