KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > net > sf > saxon > event > Sender


1 package net.sf.saxon.event;
2
3 import net.sf.saxon.AugmentedSource;
4 import net.sf.saxon.Configuration;
5 import net.sf.saxon.StandardErrorHandler;
6 import net.sf.saxon.om.ExternalObjectModel;
7 import net.sf.saxon.om.NamePool;
8 import net.sf.saxon.om.NodeInfo;
9 import net.sf.saxon.om.Validation;
10 import net.sf.saxon.pull.PullProvider;
11 import net.sf.saxon.pull.PullPushCopier;
12 import net.sf.saxon.pull.PullSource;
13 import net.sf.saxon.trans.DynamicError;
14 import net.sf.saxon.trans.XPathException;
15 import net.sf.saxon.type.Type;
16 import org.xml.sax.*;
17
18 import javax.xml.transform.Source JavaDoc;
19 import javax.xml.transform.dom.DOMSource JavaDoc;
20 import javax.xml.transform.sax.SAXSource JavaDoc;
21 import javax.xml.transform.stream.StreamSource JavaDoc;
22 import java.util.List JavaDoc;
23
24 /**
25 * Sender is a helper class that sends events to a Receiver from any kind of Source object
26 */

27
28 public class Sender {
29
30     PipelineConfiguration pipe;
31     public Sender (PipelineConfiguration pipe) {
32         this.pipe = pipe;
33     }
34
35     /**
36     * Send the contents of a Source to a Receiver. Note that if the Source
37      * identifies an element node rather than a document node, only the subtree
38      * rooted at that element will be copied.
39     * @param source the document or element to be copied
40     * @param receiver the destination to which it is to be copied
41     */

42
43     public void send(Source source, Receiver receiver)
44     throws XPathException {
45         send(source, receiver, false);
46     }
47
48     /**
49      * Send the contents of a Source to a Receiver. Note that if the Source
50      * identifies an element node rather than a document node, only the subtree
51      * rooted at that element will be copied.
52      * @param source the document or element to be copied
53      * @param receiver the destination to which it is to be copied
54      * @param isFinal set to true when the document is being processed purely for the
55      * sake of validation, in which case multiple validation errors in the source can be
56      * reported.
57      */

58
59     public void send(Source source, Receiver receiver, boolean isFinal)
60     throws XPathException {
61         Configuration config = pipe.getConfiguration();
62         receiver.setPipelineConfiguration(pipe);
63         receiver.setSystemId(source.getSystemId());
64
65         int validation = config.getSchemaValidationMode();
66         if (isFinal) {
67             // this ensures that the Validate command produces multiple error messages
68
validation |= Validation.VALIDATE_OUTPUT;
69         }
70
71         XMLReader parser = null;
72         if (source instanceof AugmentedSource) {
73             int localValidate = ((AugmentedSource)source).getSchemaValidation();
74             if (localValidate != Validation.DEFAULT) {
75                 validation = localValidate;
76             }
77             parser = ((AugmentedSource)source).getXMLReader();
78
79             List JavaDoc filters = ((AugmentedSource)source).getFilters();
80             if (filters != null) {
81                 for (int i=filters.size()-1; i>=0; i--) {
82                     ProxyReceiver filter = (ProxyReceiver)filters.get(i);
83                     filter.setPipelineConfiguration(pipe);
84                     filter.setSystemId(source.getSystemId());
85                     filter.setUnderlyingReceiver(receiver);
86                     receiver = filter;
87                 }
88             }
89
90             source = ((AugmentedSource)source).getContainedSource();
91         }
92
93         if (source instanceof NodeInfo) {
94             NodeInfo ns = (NodeInfo)source;
95             String JavaDoc baseURI = ns.getBaseURI();
96             int val = validation & Validation.VALIDATION_MODE_MASK;
97             if (val != Validation.PRESERVE) {
98                 receiver = config.getDocumentValidator(receiver, baseURI, config.getNamePool(), val, null);
99             }
100
101             int kind = ns.getNodeKind();
102             if (kind != Type.DOCUMENT && kind != Type.ELEMENT) {
103                 throw new IllegalArgumentException JavaDoc("Sender can only handle document or element nodes");
104             }
105             receiver.setSystemId(baseURI);
106             sendDocumentInfo(ns, receiver, pipe.getConfiguration().getNamePool());
107             return;
108
109         } else if (source instanceof PullSource) {
110             sendPullSource((PullSource)source, receiver, validation);
111             return;
112
113         } else if (source instanceof SAXSource JavaDoc) {
114             sendSAXSource((SAXSource JavaDoc)source, receiver, validation);
115             return;
116
117         } else if (source instanceof StreamSource JavaDoc) {
118             StreamSource JavaDoc ss = (StreamSource JavaDoc)source;
119             String JavaDoc url = source.getSystemId();
120             InputSource is = new InputSource(url);
121             is.setCharacterStream(ss.getReader());
122             is.setByteStream(ss.getInputStream());
123             boolean reuseParser = false;
124             if (parser == null) {
125                 parser = config.getSourceParser();
126                 reuseParser = true;
127             }
128             SAXSource JavaDoc sax = new SAXSource JavaDoc(parser, is);
129             sax.setSystemId(source.getSystemId());
130             sendSAXSource(sax, receiver, validation);
131             if (reuseParser) {
132                 config.reuseSourceParser(parser);
133             }
134             return;
135         } else {
136             if ((validation & Validation.VALIDATION_MODE_MASK) != Validation.PRESERVE) {
137                 // Add a document validator to the pipeline
138
receiver = config.getDocumentValidator(receiver,
139                                                    source.getSystemId(),
140                                                    config.getNamePool(),
141                                                    validation, null);
142             }
143
144             // See if there is a registered SourceResolver than can handle it
145
Source newSource = config.getSourceResolver().resolveSource(source, config);
146             if (newSource instanceof StreamSource JavaDoc ||
147                     newSource instanceof SAXSource JavaDoc ||
148                     newSource instanceof NodeInfo ||
149                     newSource instanceof PullSource) {
150                 send(newSource, receiver, isFinal);
151             }
152
153             // See if there is a registered external object model that knows about this kind of source
154

155             List JavaDoc externalObjectModels = config.getExternalObjectModels();
156             for (int m=0; m<externalObjectModels.size(); m++) {
157                 ExternalObjectModel model = (ExternalObjectModel)externalObjectModels.get(m);
158                 boolean done = model.sendSource(source, receiver, pipe);
159                 if (done) {
160                     return;
161                 }
162             }
163
164         }
165         if (source instanceof DOMSource JavaDoc) {
166             throw new DynamicError("DOMSource cannot be processed: check that saxon8-dom.jar is on the classpath");
167         }
168         throw new DynamicError("A source of type " + source.getClass().getName() +
169                 " is not supported in this environment");
170     }
171
172
173     private void sendDocumentInfo(NodeInfo top, Receiver receiver, NamePool namePool)
174     throws XPathException {
175         if (top.getNamePool() != namePool) {
176             // This happens for example when turning an arbitrary DocumentInfo tree into a stylesheet
177
NamePoolConverter converter = new NamePoolConverter(top.getNamePool(), namePool);
178             converter.setUnderlyingReceiver(receiver);
179             receiver = converter;
180         }
181         DocumentSender sender = new DocumentSender(top);
182         sender.send(receiver);
183     }
184
185 // private void sendDOMSource(DOMSource source, Receiver receiver, int validation)
186
// throws XPathException {
187
// Node startNode = source.getNode();
188
// Configuration config = pipe.getConfiguration();
189
// NamePool pool = config.getNamePool();
190
// if (startNode instanceof DocumentInfo) {
191
// sendDocumentInfo((DocumentInfo)startNode, receiver, pool);
192
// } else {
193
// if ((validation & Validation.VALIDATION_MODE_MASK) != Validation.PRESERVE) {
194
// // Add a document validator to the pipeline
195
// receiver = config.getDocumentValidator(receiver,
196
// source.getSystemId(),
197
// pool,
198
// validation);
199
// }
200
// DOMSender driver = new DOMSender();
201
// driver.setStartNode(startNode);
202
// driver.setReceiver(receiver);
203
// driver.setPipelineConfiguration(pipe);
204
// driver.setSystemId(source.getSystemId());
205
// driver.send();
206
// }
207
// }
208

209     private void sendSAXSource(SAXSource JavaDoc source, Receiver receiver, int validation)
210     throws XPathException {
211         XMLReader parser = source.getXMLReader();
212         boolean reuseParser = false;
213         if (parser==null) {
214             SAXSource JavaDoc ss = new SAXSource JavaDoc();
215             ss.setInputSource(source.getInputSource());
216             ss.setSystemId(source.getSystemId());
217             parser = pipe.getConfiguration().getSourceParser();
218             ss.setXMLReader(parser);
219             source = ss;
220             reuseParser = true;
221         }
222
223         if (parser.getErrorHandler()==null) {
224             parser.setErrorHandler(new StandardErrorHandler(pipe.getErrorListener()));
225         }
226
227         try {
228             parser.setFeature("http://xml.org/sax/features/namespaces", true);
229         } catch (SAXNotSupportedException err) { // SAX2 parsers MUST support this feature!
230
throw new DynamicError(
231                 "The SAX2 parser does not recognize the 'namespaces' feature");
232         } catch (SAXNotRecognizedException err) {
233             throw new DynamicError(
234                 "The SAX2 parser does not support setting the 'namespaces' feature to true");
235         }
236
237         try {
238             parser.setFeature("http://xml.org/sax/features/namespace-prefixes", false);
239         } catch (SAXNotSupportedException err) { // SAX2 parsers MUST support this feature!
240
throw new DynamicError(
241                 "The SAX2 parser does not recognize the 'namespace-prefixes' feature");
242         } catch (SAXNotRecognizedException err) {
243             throw new DynamicError(
244                 "The SAX2 parser does not support setting the 'namespace-prefixes' feature to false");
245         }
246
247         if ((validation & Validation.VALIDATION_MODE_MASK) != Validation.PRESERVE) {
248             // Add a document validator to the pipeline
249
Configuration config = pipe.getConfiguration();
250             receiver = config.getDocumentValidator(receiver,
251                                                    source.getSystemId(),
252                                                    config.getNamePool(),
253                                                    validation, null);
254         }
255
256         ReceivingContentHandler ce = new ReceivingContentHandler();
257         ce.setReceiver(receiver);
258         ce.setPipelineConfiguration(pipe);
259         parser.setContentHandler(ce);
260         parser.setDTDHandler(ce);
261
262         try {
263             parser.setProperty("http://xml.org/sax/properties/lexical-handler", ce);
264         } catch (SAXNotSupportedException err) { // this just means we won't see the comments
265
} catch (SAXNotRecognizedException err) {
266         }
267
268         try {
269             parser.parse(source.getInputSource());
270         } catch (SAXException err) {
271             Exception JavaDoc nested = err.getException();
272             if (nested instanceof XPathException) {
273                 throw (XPathException)nested;
274             } else if (nested instanceof RuntimeException JavaDoc) {
275                 throw (RuntimeException JavaDoc)nested;
276             } else {
277                 throw new DynamicError(err);
278             }
279         } catch (java.io.IOException JavaDoc err) {
280             throw new DynamicError(err);
281         }
282         if (reuseParser) {
283             pipe.getConfiguration().reuseSourceParser(parser);
284         }
285     }
286
287     private void sendPullSource(PullSource source, Receiver receiver, int validation)
288             throws XPathException {
289         if (validation != Validation.PRESERVE && validation != Validation.STRIP) {
290             throw new DynamicError("Validation is not currently supported with a PullSource");
291         }
292         receiver.open();
293         PullProvider provider = source.getPullProvider();
294         provider.setPipelineConfiguration(pipe);
295         receiver.setPipelineConfiguration(pipe);
296         PullPushCopier copier = new PullPushCopier(provider, receiver);
297         copier.copy();
298         receiver.close();
299     }
300
301 }
302
303 //
304
// The contents of this file are subject to the Mozilla Public License Version 1.0 (the "License");
305
// you may not use this file except in compliance with the License. You may obtain a copy of the
306
// License at http://www.mozilla.org/MPL/
307
//
308
// Software distributed under the License is distributed on an "AS IS" basis,
309
// WITHOUT WARRANTY OF ANY KIND, either express or implied.
310
// See the License for the specific language governing rights and limitations under the License.
311
//
312
// The Original Code is: all this file.
313
//
314
// The Initial Developer of the Original Code is Michael H. Kay
315
//
316
// Portions created by (your name) are Copyright (C) (your legal entity). All Rights Reserved.
317
//
318
// Contributor(s): none.
319
//
320
Popular Tags