1 /*
2  * Licensed to the Apache Software Foundation (ASF) under one or more
3  * contributor license agreements.  See the NOTICE file distributed with
4  * this work for additional information regarding copyright ownership.
5  * The ASF licenses this file to You under the Apache License, Version 2.0
6  * (the "License"); you may not use this file except in compliance with
7  * the License.  You may obtain a copy of the License at
8  *
9  *     http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  */
17 
18 // $Id: StreamSource.java 829971 2009-10-26 21:15:39Z mrglavas $
19 
20 package javax.xml.transform.stream;
21 
22 import java.io.File;
23 import java.io.InputStream;
24 import java.io.Reader;
25 import javax.xml.transform.Source;
26 
27 /**
28  * <p>Acts as an holder for a transformation Source in the form
29  * of a stream of XML markup.</p>
30  *
31  * <p><em>Note:</em> Due to their internal use of either a {@link Reader} or {@link InputStream} instance,
32  * <code>StreamSource</code> instances may only be used once.</p>
33  *
34  * @author <a href="Jeff.Suttor@Sun.com">Jeff Suttor</a>
35  * @version $Revision: 829971 $, $Date: 2009-10-26 14:15:39 -0700 (Mon, 26 Oct 2009) $
36  */
37 public class StreamSource implements Source {
38 
39     /** If {@link javax.xml.transform.TransformerFactory#getFeature}
40      * returns true when passed this value as an argument,
41      * the Transformer supports Source input of this type.
42      */
43     public static final String FEATURE =
44         "http://javax.xml.transform.stream.StreamSource/feature";
45 
46     /**
47      * <p>Zero-argument default constructor.  If this constructor is used, and
48      * no Stream source is set using
49      * {@link #setInputStream(java.io.InputStream inputStream)} or
50      * {@link #setReader(java.io.Reader reader)}, then the
51      * <code>Transformer</code> will
52      * create an empty source {@link java.io.InputStream} using
53      * {@link java.io.InputStream#InputStream() new InputStream()}.</p>
54      *
55      * @see javax.xml.transform.Transformer#transform(Source xmlSource, Result outputTarget)
56      */
StreamSource()57     public StreamSource() { }
58 
59     /**
60      * Construct a StreamSource from a byte stream.  Normally,
61      * a stream should be used rather than a reader, so
62      * the XML parser can resolve character encoding specified
63      * by the XML declaration.
64      *
65      * <p>If this constructor is used to process a stylesheet, normally
66      * setSystemId should also be called, so that relative URI references
67      * can be resolved.</p>
68      *
69      * @param inputStream A valid InputStream reference to an XML stream.
70      */
StreamSource(InputStream inputStream)71     public StreamSource(InputStream inputStream) {
72         setInputStream(inputStream);
73     }
74 
75     /**
76      * Construct a StreamSource from a byte stream.  Normally,
77      * a stream should be used rather than a reader, so that
78      * the XML parser can resolve character encoding specified
79      * by the XML declaration.
80      *
81      * <p>This constructor allows the systemID to be set in addition
82      * to the input stream, which allows relative URIs
83      * to be processed.</p>
84      *
85      * @param inputStream A valid InputStream reference to an XML stream.
86      * @param systemId Must be a String that conforms to the URI syntax.
87      */
StreamSource(InputStream inputStream, String systemId)88     public StreamSource(InputStream inputStream, String systemId) {
89         setInputStream(inputStream);
90         setSystemId(systemId);
91     }
92 
93     /**
94      * Construct a StreamSource from a character reader.  Normally,
95      * a stream should be used rather than a reader, so that
96      * the XML parser can resolve character encoding specified
97      * by the XML declaration.  However, in many cases the encoding
98      * of the input stream is already resolved, as in the case of
99      * reading XML from a StringReader.
100      *
101      * @param reader A valid Reader reference to an XML character stream.
102      */
StreamSource(Reader reader)103     public StreamSource(Reader reader) {
104         setReader(reader);
105     }
106 
107     /**
108      * Construct a StreamSource from a character reader.  Normally,
109      * a stream should be used rather than a reader, so that
110      * the XML parser may resolve character encoding specified
111      * by the XML declaration.  However, in many cases the encoding
112      * of the input stream is already resolved, as in the case of
113      * reading XML from a StringReader.
114      *
115      * @param reader A valid Reader reference to an XML character stream.
116      * @param systemId Must be a String that conforms to the URI syntax.
117      */
StreamSource(Reader reader, String systemId)118     public StreamSource(Reader reader, String systemId) {
119         setReader(reader);
120         setSystemId(systemId);
121     }
122 
123     /**
124      * Construct a StreamSource from a URL.
125      *
126      * @param systemId Must be a String that conforms to the URI syntax.
127      */
StreamSource(String systemId)128     public StreamSource(String systemId) {
129         this.systemId = systemId;
130     }
131 
132     /**
133      * Construct a StreamSource from a File.
134      *
135      * @param f Must a non-null File reference.
136      */
StreamSource(File f)137     public StreamSource(File f) {
138         setSystemId(f);
139     }
140 
141     /**
142      * Set the byte stream to be used as input.  Normally,
143      * a stream should be used rather than a reader, so that
144      * the XML parser can resolve character encoding specified
145      * by the XML declaration.
146      *
147      * <p>If this Source object is used to process a stylesheet, normally
148      * setSystemId should also be called, so that relative URL references
149      * can be resolved.</p>
150      *
151      * @param inputStream A valid InputStream reference to an XML stream.
152      */
setInputStream(InputStream inputStream)153     public void setInputStream(InputStream inputStream) {
154         this.inputStream = inputStream;
155     }
156 
157     /**
158      * Get the byte stream that was set with setByteStream.
159      *
160      * @return The byte stream that was set with setByteStream, or null
161      * if setByteStream or the ByteStream constructor was not called.
162      */
getInputStream()163     public InputStream getInputStream() {
164         return inputStream;
165     }
166 
167     /**
168      * Set the input to be a character reader.  Normally,
169      * a stream should be used rather than a reader, so that
170      * the XML parser can resolve character encoding specified
171      * by the XML declaration.  However, in many cases the encoding
172      * of the input stream is already resolved, as in the case of
173      * reading XML from a StringReader.
174      *
175      * @param reader A valid Reader reference to an XML CharacterStream.
176      */
setReader(Reader reader)177     public void setReader(Reader reader) {
178         this.reader = reader;
179     }
180 
181     /**
182      * Get the character stream that was set with setReader.
183      *
184      * @return The character stream that was set with setReader, or null
185      * if setReader or the Reader constructor was not called.
186      */
getReader()187     public Reader getReader() {
188         return reader;
189     }
190 
191     /**
192      * Set the public identifier for this Source.
193      *
194      * <p>The public identifier is always optional: if the application
195      * writer includes one, it will be provided as part of the
196      * location information.</p>
197      *
198      * @param publicId The public identifier as a string.
199      */
setPublicId(String publicId)200     public void setPublicId(String publicId) {
201         this.publicId = publicId;
202     }
203 
204     /**
205      * Get the public identifier that was set with setPublicId.
206      *
207      * @return The public identifier that was set with setPublicId, or null
208      * if setPublicId was not called.
209      */
getPublicId()210     public String getPublicId() {
211         return publicId;
212     }
213 
214     /**
215      * Set the system identifier for this Source.
216      *
217      * <p>The system identifier is optional if there is a byte stream
218      * or a character stream, but it is still useful to provide one,
219      * since the application can use it to resolve relative URIs
220      * and can include it in error messages and warnings (the parser
221      * will attempt to open a connection to the URI only if
222      * there is no byte stream or character stream specified).</p>
223      *
224      * @param systemId The system identifier as a URL string.
225      */
setSystemId(String systemId)226     public void setSystemId(String systemId) {
227         this.systemId = systemId;
228     }
229 
230     /**
231      * Get the system identifier that was set with setSystemId.
232      *
233      * @return The system identifier that was set with setSystemId, or null
234      * if setSystemId was not called.
235      */
getSystemId()236     public String getSystemId() {
237         return systemId;
238     }
239 
240     /**
241      * Set the system ID from a File reference.
242      *
243      * @param f Must a non-null File reference.
244      */
setSystemId(File f)245     public void setSystemId(File f) {
246         this.systemId = FilePathToURI.filepath2URI(f.getAbsolutePath());
247     }
248 
249     //////////////////////////////////////////////////////////////////////
250     // Internal state.
251     //////////////////////////////////////////////////////////////////////
252 
253     /**
254      * The public identifier for this input source, or null.
255      */
256     private String publicId;
257 
258     /**
259      * The system identifier as a URL string, or null.
260      */
261     private String systemId;
262 
263     /**
264      * The byte stream for this Source, or null.
265      */
266     private InputStream inputStream;
267 
268     /**
269      * The character stream for this Source, or null.
270      */
271     private Reader reader;
272 }
273