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