1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24 package org.modeshape.common.xml;
25
26 import java.io.IOException;
27 import java.io.OutputStream;
28 import java.util.Collection;
29 import java.util.Collections;
30 import java.util.HashMap;
31 import java.util.Map;
32 import org.modeshape.common.text.TextEncoder;
33 import org.modeshape.common.text.XmlValueEncoder;
34 import org.xml.sax.Attributes;
35 import org.xml.sax.ContentHandler;
36 import org.xml.sax.SAXException;
37 import org.xml.sax.helpers.DefaultHandler;
38
39
40
41
42
43 public class StreamingContentHandler extends DefaultHandler {
44
45
46 private static final boolean LOG_TO_CONSOLE = false;
47
48
49
50
51
52
53 private final TextEncoder VALUE_ENCODER = new XmlValueEncoder();
54
55
56
57
58 private final Collection<String> unexportableNamespaces;
59
60
61
62
63 private final OutputStream os;
64
65
66
67
68 private final Map<String, String> mappedPrefixes;
69
70 public StreamingContentHandler( OutputStream os ) {
71 this(os, Collections.<String>emptyList());
72 }
73
74 public StreamingContentHandler( OutputStream os,
75 Collection<String> unexportableNamespaces ) {
76 this.os = os;
77 this.unexportableNamespaces = unexportableNamespaces;
78 mappedPrefixes = new HashMap<String, String>();
79 }
80
81
82
83
84
85
86 @Override
87 public void characters( char[] ch,
88 int start,
89 int length ) throws SAXException {
90 emit(VALUE_ENCODER.encode(new String(ch, start, length)));
91 }
92
93
94
95
96
97
98 @Override
99 public void startDocument() throws SAXException {
100 emit("<?xml version=\"1.0\" encoding=\"UTF-8\"?>");
101 }
102
103
104
105
106
107
108
109 @Override
110 public void startElement( String uri,
111 String localName,
112 String name,
113 Attributes attributes ) throws SAXException {
114 emit("<");
115 emit(name);
116
117 for (Map.Entry<String, String> mapping : mappedPrefixes.entrySet()) {
118 emit(" xmlns:");
119 emit(mapping.getKey());
120 emit("=\"");
121 emit(mapping.getValue());
122 emit("\"");
123 }
124
125 mappedPrefixes.clear();
126
127 if (attributes != null) {
128 for (int i = 0; i < attributes.getLength(); i++) {
129 emit(" ");
130 emit(attributes.getQName(i));
131 emit("=\"");
132 emit(VALUE_ENCODER.encode(attributes.getValue(i)));
133 emit("\"");
134 }
135 }
136
137 emit(">");
138 }
139
140
141
142
143
144
145 @Override
146 public void endElement( String uri,
147 String localName,
148 String name ) throws SAXException {
149 emit("</");
150 emit(name);
151 emit(">");
152 if (LOG_TO_CONSOLE) System.out.println();
153
154 }
155
156
157
158
159
160
161 @Override
162 public void startPrefixMapping( String prefix,
163 String uri ) {
164 if (!unexportableNamespaces.contains(prefix)) {
165 mappedPrefixes.put(prefix, uri);
166 }
167 }
168
169
170
171
172
173
174
175
176 private void emit( String text ) throws SAXException {
177
178 try {
179 if (LOG_TO_CONSOLE) {
180 System.out.print(text);
181 }
182
183 os.write(text.getBytes());
184 } catch (IOException ioe) {
185 throw new SAXException(ioe);
186 }
187 }
188 }