|
|||||||||||||||||||
Source file | Conditionals | Statements | Methods | TOTAL | |||||||||||||||
SAXModifier.java | 0% | 0% | 0% | 0% |
|
1 | /* | |
2 | * Copyright 2001-2004 (C) MetaStuff, Ltd. All Rights Reserved. | |
3 | * | |
4 | * This software is open source. | |
5 | * See the bottom of this file for the licence. | |
6 | * | |
7 | * $Id: SAXModifier.java,v 1.1 2004/08/02 18:44:07 maartenc Exp $ | |
8 | */ | |
9 | ||
10 | package org.dom4j.io; | |
11 | ||
12 | import java.io.File; | |
13 | import java.io.InputStream; | |
14 | import java.io.Reader; | |
15 | import java.net.URL; | |
16 | import java.util.HashMap; | |
17 | import java.util.Iterator; | |
18 | import java.util.Map; | |
19 | ||
20 | import org.dom4j.Document; | |
21 | import org.dom4j.DocumentException; | |
22 | import org.dom4j.DocumentFactory; | |
23 | import org.xml.sax.InputSource; | |
24 | import org.xml.sax.SAXException; | |
25 | import org.xml.sax.XMLReader; | |
26 | ||
27 | /** | |
28 | * The SAXModifier reads, modifies and writes XML documents using SAX. <br> | |
29 | * Registered {@link ElementModifier} objects can provide modifications to (part of) the xml tree, | |
30 | * while the document is still being processed. This makes it possible to change large xml documents | |
31 | * without having them in memory.<br> | |
32 | * The modified document is written when the {@link XMLWriter} is specified. | |
33 | * | |
34 | * @see org.dom4j.io.SAXReader | |
35 | * @see org.dom4j.io.XMLWriter | |
36 | * @author Wonne Keysers (Realsoftware.be) | |
37 | */ | |
38 | public class SAXModifier { | |
39 | ||
40 | private XMLWriter xmlWriter; | |
41 | private XMLReader xmlReader; | |
42 | ||
43 | private boolean pruneElements; | |
44 | private SAXModifyReader modifyReader; | |
45 | private HashMap modifiers = new HashMap(); | |
46 | ||
47 | /** | |
48 | * Creates a new modifier.<br> | |
49 | * The XMLReader to parse the source will be created via the org.xml.sax.driver system property | |
50 | * or JAXP if the system property is not set. | |
51 | */ | |
52 | 0 | public SAXModifier() { |
53 | } | |
54 | ||
55 | /** | |
56 | * Creates a new modifier.<br> | |
57 | * The XMLReader to parse the source will be created via the org.xml.sax.driver system property | |
58 | * or JAXP if the system property is not set. | |
59 | * | |
60 | * @param pruneElements Set to true when the modified document must NOT be kept in memory. | |
61 | */ | |
62 | 0 | public SAXModifier(boolean pruneElements) { |
63 | 0 | this.pruneElements = pruneElements; |
64 | } | |
65 | ||
66 | /** | |
67 | * Creates a new modifier that will the specified {@link org.xml.sax.XMLReader} | |
68 | * to parse the source. | |
69 | * | |
70 | * @param xmlReader The XMLReader to use | |
71 | */ | |
72 | 0 | public SAXModifier(XMLReader xmlReader) { |
73 | 0 | this.xmlReader = xmlReader; |
74 | } | |
75 | ||
76 | /** | |
77 | * Creates a new modifier that will the specified {@link org.xml.sax.XMLReader} | |
78 | * to parse the source. | |
79 | * | |
80 | * @param xmlReader The XMLReader to use | |
81 | * @param pruneElements Set to true when the modified document must NOT be kept in memory. | |
82 | */ | |
83 | 0 | public SAXModifier(XMLReader xmlReader, boolean pruneElements) { |
84 | 0 | this.xmlReader = xmlReader; |
85 | } | |
86 | ||
87 | /** | |
88 | * Reads a Document from the given {@link java.io.File} | |
89 | * and writes it to the specified {@link XMLWriter} using SAX. | |
90 | * Registered {@link ElementModifier} objects are invoked on the fly. | |
91 | * | |
92 | * @param source is the <code>File</code> to read from. | |
93 | * @return the newly created Document instance | |
94 | * @throws {@link org.dom4j.DocumentException} if an error occurs during parsing. | |
95 | */ | |
96 | 0 | public Document modify(File source) throws DocumentException { |
97 | 0 | try { |
98 | 0 | return installModifyReader().read(source); |
99 | } | |
100 | catch (SAXModifyException ex) { | |
101 | 0 | Throwable cause = ex.getCause(); |
102 | 0 | throw new DocumentException(cause.getMessage(), cause); |
103 | } | |
104 | } | |
105 | ||
106 | /** | |
107 | * Reads a Document from the given {@link org.xml.sax.InputSource} | |
108 | * and writes it to the specified {@link XMLWriter} using SAX. | |
109 | * Registered {@link ElementModifier} objects are invoked on the fly. | |
110 | * | |
111 | * @param source is the <code>org.xml.sax.InputSource</code> to read from. | |
112 | * @return the newly created Document instance | |
113 | * @throws {@link org.dom4j.DocumentException} if an error occurs during parsing. | |
114 | */ | |
115 | 0 | public Document modify(InputSource source) throws DocumentException { |
116 | 0 | try { |
117 | 0 | return installModifyReader().read(source); |
118 | } | |
119 | catch (SAXModifyException ex) { | |
120 | 0 | Throwable cause = ex.getCause(); |
121 | 0 | throw new DocumentException(cause.getMessage(), cause); |
122 | } | |
123 | } | |
124 | ||
125 | /** | |
126 | * Reads a Document from the given {@link java.io.InputStream} | |
127 | * and writes it to the specified {@link XMLWriter} using SAX. | |
128 | * Registered {@link ElementModifier} objects are invoked on the fly. | |
129 | * | |
130 | * @param source is the <code>java.io.InputStream</code> to read from. | |
131 | * @return the newly created Document instance | |
132 | * @throws {@link org.dom4j.DocumentException} if an error occurs during parsing. | |
133 | */ | |
134 | 0 | public Document modify(InputStream source) throws DocumentException { |
135 | 0 | try { |
136 | 0 | return installModifyReader().read(source); |
137 | } | |
138 | catch (SAXModifyException ex) { | |
139 | 0 | Throwable cause = ex.getCause(); |
140 | 0 | throw new DocumentException(cause.getMessage(), cause); |
141 | } | |
142 | } | |
143 | ||
144 | /** | |
145 | * Reads a Document from the given {@link java.io.InputStream} | |
146 | * and writes it to the specified {@link XMLWriter} using SAX. | |
147 | * Registered {@link ElementModifier} objects are invoked on the fly. | |
148 | * | |
149 | * @param source is the <code>java.io.InputStream</code> to read from. | |
150 | * @return the newly created Document instance | |
151 | * @throws {@link org.dom4j.DocumentException} if an error occurs during parsing. | |
152 | */ | |
153 | 0 | public Document modify(InputStream source, String systemId) throws DocumentException { |
154 | 0 | try { |
155 | 0 | return installModifyReader().read(source); |
156 | } | |
157 | catch (SAXModifyException ex) { | |
158 | 0 | Throwable cause = ex.getCause(); |
159 | 0 | throw new DocumentException(cause.getMessage(), cause); |
160 | } | |
161 | } | |
162 | ||
163 | /** | |
164 | * Reads a Document from the given {@link java.io.Reader} | |
165 | * and writes it to the specified {@link XMLWriter} using SAX. | |
166 | * Registered {@link ElementModifier} objects are invoked on the fly. | |
167 | * | |
168 | * @param source is the <code>java.io.Reader</code> to read from. | |
169 | * @return the newly created Document instance | |
170 | * @throws {@link org.dom4j.DocumentException} if an error occurs during parsing. | |
171 | */ | |
172 | 0 | public Document modify(Reader source) throws DocumentException { |
173 | 0 | try { |
174 | 0 | return installModifyReader().read(source); |
175 | } | |
176 | catch (SAXModifyException ex) { | |
177 | 0 | Throwable cause = ex.getCause(); |
178 | 0 | throw new DocumentException(cause.getMessage(), cause); |
179 | } | |
180 | } | |
181 | ||
182 | /** | |
183 | * Reads a Document from the given {@link java.io.Reader} | |
184 | * and writes it to the specified {@link XMLWriter} using SAX. | |
185 | * Registered {@link ElementModifier} objects are invoked on the fly. | |
186 | * | |
187 | * @param source is the <code>java.io.Reader</code> to read from. | |
188 | * @return the newly created Document instance | |
189 | * @throws {@link org.dom4j.DocumentException} if an error occurs during parsing. | |
190 | */ | |
191 | 0 | public Document modify(Reader source, String systemId) throws DocumentException { |
192 | 0 | try { |
193 | 0 | return installModifyReader().read(source); |
194 | } | |
195 | catch (SAXModifyException ex) { | |
196 | 0 | Throwable cause = ex.getCause(); |
197 | 0 | throw new DocumentException(cause.getMessage(), cause); |
198 | } | |
199 | } | |
200 | ||
201 | /** | |
202 | * Reads a Document from the given {@link java.net.URL} | |
203 | * and writes it to the specified {@link XMLWriter} using SAX. | |
204 | * Registered {@link ElementModifier} objects are invoked on the fly. | |
205 | * | |
206 | * @param source is the <code>java.net.URL</code> to read from. | |
207 | * @return the newly created Document instance | |
208 | * @throws {@link org.dom4j.DocumentException} if an error occurs during parsing. | |
209 | */ | |
210 | 0 | public Document modify(URL source) throws DocumentException { |
211 | 0 | try { |
212 | 0 | return installModifyReader().read(source); |
213 | } | |
214 | catch (SAXModifyException ex) { | |
215 | 0 | Throwable cause = ex.getCause(); |
216 | 0 | throw new DocumentException(cause.getMessage(), cause); |
217 | } | |
218 | } | |
219 | ||
220 | /** | |
221 | * Reads a Document from the given URL or filename | |
222 | * and writes it to the specified {@link XMLWriter} using SAX. | |
223 | * Registered {@link ElementModifier} objects are invoked on the fly. | |
224 | * | |
225 | * @param source is the URL or filename to read from. | |
226 | * @return the newly created Document instance | |
227 | * @throws {@link org.dom4j.DocumentException} if an error occurs during parsing. | |
228 | */ | |
229 | 0 | public Document modify(String source) throws DocumentException { |
230 | 0 | try { |
231 | 0 | return installModifyReader().read(source); |
232 | } | |
233 | catch (SAXModifyException ex) { | |
234 | 0 | Throwable cause = ex.getCause(); |
235 | 0 | throw new DocumentException(cause.getMessage(), cause); |
236 | } | |
237 | } | |
238 | ||
239 | /** | |
240 | * Adds the {@link ElementModifier} to be called | |
241 | * when the specified element path is encounted while parsing the source. | |
242 | * | |
243 | * @param path The element path to be handled | |
244 | * @param handler The {@link ElementModifier} to be called by the event based processor. | |
245 | */ | |
246 | 0 | public void addModifier(String path, ElementModifier modifier) { |
247 | 0 | this.modifiers.put(path, modifier); |
248 | } | |
249 | ||
250 | /** | |
251 | * Removes all registered {@link ElementModifier} instances from the event based processor. | |
252 | */ | |
253 | 0 | public void resetModifiers() { |
254 | 0 | this.modifiers.clear(); |
255 | 0 | getSAXModifyReader().resetHandlers(); |
256 | } | |
257 | ||
258 | /** | |
259 | * Removes the {@link ElementModifier} from the event based processor, | |
260 | * for the specified element path. | |
261 | * | |
262 | * @param path The path to remove the {@link ElementModifier} for. | |
263 | */ | |
264 | 0 | public void removeModifier(String path) { |
265 | 0 | this.modifiers.remove(path); |
266 | 0 | getSAXModifyReader().removeHandler(path); |
267 | } | |
268 | ||
269 | /** | |
270 | * Get the {@link org.dom4j.DocumentFactory} used to create the DOM4J document structure | |
271 | * | |
272 | * @return <code>DocumentFactory</code> that will be used | |
273 | */ | |
274 | 0 | public DocumentFactory getDocumentFactory() { |
275 | 0 | return getSAXModifyReader().getDocumentFactory(); |
276 | } | |
277 | ||
278 | /** | |
279 | * Sets the {@link org.dom4j.DocumentFactory} used to create the DOM4J document tree. | |
280 | * | |
281 | * @param factory <code>DocumentFactory</code> to be used | |
282 | */ | |
283 | 0 | public void setDocumentFactory(DocumentFactory factory) { |
284 | 0 | getSAXModifyReader().setDocumentFactory(factory); |
285 | } | |
286 | ||
287 | /** | |
288 | * Returns the current {@link XMLWriter}. | |
289 | * @return XMLWriter | |
290 | */ | |
291 | 0 | public XMLWriter getXMLWriter() { |
292 | 0 | return this.xmlWriter; |
293 | } | |
294 | ||
295 | /** | |
296 | * Sets the {@link XMLWriter} used to write the modified document. | |
297 | * @param xmlWriter The writer to use. | |
298 | */ | |
299 | 0 | public void setXMLWriter(XMLWriter xmlWriter) { |
300 | 0 | this.xmlWriter = xmlWriter; |
301 | } | |
302 | ||
303 | /** | |
304 | * Returns true when xml elements are not kept in memory while parsing. | |
305 | * The {@link org.dom4j.Document} returned by the modify methods will be null. | |
306 | * @return Returns the pruneElements. | |
307 | */ | |
308 | 0 | public boolean isPruneElements() { |
309 | 0 | return pruneElements; |
310 | } | |
311 | ||
312 | 0 | private SAXReader installModifyReader() throws DocumentException { |
313 | 0 | try { |
314 | 0 | SAXModifyReader reader = getSAXModifyReader(); |
315 | ||
316 | 0 | if (isPruneElements()) { |
317 | 0 | modifyReader.setDispatchHandler(new PruningDispatchHandler()); |
318 | } | |
319 | ||
320 | 0 | reader.resetHandlers(); |
321 | ||
322 | 0 | Iterator modifierIt = this.modifiers.entrySet().iterator(); |
323 | 0 | while(modifierIt.hasNext()){ |
324 | 0 | Map.Entry entry = (Map.Entry)modifierIt.next(); |
325 | ||
326 | 0 | SAXModifyElementHandler modifierHandler |
327 | = new SAXModifyElementHandler((ElementModifier)entry.getValue()); | |
328 | 0 | reader.addHandler((String)entry.getKey(), modifierHandler); |
329 | } | |
330 | ||
331 | 0 | reader.setXMLWriter(getXMLWriter()); |
332 | 0 | reader.setXMLReader(getXMLReader()); |
333 | ||
334 | 0 | return reader; |
335 | } | |
336 | catch (SAXException ex) { | |
337 | 0 | throw new DocumentException(ex.getMessage(), ex); |
338 | } | |
339 | } | |
340 | ||
341 | 0 | private XMLReader getXMLReader() throws SAXException { |
342 | 0 | if (this.xmlReader == null) { |
343 | 0 | xmlReader = SAXHelper.createXMLReader(false); |
344 | } | |
345 | 0 | return this.xmlReader; |
346 | } | |
347 | ||
348 | 0 | private SAXModifyReader getSAXModifyReader() { |
349 | 0 | if (modifyReader == null) { |
350 | 0 | modifyReader = new SAXModifyReader(); |
351 | } | |
352 | ||
353 | 0 | return modifyReader; |
354 | } | |
355 | ||
356 | } | |
357 | ||
358 | ||
359 | ||
360 | ||
361 | /* | |
362 | * Redistribution and use of this software and associated documentation | |
363 | * ("Software"), with or without modification, are permitted provided | |
364 | * that the following conditions are met: | |
365 | * | |
366 | * 1. Redistributions of source code must retain copyright | |
367 | * statements and notices. Redistributions must also contain a | |
368 | * copy of this document. | |
369 | * | |
370 | * 2. Redistributions in binary form must reproduce the | |
371 | * above copyright notice, this list of conditions and the | |
372 | * following disclaimer in the documentation and/or other | |
373 | * materials provided with the distribution. | |
374 | * | |
375 | * 3. The name "DOM4J" must not be used to endorse or promote | |
376 | * products derived from this Software without prior written | |
377 | * permission of MetaStuff, Ltd. For written permission, | |
378 | * please contact dom4j-info@metastuff.com. | |
379 | * | |
380 | * 4. Products derived from this Software may not be called "DOM4J" | |
381 | * nor may "DOM4J" appear in their names without prior written | |
382 | * permission of MetaStuff, Ltd. DOM4J is a registered | |
383 | * trademark of MetaStuff, Ltd. | |
384 | * | |
385 | * 5. Due credit should be given to the DOM4J Project - | |
386 | * http://www.dom4j.org | |
387 | * | |
388 | * THIS SOFTWARE IS PROVIDED BY METASTUFF, LTD. AND CONTRIBUTORS | |
389 | * ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT | |
390 | * NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND | |
391 | * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL | |
392 | * METASTUFF, LTD. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, | |
393 | * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | |
394 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR | |
395 | * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | |
396 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, | |
397 | * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | |
398 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED | |
399 | * OF THE POSSIBILITY OF SUCH DAMAGE. | |
400 | * | |
401 | * Copyright 2001-2004 (C) MetaStuff, Ltd. All Rights Reserved. | |
402 | * | |
403 | * $Id: SAXModifier.java,v 1.1 2004/08/02 18:44:07 maartenc Exp $ | |
404 | */ |
|