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: SAXSource.java 446598 2006-09-15 12:55:40Z jeremias $
19
20package javax.xml.transform.sax;
21
22import javax.xml.transform.Source;
23import javax.xml.transform.stream.StreamSource;
24import org.xml.sax.InputSource;
25import org.xml.sax.XMLReader;
26
27/**
28 * <p>Acts as an holder for SAX-style Source.</p>
29 *
30 * <p>Note that XSLT requires namespace support. Attempting to transform an
31 * input source that is not
32 * generated with a namespace-aware parser may result in errors.
33 * Parsers can be made namespace aware by calling the
34 * {@link javax.xml.parsers.SAXParserFactory#setNamespaceAware(boolean awareness)} method.</p>
35 *
36 * @author <a href="mailto:Jeff.Suttor@Sun.com">Jeff Suttor</a>
37 * @version $Revision: 446598 $, $Date: 2006-09-15 05:55:40 -0700 (Fri, 15 Sep 2006) $
38 */
39public class SAXSource implements Source {
40
41    /**
42     * If {@link javax.xml.transform.TransformerFactory#getFeature}
43     * returns true when passed this value as an argument,
44     * the Transformer supports Source input of this type.
45     */
46    public static final String FEATURE =
47        "http://javax.xml.transform.sax.SAXSource/feature";
48
49    /**
50     * <p>Zero-argument default constructor.  If this constructor is used, and
51     * no SAX source is set using
52     * {@link #setInputSource(InputSource inputSource)} , then the
53     * <code>Transformer</code> will
54     * create an empty source {@link org.xml.sax.InputSource} using
55     * {@link org.xml.sax.InputSource#InputSource() new InputSource()}.</p>
56     *
57     * @see javax.xml.transform.Transformer#transform(Source xmlSource, Result outputTarget)
58     */
59    public SAXSource() { }
60
61    /**
62     * Create a <code>SAXSource</code>, using an {@link org.xml.sax.XMLReader}
63     * and a SAX InputSource. The {@link javax.xml.transform.Transformer}
64     * or {@link javax.xml.transform.sax.SAXTransformerFactory} will set itself
65     * to be the reader's {@link org.xml.sax.ContentHandler}, and then will call
66     * reader.parse(inputSource).
67     *
68     * @param reader An XMLReader to be used for the parse.
69     * @param inputSource A SAX input source reference that must be non-null
70     * and that will be passed to the reader parse method.
71     */
72    public SAXSource(XMLReader reader, InputSource inputSource) {
73        this.reader      = reader;
74        this.inputSource = inputSource;
75    }
76
77    /**
78     * Create a <code>SAXSource</code>, using a SAX <code>InputSource</code>.
79     * The {@link javax.xml.transform.Transformer} or
80     * {@link javax.xml.transform.sax.SAXTransformerFactory} creates a
81     * reader via {@link org.xml.sax.helpers.XMLReaderFactory}
82     * (if setXMLReader is not used), sets itself as
83     * the reader's {@link org.xml.sax.ContentHandler}, and calls
84     * reader.parse(inputSource).
85     *
86     * @param inputSource An input source reference that must be non-null
87     * and that will be passed to the parse method of the reader.
88     */
89    public SAXSource(InputSource inputSource) {
90        this.inputSource = inputSource;
91    }
92
93    /**
94     * Set the XMLReader to be used for the Source.
95     *
96     * @param reader A valid XMLReader or XMLFilter reference.
97     */
98    public void setXMLReader(XMLReader reader) {
99        this.reader = reader;
100    }
101
102    /**
103     * Get the XMLReader to be used for the Source.
104     *
105     * @return A valid XMLReader or XMLFilter reference, or null.
106     */
107    public XMLReader getXMLReader() {
108        return reader;
109    }
110
111    /**
112     * Set the SAX InputSource to be used for the Source.
113     *
114     * @param inputSource A valid InputSource reference.
115     */
116    public void setInputSource(InputSource inputSource) {
117        this.inputSource = inputSource;
118    }
119
120    /**
121     * Get the SAX InputSource to be used for the Source.
122     *
123     * @return A valid InputSource reference, or null.
124     */
125    public InputSource getInputSource() {
126        return inputSource;
127    }
128
129    /**
130     * Set the system identifier for this Source.  If an input source
131     * has already been set, it will set the system ID or that
132     * input source, otherwise it will create a new input source.
133     *
134     * <p>The system identifier is optional if there is a byte stream
135     * or a character stream, but it is still useful to provide one,
136     * since the application can use it to resolve relative URIs
137     * and can include it in error messages and warnings (the parser
138     * will attempt to open a connection to the URI only if
139     * no byte stream or character stream is specified).</p>
140     *
141     * @param systemId The system identifier as a URI string.
142     */
143    public void setSystemId(String systemId) {
144
145        if (null == inputSource) {
146            inputSource = new InputSource(systemId);
147        } else {
148            inputSource.setSystemId(systemId);
149        }
150    }
151
152    /**
153     * <p>Get the base ID (URI or system ID) from where URIs
154     * will be resolved.</p>
155     *
156     * @return Base URL for the <code>Source</code>, or <code>null</code>.
157     */
158    public String getSystemId() {
159
160        if (inputSource == null) {
161            return null;
162        } else {
163            return inputSource.getSystemId();
164        }
165    }
166
167    /**
168     * The XMLReader to be used for the source tree input. May be null.
169     */
170    private XMLReader reader;
171
172    /**
173     * <p>The SAX InputSource to be used for the source tree input.
174     * Should not be <code>null<code>.</p>
175     */
176    private InputSource inputSource;
177
178    /**
179     * Attempt to obtain a SAX InputSource object from a Source
180     * object.
181     *
182     * @param source Must be a non-null Source reference.
183     *
184     * @return An InputSource, or null if Source can not be converted.
185     */
186    public static InputSource sourceToInputSource(Source source) {
187
188        if (source instanceof SAXSource) {
189            return ((SAXSource) source).getInputSource();
190        } else if (source instanceof StreamSource) {
191            StreamSource ss      = (StreamSource) source;
192            InputSource  isource = new InputSource(ss.getSystemId());
193
194            isource.setByteStream(ss.getInputStream());
195            isource.setCharacterStream(ss.getReader());
196            isource.setPublicId(ss.getPublicId());
197
198            return isource;
199        } else {
200            return null;
201        }
202    }
203}
204
205