KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > thoughtworks > xstream > io > xml > TraxSource


1 package com.thoughtworks.xstream.io.xml;
2
3 import com.thoughtworks.xstream.XStream;
4 import org.xml.sax.InputSource JavaDoc;
5 import org.xml.sax.SAXException JavaDoc;
6 import org.xml.sax.XMLFilter JavaDoc;
7 import org.xml.sax.XMLReader JavaDoc;
8
9 import javax.xml.transform.sax.SAXSource JavaDoc;
10 import java.util.ArrayList JavaDoc;
11 import java.util.List JavaDoc;
12
13 /**
14  * A {@link SAXSource JAXP TrAX Source} that enables using XStream
15  * object serialization as direct input for XSLT processors without
16  * resorting to an intermediate representation such as text XML, DOM
17  * or DOM4J.
18  * <p/>
19  * The following example shows how to apply an XSL Transformation
20  * to a set of Java objects gathered into a List
21  * (<code>source</code>):</p>
22  * <pre><code>
23  * public static String transform(List source, String stylesheet) {
24  * try {
25  * Transformer transformer = TransformerFactory.newInstance()
26  * .newTransformer(new StreamSource(stylesheet));
27  * XStreamSource in = new XStreamSource(source);
28  * Writer out = new StringWriter();
29  * transformer.transform(in, new StreamResult(out));
30  * return out.toString();
31  * }
32  * catch (TransformerException e) {
33  * throw new RuntimeException("XSLT Transformation failed", e);
34  * }
35  * }
36  * </code></pre>
37  *
38  * @author Laurent Bihanic
39  */

40 public class TraxSource extends SAXSource JavaDoc {
41
42     /**
43      * If {@link javax.xml.transform.TransformerFactory#getFeature}
44      * returns <code>true</code> when passed this value as an
45      * argument, the Transformer natively supports XStream.
46      * <p/>
47      * <strong>Note</strong>: This implementation does not override
48      * the {@link SAXSource#FEATURE} value defined by its superclass
49      * to be considered as a SAXSource by Transformer implementations
50      * not natively supporting this XStream-specific source
51      * </p>
52      */

53     public final static String JavaDoc XSTREAM_FEATURE =
54             "http://com.thoughtworks.xstream/XStreamSource/feature";
55
56     /**
57      * The XMLReader object associated to this source or
58      * <code>null</code> if no XMLReader has yet been requested.
59      *
60      * @see #getXMLReader
61      */

62     private XMLReader JavaDoc xmlReader = null;
63
64     /**
65      * The configured XStream facade to use for serializing objects.
66      */

67     private XStream xstream = null;
68
69     /**
70      * The list of Java objects to be serialized.
71      */

72     private List JavaDoc source = null;
73
74
75     //-------------------------------------------------------------------------
76
// Constructors
77
//-------------------------------------------------------------------------
78

79     /**
80      * Creates a XStream TrAX source.
81      */

82     public TraxSource() {
83         super(new InputSource JavaDoc());
84     }
85
86     /**
87      * Creates a XStream TrAX source, specifying the object to
88      * marshal.
89      *
90      * @param source the object to marshal.
91      * @throws IllegalArgumentException if <code>source</code> is
92      * <code>null</code>.
93      * @see #setSource(java.lang.Object)
94      */

95     public TraxSource(Object JavaDoc source) {
96         super(new InputSource JavaDoc());
97
98         this.setSource(source);
99     }
100
101     /**
102      * Creates a XStream TrAX source, specifying the object to
103      * marshal and a configured (with aliases) XStream facade.
104      *
105      * @param source the object to marshal.
106      * @param xstream a configured XStream facade.
107      * @throws IllegalArgumentException if <code>source</code> or
108      * <code>xstream</code> is <code>null</code>.
109      * @see #setSource(java.lang.Object)
110      * @see #setXStream(com.thoughtworks.xstream.XStream)
111      */

112     public TraxSource(Object JavaDoc source, XStream xstream) {
113         super(new InputSource JavaDoc());
114
115         this.setSource(source);
116         this.setXStream(xstream);
117     }
118
119     /**
120      * Creates a XStream TrAX source, setting the objects to
121      * marshal.
122      *
123      * @param source the list of objects to marshal.
124      * @throws IllegalArgumentException if <code>source</code> is
125      * <code>null</code> or empty.
126      * @see #setSourceAsList(java.util.List)
127      */

128     public TraxSource(List JavaDoc source) {
129         super(new InputSource JavaDoc());
130
131         this.setSourceAsList(source);
132     }
133
134     /**
135      * Creates a XStream TrAX source, setting the objects to
136      * marshal and a configured (with aliases) XStream facade.
137      *
138      * @param source the list of objects to marshal.
139      * @param xstream a configured XStream facade.
140      * @throws IllegalArgumentException if <code>source</code> or
141      * <code>xstream</code> is <code>null</code> or
142      * <code>source</code> is empty.
143      * @see #setSourceAsList(java.util.List)
144      * @see #setXStream(com.thoughtworks.xstream.XStream)
145      */

146     public TraxSource(List JavaDoc source, XStream xstream) {
147         super(new InputSource JavaDoc());
148
149         this.setSourceAsList(source);
150         this.setXStream(xstream);
151     }
152
153     //-------------------------------------------------------------------------
154
// SAXSource overwritten methods
155
//-------------------------------------------------------------------------
156

157     /**
158      * Sets the SAX InputSource to be used for the Source.
159      * <p/>
160      * As this implementation only supports object lists as data
161      * source, this method always throws an
162      * {@link UnsupportedOperationException}.
163      * </p>
164      *
165      * @param inputSource a valid InputSource reference.
166      * @throws UnsupportedOperationException always!
167      */

168     public void setInputSource(InputSource JavaDoc inputSource) {
169         throw new UnsupportedOperationException JavaDoc();
170     }
171
172     /**
173      * Set the XMLReader to be used for the Source.
174      * <p/>
175      * As this implementation only supports object lists as data
176      * source, this method throws an
177      * {@link UnsupportedOperationException} if the provided reader
178      * object does not implement the SAX {@link XMLFilter}
179      * interface. Otherwise, a {@link SaxWriter} instance will be
180      * attached as parent of the filter chain.</p>
181      *
182      * @param reader a valid XMLReader or XMLFilter reference.
183      * @throws UnsupportedOperationException if <code>reader</code>
184      * is not a SAX
185      * {@link XMLFilter}.
186      * @see #getXMLReader
187      */

188     public void setXMLReader(XMLReader JavaDoc reader) {
189         this.createXMLReader(reader);
190     }
191
192     /**
193      * Returns the XMLReader to be used for the Source.
194      * <p/>
195      * This implementation returns a specific XMLReader
196      * ({@link SaxWriter}) generating the XML from a list of input
197      * objects.
198      * </p>
199      *
200      * @return an XMLReader generating the XML from a list of input
201      * objects.
202      */

203     public XMLReader JavaDoc getXMLReader() {
204         if (this.xmlReader == null) {
205             this.createXMLReader(null);
206         }
207         return this.xmlReader;
208     }
209
210
211     //-------------------------------------------------------------------------
212
// Specific implementation
213
//-------------------------------------------------------------------------
214

215     /**
216      * Sets the XStream facade to use when marshalling objects.
217      *
218      * @param xstream a configured XStream facade.
219      * @throws IllegalArgumentException if <code>xstream</code> is
220      * <code>null</code>.
221      */

222     public void setXStream(XStream xstream) {
223         if (xstream == null) {
224             throw new IllegalArgumentException JavaDoc("xstream");
225         }
226         this.xstream = xstream;
227
228         this.configureXMLReader();
229     }
230
231     /**
232      * Sets the object to marshal.
233      *
234      * @param obj the object to marshal.
235      * @throws IllegalArgumentException if <code>source</code> is
236      * <code>null</code>.
237      */

238     public void setSource(Object JavaDoc obj) {
239         if (obj == null) {
240             throw new IllegalArgumentException JavaDoc("obj");
241         }
242         List JavaDoc list = new ArrayList JavaDoc(1);
243         list.add(obj);
244
245         this.setSourceAsList(list);
246     }
247
248     /**
249      * Sets the list of objects to marshal.
250      * <p/>
251      * When dealing with non-text input (such as SAX or DOM), XSLT
252      * processors support multiple root node children for the source
253      * tree (see
254      * <a HREF="http://www.w3.org/TR/xslt#root-node-children">section 3.1</a>
255      * of the &quot;XSL Transformations (XSLT) Version 1.0&quot;
256      * specification. Using a list of objects as source makes use
257      * of this feature and allows creating XML documents merging
258      * the XML serialization of several Java objects.
259      *
260      * @param list the list of objects to marshal.
261      * @throws IllegalArgumentException if <code>source</code> is
262      * <code>null</code> or empty.
263      */

264     public void setSourceAsList(List JavaDoc list) {
265         if ((list == null) || (list.isEmpty())) {
266             throw new IllegalArgumentException JavaDoc("list");
267         }
268         this.source = list;
269
270         this.configureXMLReader();
271     }
272
273     private void createXMLReader(XMLReader JavaDoc filterChain) {
274         if (filterChain == null) {
275             this.xmlReader = new SaxWriter();
276         } else {
277             if (filterChain instanceof XMLFilter JavaDoc) {
278                 // Connect the filter chain to a document reader.
279
XMLFilter JavaDoc filter = (XMLFilter JavaDoc) filterChain;
280                 while (filter.getParent() instanceof XMLFilter JavaDoc) {
281                     filter = (XMLFilter JavaDoc) (filter.getParent());
282                 }
283                 filter.setParent(new SaxWriter());
284
285                 // Read XML data from filter chain.
286
this.xmlReader = filterChain;
287             } else {
288                 throw new UnsupportedOperationException JavaDoc();
289             }
290         }
291         this.configureXMLReader();
292     }
293
294     private void configureXMLReader() {
295         if (this.xmlReader != null) {
296             try {
297                 if (this.xstream != null) {
298                     this.xmlReader.setProperty(SaxWriter.CONFIGURED_XSTREAM_PROPERTY, this.xstream);
299                 }
300                 if (this.source != null) {
301                     this.xmlReader.setProperty(SaxWriter.SOURCE_OBJECT_LIST_PROPERTY, this.source);
302                 }
303             } catch (SAXException JavaDoc e) {
304                 throw new IllegalArgumentException JavaDoc(e.getMessage());
305             }
306         }
307     }
308 }
309
310
Popular Tags