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 
20 package javax.xml.transform.sax;
21 
22 import javax.xml.transform.Source;
23 import javax.xml.transform.stream.StreamSource;
24 import org.xml.sax.InputSource;
25 import 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  */
39 public 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      */
SAXSource()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      */
SAXSource(XMLReader reader, InputSource inputSource)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      */
SAXSource(InputSource inputSource)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      */
setXMLReader(XMLReader reader)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      */
getXMLReader()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      */
setInputSource(InputSource inputSource)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      */
getInputSource()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      */
setSystemId(String systemId)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      */
getSystemId()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      */
sourceToInputSource(Source source)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