KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > icl > saxon > output > ContentHandlerProxy


1 package com.icl.saxon.output;
2 import com.icl.saxon.*;
3 import com.icl.saxon.om.NamePool;
4 import com.icl.saxon.om.Namespace;
5 import org.xml.sax.*;
6 import org.xml.sax.helpers.AttributesImpl JavaDoc;
7 import org.xml.sax.ext.LexicalHandler JavaDoc;
8 import java.io.*;
9 import java.util.*;
10 import javax.xml.transform.Result JavaDoc;
11 import javax.xml.transform.TransformerException JavaDoc;
12
13 /**
14 * A ContentHandlerProxy is an Emitter that filters data before passing it to an
15 * underlying SAX2 ContentHandler. Relevant events (notably comments) can also be
16 * fed to a LexicalHandler.
17
18 * Note that in general the output passed to an Emitter
19 * corresponds to an External General Parsed Entity. A SAX2 ContentHandler only expects
20 * to deal with well-formed XML documents, so we only pass it the contents of the first
21 * element encountered.
22 */

23   
24 public class ContentHandlerProxy extends Emitter implements Locator
25 {
26     protected ContentHandler handler;
27     protected LexicalHandler JavaDoc lexicalHandler;
28     //protected AttributesImpl attributes = new AttributesImpl();
29
protected Locator locator = this;
30     private int depth = 0;
31     protected boolean requireWellFormed = true;
32
33     /**
34     * Set the underlying content handler. This call is mandatory before using the Emitter.
35     */

36
37     public void setUnderlyingContentHandler(ContentHandler handler) {
38         this.handler = handler;
39         if (handler instanceof LexicalHandler JavaDoc) {
40             this.lexicalHandler = (LexicalHandler JavaDoc)handler;
41         }
42     }
43
44     /**
45     * Set the Lexical Handler to be used. If called, this must be called AFTER
46     * setUnderlyingContentHandler()
47     */

48
49     public void setLexicalHandler(LexicalHandler JavaDoc handler) {
50         this.lexicalHandler = handler;
51     }
52
53     /**
54     * Indicate whether the content handler can handle a stream of events that is merely
55     * well-balanced, or whether it can only handle a well-formed sequence.
56     */

57
58     public void setRequireWellFormed(boolean wellFormed) {
59         requireWellFormed = wellFormed;
60     }
61
62     /**
63     * Set Document Locator
64     */

65
66     public void setDocumentLocator(Locator locator) {
67         this.locator = locator;
68     }
69
70     /**
71     * Start of document
72     */

73
74     public void startDocument() throws TransformerException JavaDoc {
75         // System.err.println(this + " startDocument(), handler = " + handler);
76
if (handler==null) {
77             throw new TransformerException JavaDoc("ContentHandlerProxy.startDocument(): no underlying handler provided");
78         }
79         try {
80             handler.setDocumentLocator(locator);
81             handler.startDocument();
82         } catch (SAXException err) {
83             throw new TransformerException JavaDoc(err);
84         }
85         depth = 0;
86     }
87
88     /**
89     * End of document
90     */

91
92     public void endDocument() throws TransformerException JavaDoc {
93         try {
94             handler.endDocument();
95         } catch (SAXException err) {
96             throw new TransformerException JavaDoc(err);
97         }
98     }
99
100
101     /**
102     * Start of element
103     */

104
105     public void startElement(int nameCode, Attributes atts,
106                              int[] namespaces, int nscount) throws TransformerException JavaDoc {
107         depth++;
108         try {
109             if (depth<=0 && requireWellFormed) {
110                 notifyNotWellFormed();
111             }
112             if (depth>0 || !requireWellFormed) {
113                 for (int n=0; n<nscount; n++) {
114                     String JavaDoc prefix = namePool.getPrefixFromNamespaceCode(namespaces[n]);
115                     String JavaDoc uri = namePool.getURIFromNamespaceCode(namespaces[n]);
116                     handler.startPrefixMapping(prefix, uri);
117                 }
118             
119                 handler.startElement(
120                     namePool.getURI(nameCode),
121                     namePool.getLocalName(nameCode),
122                     namePool.getDisplayName(nameCode),
123                     atts);
124             }
125         } catch (SAXException err) {
126             throw new TransformerException JavaDoc(err);
127         }
128     }
129
130     /**
131     * End of element
132     */

133
134     public void endElement(int nameCode) throws TransformerException JavaDoc {
135         if (depth>0) {
136             try {
137                 handler.endElement(
138                     namePool.getURI(nameCode),
139                     namePool.getLocalName(nameCode),
140                     namePool.getDisplayName(nameCode));
141             } catch (SAXException err) {
142                 throw new TransformerException JavaDoc(err);
143             }
144         }
145         depth--;
146         // if this was the outermost element, and well formed output is required
147
// then no further elements will be processed
148
if (requireWellFormed && depth<=0) {
149             depth = Integer.MIN_VALUE; // crude but effective
150
}
151
152     }
153
154     /**
155     * Character data
156     */

157
158     public void characters(char[] chars, int start, int len) throws TransformerException JavaDoc {
159         try {
160             if (depth<=0 && requireWellFormed) {
161                 boolean isWhite = new String JavaDoc(chars, start, len).trim().length()==0;
162                 if (isWhite) {
163                     // ignore top-level white space
164
} else {
165                     notifyNotWellFormed();
166                     if (!requireWellFormed) {
167                         handler.characters(chars, start, len);
168                     }
169                 }
170             } else {
171                 handler.characters(chars, start, len);
172             }
173         } catch (SAXException err) {
174             throw new TransformerException JavaDoc(err);
175         }
176     }
177
178     /**
179     * The following function notifies the content handler, by means of a processing
180     * instruction, that the output is not a well-formed document. If the content
181     * handler responds with an exception containing the message "continue"
182     * (this is the only way it can get information back) then further events are
183     * notified, otherwise they are suppressed.
184     */

185
186     protected void notifyNotWellFormed() throws SAXException {
187         try {
188             handler.processingInstruction(
189                 "saxon:warning", "Output suppressed because it is not well-formed");
190         } catch (SAXException err) {
191             if (err.getMessage().equals("continue")) {
192                 requireWellFormed = false;
193             } else {
194                 throw err;
195             }
196         }
197     }
198
199
200     /**
201     * Processing Instruction
202     */

203
204     public void processingInstruction(String JavaDoc target, String JavaDoc data)
205     throws TransformerException JavaDoc {
206         try {
207             handler.processingInstruction(target, data);
208         } catch (SAXException err) {
209             throw new TransformerException JavaDoc(err);
210         }
211     }
212
213     /**
214     * Output a comment. Passes it on to the ContentHandler provided that the ContentHandler
215     * is also a SAX2 LexicalHandler.
216     */

217
218     public void comment (char ch[], int start, int length)
219     throws TransformerException JavaDoc {
220         try {
221             if (lexicalHandler != null) {
222                 lexicalHandler.comment(ch, start, length);
223             }
224         } catch (SAXException err) {
225             throw new TransformerException JavaDoc(err);
226         }
227     }
228
229
230     /**
231     * Switch escaping on or off. This is called when the XSLT disable-output-escaping attribute
232     * is used to switch escaping on or off. It is not called for other sections of output (e.g.
233     * element names) where escaping is inappropriate. The action, as defined in JAXP 1.1, is
234     * to notify the request to the Content Handler using a processing instruction.
235     */

236
237     public void setEscaping(boolean escaping) {
238         try {
239             handler.processingInstruction(
240                 (escaping ? Result.PI_ENABLE_OUTPUT_ESCAPING : PI_DISABLE_OUTPUT_ESCAPING),
241                 "");
242         } catch (SAXException err) {}
243     }
244
245     ////////////////////////////////////////////////////////////////////
246
// dummy implementation of Locator interface
247
////////////////////////////////////////////////////////////////////
248

249     public String JavaDoc getPublicId() {
250         return null;
251     }
252     
253     public int getLineNumber() {
254         return -1;
255     }
256     
257     public int getColumnNumber() {
258         return -1;
259     }
260 }
261
262 //
263
// The contents of this file are subject to the Mozilla Public License Version 1.0 (the "License");
264
// you may not use this file except in compliance with the License. You may obtain a copy of the
265
// License at http://www.mozilla.org/MPL/
266
//
267
// Software distributed under the License is distributed on an "AS IS" basis,
268
// WITHOUT WARRANTY OF ANY KIND, either express or implied.
269
// See the License for the specific language governing rights and limitations under the License.
270
//
271
// The Original Code is: all this file.
272
//
273
// The Initial Developer of the Original Code is
274
// Michael Kay of International Computers Limited (michael.h.kay@ntlworld.com).
275
//
276
// Portions created by (your name) are Copyright (C) (your legal entity). All Rights Reserved.
277
//
278
// Contributor(s): none.
279
//
280
Popular Tags