View Javadoc

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: JAXBReader.java,v 1.1 2004/08/02 18:44:07 maartenc Exp $
8    */
9   
10  package org.dom4j.jaxb;
11  
12  import java.io.File;
13  import java.io.FileInputStream;
14  import java.io.FileNotFoundException;
15  import java.io.InputStream;
16  import java.io.InputStreamReader;
17  import java.io.Reader;
18  import java.net.URL;
19  import java.nio.charset.Charset;
20  
21  import org.dom4j.Document;
22  import org.dom4j.DocumentException;
23  import org.dom4j.Element;
24  import org.dom4j.ElementHandler;
25  import org.dom4j.ElementPath;
26  import org.dom4j.io.SAXReader;
27  import org.xml.sax.InputSource;
28  
29  /***
30   * Reads an XML document and creates a DOM4J tree from SAX parsing events.
31   * {@link JAXBObjectHandler} objects can be registered to automatically receive
32   * unmarshalled XML fragments. 
33   * 
34   * @see org.dom4j.io.SAXReader
35   * @see javax.xml.bind.JAXBContext
36   * @author Wonne Keysers (Realsoftware.be)
37   */
38  public class JAXBReader extends JAXBSupport {
39  
40     private SAXReader reader;
41     private boolean pruneElements;
42  
43     /***
44      * Creates a new JAXBReader for the given JAXB context path.
45      * This is the Java package where JAXB can find the generated XML classes.
46      * This package MUST contain jaxb.properties!
47      * 
48      * @param contextPath context path to be used
49      * @see javax.xml.bind.JAXBContext
50      */
51     public JAXBReader(String contextPath) {
52        super(contextPath);
53     }
54  
55     /***
56      * Creates a new JAXBReader for the given JAXB context path,
57      * using the specified {@link java.lang.Classloader}.
58      * This is the Java package where JAXB can find the generated XML classes.
59      * This package MUST contain jaxb.properties!
60      * 
61      * @param contextPath to be used
62      * @param classloader to be used
63      * @see javax.xml.bind.JAXBContext
64      */
65     public JAXBReader(String contextPath, ClassLoader classloader) {
66        super(contextPath, classloader);
67     }
68  
69     /***
70      * Parses the specified {@link java.io.File}
71      * 
72      * @param source the file to parse
73      * @return the resulting DOM4J document
74      * @throws DocumentException when an error occurs while parsing
75      */
76     public Document read(File source) throws DocumentException {
77        return getReader().read(source);
78     }
79  
80     /***
81      * Parses the specified {@link java.io.File}, using the given {@link java.nio.charset.Charset}.
82      * 
83      * @param source the file to parse
84      * @param charset the charset to be used
85      * @return the resulting DOM4J document
86      * @throws DocumentException when an error occurs while parsing
87      */
88     public Document read(File source, Charset charset) throws DocumentException {
89        try {
90           return getReader().read(new InputStreamReader(new FileInputStream(source), charset));
91        }
92        catch (JAXBRuntimeException ex) {
93           Throwable cause = ex.getCause();
94           throw new DocumentException(cause.getMessage(), cause);
95        }
96        catch (FileNotFoundException ex) {
97           throw new DocumentException(ex.getMessage(), ex);
98        }
99     }
100 
101    /***
102     * Parses the specified {@link org.xml.sax.InputSource}
103     * 
104     * @param source the source to parse
105     * @return the resulting DOM4J document
106     * @throws DocumentException when an error occurs while parsing
107     */
108    public Document read(InputSource source) throws DocumentException {
109       try {
110          return getReader().read(source);
111       }
112       catch (JAXBRuntimeException ex) {
113          Throwable cause = ex.getCause();
114          throw new DocumentException(cause.getMessage(), cause);
115       }
116    }
117 
118    /***
119     * Parses the specified {@link java.io.InputStream}
120     * 
121     * @param source the input stream to parse
122     * @return the resulting DOM4J document
123     * @throws DocumentException when an error occurs while parsing
124     */
125    public Document read(InputStream source) throws DocumentException {
126       try {
127          return getReader().read(source);
128       }
129       catch (JAXBRuntimeException ex) {
130          Throwable cause = ex.getCause();
131          throw new DocumentException(cause.getMessage(), cause);
132       }
133    }
134 
135    /***
136     * Parses the specified {@link java.io.InputStream} 
137     * 
138     * @param source the input stream to parse
139     * @param systemId is the URI for the input
140     * @return the resulting DOM4J document
141     * @throws DocumentException when an error occurs while parsing
142     */
143    public Document read(InputStream source, String systemId) throws DocumentException {
144       try {
145          return getReader().read(source);
146       }
147       catch (JAXBRuntimeException ex) {
148          Throwable cause = ex.getCause();
149          throw new DocumentException(cause.getMessage(), cause);
150       }
151    }
152 
153    /***
154     * Parses the specified {@link java.io.Reader} 
155     * 
156     * @param source the input reader to use
157     * @return the resulting DOM4J document
158     * @throws DocumentException when an error occurs while parsing
159     */
160    public Document read(Reader source) throws DocumentException {
161       try {
162          return getReader().read(source);
163       }
164       catch (JAXBRuntimeException ex) {
165          Throwable cause = ex.getCause();
166          throw new DocumentException(cause.getMessage(), cause);
167       }
168    }
169 
170    /***
171     * Parses the specified {@link java.io.Reader} 
172     * 
173     * @param source the input reader to parse
174     * @param systemId is the URI for the input
175     * @return the resulting DOM4J document
176     * @throws DocumentException when an error occurs while parsing
177     */
178    public Document read(Reader source, String systemId) throws DocumentException {
179       try {
180          return getReader().read(source);
181       }
182       catch (JAXBRuntimeException ex) {
183          Throwable cause = ex.getCause();
184          throw new DocumentException(cause.getMessage(), cause);
185       }
186    }
187 
188    /***
189     * Parses the the given URL or filename. 
190     * 
191     * @param source the location to parse
192     * @return the resulting DOM4J document
193     * @throws DocumentException when an error occurs while parsing
194     */
195    public Document read(String source) throws DocumentException {
196       try {
197          return getReader().read(source);
198       }
199       catch (JAXBRuntimeException ex) {
200          Throwable cause = ex.getCause();
201          throw new DocumentException(cause.getMessage(), cause);
202       }
203    }
204 
205    /***
206     * Parses the the given URL. 
207     * 
208     * @param source the URL to parse
209     * @return the resulting DOM4J document
210     * @throws DocumentException when an error occurs while parsing
211     */
212    public Document read(URL source) throws DocumentException {
213       try {
214          return getReader().read(source);
215       }
216       catch (JAXBRuntimeException ex) {
217          Throwable cause = ex.getCause();
218          throw new DocumentException(cause.getMessage(), cause);
219       }
220    }
221 
222    /***
223     * Registers a {@link JAXBObjectHandler} that will be supplied with the unmarshalled representation
224     * of the xml fragment whenever the specified path is encounted.
225     * 
226     * @param path the path to listen for
227     * @param handler the handler to be notified
228     */
229    public void addObjectHandler(String path, JAXBObjectHandler handler) {
230       getReader().addHandler(path, new UnmarshalElementHandler(this, handler));
231    }
232 
233    /***
234     * Removes the {@link JAXBObjectHandler} from the event based processor,
235     * for the specified element path.
236     * 
237     * @param path The path to remove the {@link JAXBObjectHandler} for
238     */
239    public void removeObjectHandler(String path) {
240       getReader().removeHandler(path);
241    }
242 
243    /***
244     * Removes all registered {@link JAXBObjectHandler} instances from the event based processor.
245     */
246    public void resetObjectHandlers() {
247       getReader().resetHandlers();
248    }
249 
250    /***
251     * When 'true', the DOM4J document will not be kept in memory while parsing.
252     * 
253     * @return Returns the pruneElements.
254     */
255    public boolean isPruneElements() {
256       return pruneElements;
257    }
258 
259    /***
260     * Set to true when DOM4J elements must immediately be pruned from the tree.
261     * The {@link Document} will not be available afterwards!
262     *  
263     * @param pruneElements 
264     */
265    public void setPruneElements(boolean pruneElements) {
266       this.pruneElements = pruneElements;
267       if (pruneElements) {
268          getReader().setDefaultHandler(new PruningElementHandler());
269       }
270    }
271 
272    private SAXReader getReader() {
273       if (reader == null) {
274          reader = new SAXReader();
275       }
276       return reader;
277    }
278 
279    private class UnmarshalElementHandler implements ElementHandler {
280 
281       private JAXBReader jaxbReader;
282       private JAXBObjectHandler handler;
283 
284       public UnmarshalElementHandler(JAXBReader documentReader, JAXBObjectHandler handler) {
285          this.jaxbReader = documentReader;
286          this.handler = handler;
287       }
288 
289       public void onStart(ElementPath elementPath) {
290       }
291 
292       public void onEnd(ElementPath elementPath) {
293          try {
294             org.dom4j.Element elem = elementPath.getCurrent();
295 
296             javax.xml.bind.Element jaxbObject = (javax.xml.bind.Element) jaxbReader.unmarshal(elem);
297 
298             if (jaxbReader.isPruneElements()) {
299                elem.detach();
300             }
301 
302             handler.handleObject(jaxbObject);
303          }
304          catch (Exception ex) {
305             throw new JAXBRuntimeException(ex);
306          }
307       }
308 
309    }
310 
311    private class PruningElementHandler implements ElementHandler {
312 
313       public PruningElementHandler() {
314       }
315 
316       public void onStart(ElementPath parm1) {
317       }
318 
319       public void onEnd(ElementPath elementPath) {
320          Element elem = elementPath.getCurrent();
321          elem.detach();
322          elem = null;
323       }
324 
325    }
326 
327 }
328 
329 
330 
331 
332 /*
333  * Redistribution and use of this software and associated documentation
334  * ("Software"), with or without modification, are permitted provided
335  * that the following conditions are met:
336  *
337  * 1. Redistributions of source code must retain copyright
338  *    statements and notices.  Redistributions must also contain a
339  *    copy of this document.
340  *
341  * 2. Redistributions in binary form must reproduce the
342  *    above copyright notice, this list of conditions and the
343  *    following disclaimer in the documentation and/or other
344  *    materials provided with the distribution.
345  *
346  * 3. The name "DOM4J" must not be used to endorse or promote
347  *    products derived from this Software without prior written
348  *    permission of MetaStuff, Ltd.  For written permission,
349  *    please contact dom4j-info@metastuff.com.
350  *
351  * 4. Products derived from this Software may not be called "DOM4J"
352  *    nor may "DOM4J" appear in their names without prior written
353  *    permission of MetaStuff, Ltd. DOM4J is a registered
354  *    trademark of MetaStuff, Ltd.
355  *
356  * 5. Due credit should be given to the DOM4J Project - 
357  *    http://www.dom4j.org
358  *
359  * THIS SOFTWARE IS PROVIDED BY METASTUFF, LTD. AND CONTRIBUTORS
360  * ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT
361  * NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
362  * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL
363  * METASTUFF, LTD. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
364  * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
365  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
366  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
367  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
368  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
369  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
370  * OF THE POSSIBILITY OF SUCH DAMAGE.
371  *
372  * Copyright 2001-2004 (C) MetaStuff, Ltd. All Rights Reserved.
373  *
374  * $Id: JAXBReader.java,v 1.1 2004/08/02 18:44:07 maartenc Exp $
375  */