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