KickJava   Java API By Example, From Geeks To Geeks.

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


1 package net.sf.saxon.event;
2 import net.sf.saxon.om.NamespaceConstant;
3 import net.sf.saxon.om.NamePool;
4 import net.sf.saxon.trans.XPathException;
5 import net.sf.saxon.type.Type;
6 import net.sf.saxon.value.Whitespace;
7
8 import javax.xml.transform.OutputKeys JavaDoc;
9 import javax.xml.transform.Result JavaDoc;
10 import java.util.ArrayList JavaDoc;
11 import java.util.List JavaDoc;
12 import java.util.Properties JavaDoc;
13
14 /**
15  * This class is used when the decision on which serialization method to use has to be delayed until the first
16  * element is read. It buffers comments and processing instructions until that happens; then when the first
17  * element arrives it creates a real serialization pipeline and uses that for future output.
18  * @author Michael H. Kay
19  */

20
21 public class UncommittedSerializer extends ProxyReceiver {
22
23     boolean committed = false;
24     List JavaDoc pending = null;
25     Result JavaDoc finalResult;
26     Properties JavaDoc outputProperties;
27
28     public UncommittedSerializer(Result JavaDoc finalResult, Properties JavaDoc outputProperties) {
29         this.finalResult = finalResult;
30         this.outputProperties = outputProperties;
31         setUnderlyingReceiver(new Sink());
32     }
33
34     public void open() throws XPathException {
35         committed = false;
36     }
37
38     /**
39     * End of document
40     */

41
42     public void close() throws XPathException {
43         // empty output: must send a beginDocument()/endDocument() pair to the content handler
44
if (!committed) {
45             switchToMethod("xml");
46         }
47         getUnderlyingReceiver().close();
48     }
49
50     /**
51     * Produce character output using the current Writer. <BR>
52     */

53
54     public void characters(CharSequence JavaDoc chars, int locationId, int properties) throws XPathException {
55         if (committed) {
56             getUnderlyingReceiver().characters(chars, locationId, properties);
57         } else {
58             if (pending==null) {
59                 pending = new ArrayList JavaDoc(10);
60             }
61             PendingNode node = new PendingNode();
62             node.kind = Type.TEXT;
63             node.name = null;
64             node.content = chars;
65             node.locationId = locationId;
66             node.properties = properties;
67             pending.add(node);
68             if (!Whitespace.isWhite(chars)) {
69                 switchToMethod("xml");
70             }
71         }
72     }
73
74     /**
75     * Processing Instruction
76     */

77
78     public void processingInstruction(String JavaDoc target, CharSequence JavaDoc data, int locationId, int properties) throws XPathException {
79         if (committed) {
80             getUnderlyingReceiver().processingInstruction(target, data, locationId, properties);
81         } else {
82             if (pending==null) {
83                 pending = new ArrayList JavaDoc(10);
84             }
85             PendingNode node = new PendingNode();
86             node.kind = Type.PROCESSING_INSTRUCTION;
87             node.name = target;
88             node.content = data;
89             node.locationId = locationId;
90             node.properties = properties;
91             pending.add(node);
92         }
93     }
94
95     /**
96     * Output a comment
97     */

98
99     public void comment (CharSequence JavaDoc chars, int locationId, int properties) throws XPathException {
100         if (committed) {
101             getUnderlyingReceiver().comment(chars, locationId, properties);
102         } else {
103            if (pending==null) {
104                 pending=new ArrayList JavaDoc(10);
105             }
106             PendingNode node = new PendingNode();
107             node.kind = Type.COMMENT;
108             node.name = null;
109             node.content = chars;
110             node.locationId = locationId;
111             node.properties = properties;
112             pending.add(node);
113         }
114     }
115
116     /**
117     * Output an element start tag. <br>
118     * This can only be called once: it switches to a substitute output generator for XML, XHTML, or HTML,
119     * depending on the element name.
120     * @param nameCode The element name (tag)
121      * @param typeCode The type annotation
122      * @param properties Bit field holding special properties of the element
123     */

124
125     public void startElement(int nameCode, int typeCode, int locationId, int properties) throws XPathException {
126         if (!committed) {
127             NamePool namePool = getNamePool();
128             String JavaDoc name = namePool.getLocalName(nameCode);
129             short uriCode = namePool.getURICode(nameCode);
130             if (name.equalsIgnoreCase("html") && uriCode==NamespaceConstant.NULL_CODE) {
131                 switchToMethod("html");
132             } else if (name.equals("html") && namePool.getURIFromURICode(uriCode).equals(NamespaceConstant.XHTML)) {
133                 String JavaDoc version = outputProperties.getProperty(SaxonOutputKeys.STYLESHEET_VERSION);
134                 if ("1".equals(version)) {
135                     switchToMethod("xml");
136                 } else {
137                     switchToMethod("xhtml");
138                 }
139             } else {
140                 switchToMethod("xml");
141             }
142         }
143         getUnderlyingReceiver().startElement(nameCode, typeCode, locationId, properties);
144     }
145
146     /**
147     * Switch to a specific emitter once the output method is known
148     */

149
150     private void switchToMethod(String JavaDoc method) throws XPathException {
151         Properties JavaDoc newProperties = new Properties JavaDoc(outputProperties);
152         newProperties.setProperty(OutputKeys.METHOD, method);
153         Receiver target = ResultWrapper.getReceiver(finalResult, getPipelineConfiguration(), newProperties);
154         committed = true;
155         target.open();
156         target.startDocument(0);
157         if (pending!=null) {
158             for (int i = 0; i < pending.size(); i++) {
159                 PendingNode node = (PendingNode)pending.get(i);
160                 switch (node.kind) {
161                 case Type.COMMENT:
162                     target.comment(node.content, node.locationId, node.properties);
163                     break;
164                 case Type.PROCESSING_INSTRUCTION:
165                     target.processingInstruction(node.name, node.content, node.locationId, node.properties);
166                     break;
167                 case Type.TEXT:
168                     target.characters(node.content, node.locationId, node.properties);
169                     break;
170                 }
171             }
172             pending = null;
173         }
174         setUnderlyingReceiver(target);
175     }
176
177     /**
178      * A text, comment, or PI node that hasn't been output yet because we don't yet know what output
179      * method to use
180      */

181
182     private static final class PendingNode {
183         int kind;
184         String JavaDoc name;
185         CharSequence JavaDoc content;
186         int properties;
187         int locationId;
188     }
189
190 }
191
192 //
193
// The contents of this file are subject to the Mozilla Public License Version 1.0 (the "License");
194
// you may not use this file except in compliance with the License. You may obtain a copy of the
195
// License at http://www.mozilla.org/MPL/
196
//
197
// Software distributed under the License is distributed on an "AS IS" basis,
198
// WITHOUT WARRANTY OF ANY KIND, either express or implied.
199
// See the License for the specific language governing rights and limitations under the License.
200
//
201
// The Original Code is: all this file.
202
//
203
// The Initial Developer of the Original Code is Michael H. Kay.
204
//
205
// Portions created by (your name) are Copyright (C) (your legal entity). All Rights Reserved.
206
//
207
// Contributor(s): none.
208
//
209
Popular Tags