KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > cocoon > xml > SaxBuffer


1 /*
2  * Copyright 1999-2004 The Apache Software Foundation.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */

16 package org.apache.cocoon.xml;
17
18 import org.xml.sax.ContentHandler JavaDoc;
19 import org.xml.sax.SAXException JavaDoc;
20 import org.xml.sax.Locator JavaDoc;
21 import org.xml.sax.Attributes JavaDoc;
22 import org.xml.sax.ext.LexicalHandler JavaDoc;
23 import org.apache.excalibur.xml.sax.XMLizable;
24 import org.apache.avalon.excalibur.pool.Recyclable;
25
26 import java.io.Serializable JavaDoc;
27 import java.io.Writer JavaDoc;
28 import java.io.IOException JavaDoc;
29 import java.util.ArrayList JavaDoc;
30 import java.util.Iterator JavaDoc;
31 import java.util.List JavaDoc;
32 import java.util.Collections JavaDoc;
33
34 /**
35  * A class that can record SAX events and replay them later.
36  *
37  * <p>Compared to {@link org.apache.cocoon.components.sax.XMLByteStreamCompiler},
38  * this class is many times faster at sending out the recorded SAX events since
39  * it doesn't need to convert between byte and char representations etc.
40  * On the other hand, its data structure is more complex then a simple byte array,
41  * making XMLByteStreamCompiler better in case the recorded SAX should be stored long-term.
42  *
43  * <p>Use this class if you need to frequently generate smaller amounts of SAX events,
44  * or replay a set of recorded start events immediately.</p>
45  *
46  * <p>Both {@link ContentHandler} and {@link LexicalHandler} are supported, the only
47  * exception is that the setDocumentLocator event is not recorded.</p>
48  *
49  * @version CVS $Id: SaxBuffer.java 54074 2004-10-08 13:00:55Z vgritsenko $
50  */

51 public class SaxBuffer extends AbstractSAXFragment
52                        implements XMLConsumer, Recyclable, Serializable JavaDoc {
53
54     /**
55      * Stores list of {@link SaxBit} objects.
56      */

57     protected List JavaDoc saxbits;
58
59     /**
60      * Creates empty SaxBuffer
61      */

62     public SaxBuffer() {
63         this.saxbits = new ArrayList JavaDoc();
64     }
65
66     /**
67      * Creates SaxBuffer based on the provided bits list.
68      */

69     public SaxBuffer(List JavaDoc bits) {
70         this.saxbits = bits;
71     }
72
73     /**
74      * Creates copy of another SaxBuffer
75      */

76     public SaxBuffer(SaxBuffer saxBuffer) {
77         this.saxbits = new ArrayList JavaDoc(saxBuffer.saxbits);
78     }
79
80     //
81
// ContentHandler Interface
82
//
83

84     public void skippedEntity(String JavaDoc name) throws SAXException JavaDoc {
85         saxbits.add(new SkippedEntity(name));
86     }
87
88     public void setDocumentLocator(Locator JavaDoc locator) {
89         // Don't record this event
90
}
91
92     public void ignorableWhitespace(char ch[], int start, int length) throws SAXException JavaDoc {
93         saxbits.add(new IgnorableWhitespace(ch, start, length));
94     }
95
96     public void processingInstruction(String JavaDoc target, String JavaDoc data) throws SAXException JavaDoc {
97         saxbits.add(new PI(target, data));
98     }
99
100     public void startDocument() throws SAXException JavaDoc {
101         saxbits.add(StartDocument.SINGLETON);
102     }
103
104     public void startElement(String JavaDoc namespaceURI, String JavaDoc localName, String JavaDoc qName, Attributes JavaDoc atts) throws SAXException JavaDoc {
105         saxbits.add(new StartElement(namespaceURI, localName, qName, atts));
106     }
107
108     public void endPrefixMapping(String JavaDoc prefix) throws SAXException JavaDoc {
109         saxbits.add(new EndPrefixMapping(prefix));
110     }
111
112     public void characters(char ch[], int start, int length) throws SAXException JavaDoc {
113         saxbits.add(new Characters(ch, start, length));
114     }
115
116     public void endElement(String JavaDoc namespaceURI, String JavaDoc localName, String JavaDoc qName) throws SAXException JavaDoc {
117         saxbits.add(new EndElement(namespaceURI, localName, qName));
118     }
119
120     public void endDocument() throws SAXException JavaDoc {
121         saxbits.add(EndDocument.SINGLETON);
122     }
123
124     public void startPrefixMapping(String JavaDoc prefix, String JavaDoc uri) throws SAXException JavaDoc {
125         saxbits.add(new StartPrefixMapping(prefix, uri));
126     }
127
128     //
129
// LexicalHandler Interface
130
//
131

132     public void endCDATA() throws SAXException JavaDoc {
133         saxbits.add(EndCDATA.SINGLETON);
134     }
135
136     public void comment(char ch[], int start, int length) throws SAXException JavaDoc {
137         saxbits.add(new Comment(ch, start, length));
138     }
139
140     public void startEntity(String JavaDoc name) throws SAXException JavaDoc {
141         saxbits.add(new StartEntity(name));
142     }
143
144     public void endDTD() throws SAXException JavaDoc {
145         saxbits.add(EndDTD.SINGLETON);
146     }
147
148     public void startDTD(String JavaDoc name, String JavaDoc publicId, String JavaDoc systemId) throws SAXException JavaDoc {
149         saxbits.add(new StartDTD(name, publicId, systemId));
150     }
151
152     public void startCDATA() throws SAXException JavaDoc {
153         saxbits.add(StartCDATA.SINGLETON);
154     }
155
156     public void endEntity(String JavaDoc name) throws SAXException JavaDoc {
157         saxbits.add(new EndEntity(name));
158     }
159
160     //
161
// Public Methods
162
//
163

164     /**
165      * Add a bit containing XMLizable object
166      */

167     public void xmlizable(XMLizable xml) {
168         saxbits.add(new XMLizableBit(xml));
169     }
170
171     /**
172      * @return true if buffer is empty
173      */

174     public boolean isEmpty() {
175         return saxbits.isEmpty();
176     }
177
178     /**
179      * @return unmodifiable list of SAX bits
180      */

181     public List JavaDoc getBits() {
182         return Collections.unmodifiableList(saxbits);
183     }
184
185     /**
186      * Stream this buffer into the provided content handler.
187      * If contentHandler object implements LexicalHandler, it will get lexical
188      * events as well.
189      */

190     public void toSAX(ContentHandler JavaDoc contentHandler) throws SAXException JavaDoc {
191         for (Iterator JavaDoc i = saxbits.iterator(); i.hasNext();) {
192             SaxBit saxbit = (SaxBit)i.next();
193             saxbit.send(contentHandler);
194         }
195     }
196
197     /**
198      * @return String value of the buffer
199      */

200     public String JavaDoc toString() {
201         // NOTE: This method is used in i18n XML bundle implementation
202
final StringBuffer JavaDoc value = new StringBuffer JavaDoc();
203         for (Iterator JavaDoc i = saxbits.iterator(); i.hasNext();) {
204             final SaxBit saxbit = (SaxBit) i.next();
205             if (saxbit instanceof Characters) {
206                 ((Characters) saxbit).toString(value);
207             }
208         }
209
210         return value.toString();
211     }
212
213     /**
214      * Clear this buffer
215      */

216     public void recycle() {
217         saxbits.clear();
218     }
219
220     /**
221      * Dump buffer contents into the provided writer.
222      */

223     public void dump(Writer JavaDoc writer) throws IOException JavaDoc {
224         Iterator JavaDoc i = saxbits.iterator();
225         while (i.hasNext()) {
226             final SaxBit saxbit = (SaxBit) i.next();
227             saxbit.dump(writer);
228         }
229         writer.flush();
230     }
231
232     //
233
// Implementation Methods
234
//
235

236     /**
237      * Adds a SaxBit to the bits list
238      */

239     protected final void addBit(SaxBit bit) {
240         saxbits.add(bit);
241     }
242
243     /**
244      * Iterates through the bits list
245      */

246     protected final Iterator JavaDoc bits() {
247         return saxbits.iterator();
248     }
249
250     /**
251      * SaxBit is a representation of the SAX event. Every SaxBit is immutable object.
252      */

253     interface SaxBit {
254         public void send(ContentHandler JavaDoc contentHandler) throws SAXException JavaDoc;
255         public void dump(Writer JavaDoc writer) throws IOException JavaDoc;
256     }
257
258     public final static class StartDocument implements SaxBit, Serializable JavaDoc {
259         public static final StartDocument SINGLETON = new StartDocument();
260
261         public void send(ContentHandler JavaDoc contentHandler) throws SAXException JavaDoc {
262             contentHandler.startDocument();
263         }
264
265         public void dump(Writer JavaDoc writer) throws IOException JavaDoc {
266             writer.write("[StartDocument]\n");
267         }
268     }
269
270     public final static class EndDocument implements SaxBit, Serializable JavaDoc {
271         public static final EndDocument SINGLETON = new EndDocument();
272
273         public void send(ContentHandler JavaDoc contentHandler) throws SAXException JavaDoc {
274             contentHandler.endDocument();
275         }
276
277         public void dump(Writer JavaDoc writer) throws IOException JavaDoc {
278             writer.write("[EndDocument]\n");
279         }
280     }
281
282     public final static class PI implements SaxBit, Serializable JavaDoc {
283         public final String JavaDoc target;
284         public final String JavaDoc data;
285
286         public PI(String JavaDoc target, String JavaDoc data) {
287             this.target = target;
288             this.data = data;
289         }
290
291         public void send(ContentHandler JavaDoc contentHandler) throws SAXException JavaDoc {
292             contentHandler.processingInstruction(target, data);
293         }
294
295         public void dump(Writer JavaDoc writer) throws IOException JavaDoc {
296             writer.write("[ProcessingInstruction] target=" + target + ",data=" + data + "\n");
297         }
298     }
299
300     public final static class StartDTD implements SaxBit, Serializable JavaDoc {
301         public final String JavaDoc name;
302         public final String JavaDoc publicId;
303         public final String JavaDoc systemId;
304
305         public StartDTD(String JavaDoc name, String JavaDoc publicId, String JavaDoc systemId) {
306             this.name = name;
307             this.publicId = publicId;
308             this.systemId = systemId;
309         }
310
311         public void send(ContentHandler JavaDoc contentHandler) throws SAXException JavaDoc {
312             if (contentHandler instanceof LexicalHandler JavaDoc)
313                 ((LexicalHandler JavaDoc)contentHandler).startDTD(name, publicId, systemId);
314         }
315
316         public void dump(Writer JavaDoc writer) throws IOException JavaDoc {
317             writer.write("[StartDTD] name=" + name + ",publicId=" + publicId + ",systemId=" + systemId + "\n");
318         }
319     }
320
321     public final static class EndDTD implements SaxBit, Serializable JavaDoc {
322         public static final EndDTD SINGLETON = new EndDTD();
323
324         public void send(ContentHandler JavaDoc contentHandler) throws SAXException JavaDoc {
325             if (contentHandler instanceof LexicalHandler JavaDoc)
326                 ((LexicalHandler JavaDoc)contentHandler).endDTD();
327         }
328
329         public void dump(Writer JavaDoc writer) throws IOException JavaDoc {
330             writer.write("[EndDTD]\n");
331         }
332     }
333
334     public final static class StartEntity implements SaxBit, Serializable JavaDoc {
335         public final String JavaDoc name;
336
337         public StartEntity(String JavaDoc name) {
338             this.name = name;
339         }
340
341         public void send(ContentHandler JavaDoc contentHandler) throws SAXException JavaDoc {
342             if (contentHandler instanceof LexicalHandler JavaDoc)
343                 ((LexicalHandler JavaDoc)contentHandler).startEntity(name);
344         }
345
346         public void dump(Writer JavaDoc writer) throws IOException JavaDoc {
347             writer.write("[StartEntity] name=" + name + "\n");
348         }
349     }
350
351     public final static class EndEntity implements SaxBit, Serializable JavaDoc {
352         public final String JavaDoc name;
353
354         public EndEntity(String JavaDoc name) {
355             this.name = name;
356         }
357
358         public void send(ContentHandler JavaDoc contentHandler) throws SAXException JavaDoc {
359             if (contentHandler instanceof LexicalHandler JavaDoc)
360                 ((LexicalHandler JavaDoc)contentHandler).endEntity(name);
361         }
362
363         public void dump(Writer JavaDoc writer) throws IOException JavaDoc {
364             writer.write("[EndEntity] name=" + name + "\n");
365         }
366     }
367
368     public final static class SkippedEntity implements SaxBit, Serializable JavaDoc {
369         public final String JavaDoc name;
370
371         public SkippedEntity(String JavaDoc name) {
372             this.name = name;
373         }
374
375         public void send(ContentHandler JavaDoc contentHandler) throws SAXException JavaDoc {
376             contentHandler.skippedEntity(name);
377         }
378
379         public void dump(Writer JavaDoc writer) throws IOException JavaDoc {
380             writer.write("[SkippedEntity] name=" + name + "\n");
381         }
382     }
383
384     public final static class StartPrefixMapping implements SaxBit, Serializable JavaDoc {
385         public final String JavaDoc prefix;
386         public final String JavaDoc uri;
387
388         public StartPrefixMapping(String JavaDoc prefix, String JavaDoc uri) {
389             this.prefix = prefix;
390             this.uri = uri;
391         }
392
393         public void send(ContentHandler JavaDoc contentHandler) throws SAXException JavaDoc {
394             contentHandler.startPrefixMapping(prefix, uri);
395         }
396
397         public void dump(Writer JavaDoc writer) throws IOException JavaDoc {
398             writer.write("[StartPrefixMapping] prefix=" + prefix + ",uri=" + uri + "\n");
399         }
400     }
401
402     public final static class EndPrefixMapping implements SaxBit, Serializable JavaDoc {
403         public final String JavaDoc prefix;
404
405         public EndPrefixMapping(String JavaDoc prefix) {
406             this.prefix = prefix;
407         }
408
409         public void send(ContentHandler JavaDoc contentHandler) throws SAXException JavaDoc {
410             contentHandler.endPrefixMapping(prefix);
411         }
412
413         public void dump(Writer JavaDoc writer) throws IOException JavaDoc {
414             writer.write("[EndPrefixMapping] prefix=" + prefix + "\n");
415         }
416     }
417
418     public final static class StartElement implements SaxBit, Serializable JavaDoc {
419         public final String JavaDoc namespaceURI;
420         public final String JavaDoc localName;
421         public final String JavaDoc qName;
422         public final Attributes JavaDoc attrs;
423
424         public StartElement(String JavaDoc namespaceURI, String JavaDoc localName, String JavaDoc qName, Attributes JavaDoc attrs) {
425             this.namespaceURI = namespaceURI;
426             this.localName = localName;
427             this.qName = qName;
428             this.attrs = new org.xml.sax.helpers.AttributesImpl JavaDoc(attrs);
429         }
430
431         public void send(ContentHandler JavaDoc contentHandler) throws SAXException JavaDoc {
432             contentHandler.startElement(namespaceURI, localName, qName, attrs);
433         }
434
435         public void dump(Writer JavaDoc writer) throws IOException JavaDoc {
436             writer.write("[StartElement] namespaceURI=" + namespaceURI + ",localName=" + localName + ",qName=" + qName + "\n");
437             for (int i = 0; i < attrs.getLength(); i++) {
438                 writer.write(" [Attribute] namespaceURI=" + attrs.getURI(i) + ",localName=" + attrs.getLocalName(i) + ",qName=" + attrs.getQName(i) + ",type=" + attrs.getType(i) + ",value=" + attrs.getValue(i) + "\n");
439             }
440         }
441     }
442
443     public final static class EndElement implements SaxBit, Serializable JavaDoc {
444         public final String JavaDoc namespaceURI;
445         public final String JavaDoc localName;
446         public final String JavaDoc qName;
447
448         public EndElement(String JavaDoc namespaceURI, String JavaDoc localName, String JavaDoc qName) {
449             this.namespaceURI = namespaceURI;
450             this.localName = localName;
451             this.qName = qName;
452         }
453
454         public void send(ContentHandler JavaDoc contentHandler) throws SAXException JavaDoc {
455             contentHandler.endElement(namespaceURI, localName, qName);
456         }
457
458         public void dump(Writer JavaDoc writer) throws IOException JavaDoc {
459             writer.write("[EndElement] namespaceURI=" + namespaceURI + ",localName=" + localName + ",qName=" + qName + "\n");
460         }
461     }
462
463     public final static class Characters implements SaxBit, Serializable JavaDoc {
464         public final char[] ch;
465
466         public Characters(char[] ch, int start, int length) {
467             // make a copy so that we don't hold references to a potentially large array we don't control
468
this.ch = new char[length];
469             System.arraycopy(ch, start, this.ch, 0, length);
470         }
471
472         public void send(ContentHandler JavaDoc contentHandler) throws SAXException JavaDoc {
473             contentHandler.characters(ch, 0, ch.length);
474         }
475
476         public void toString(StringBuffer JavaDoc value) {
477             value.append(ch);
478         }
479
480         public void dump(Writer JavaDoc writer) throws IOException JavaDoc {
481             writer.write("[Characters] ch=" + new String JavaDoc(ch) + "\n");
482         }
483     }
484
485     public final static class Comment implements SaxBit, Serializable JavaDoc {
486         public final char[] ch;
487
488         public Comment(char[] ch, int start, int length) {
489             // make a copy so that we don't hold references to a potentially large array we don't control
490
this.ch = new char[length];
491             System.arraycopy(ch, start, this.ch, 0, length);
492         }
493
494         public void send(ContentHandler JavaDoc contentHandler) throws SAXException JavaDoc {
495             if (contentHandler instanceof LexicalHandler JavaDoc)
496                 ((LexicalHandler JavaDoc)contentHandler).comment(ch, 0, ch.length);
497         }
498
499         public void dump(Writer JavaDoc writer) throws IOException JavaDoc {
500             writer.write("[Comment] ch=" + new String JavaDoc(ch) + "\n");
501         }
502     }
503
504     public final static class StartCDATA implements SaxBit, Serializable JavaDoc {
505         public static final StartCDATA SINGLETON = new StartCDATA();
506
507         public void send(ContentHandler JavaDoc contentHandler) throws SAXException JavaDoc {
508             if (contentHandler instanceof LexicalHandler JavaDoc)
509                 ((LexicalHandler JavaDoc)contentHandler).startCDATA();
510         }
511
512         public void dump(Writer JavaDoc writer) throws IOException JavaDoc {
513             writer.write("[StartCDATA]\n");
514         }
515     }
516
517     public final static class EndCDATA implements SaxBit, Serializable JavaDoc {
518         public static final EndCDATA SINGLETON = new EndCDATA();
519
520         public void send(ContentHandler JavaDoc contentHandler) throws SAXException JavaDoc {
521             if (contentHandler instanceof LexicalHandler JavaDoc)
522                 ((LexicalHandler JavaDoc)contentHandler).endCDATA();
523         }
524
525         public void dump(Writer JavaDoc writer) throws IOException JavaDoc {
526             writer.write("[EndCDATA]\n");
527         }
528     }
529
530     public final static class IgnorableWhitespace implements SaxBit, Serializable JavaDoc {
531         public final char[] ch;
532
533         public IgnorableWhitespace(char[] ch, int start, int length) {
534             // make a copy so that we don't hold references to a potentially large array we don't control
535
this.ch = new char[length];
536             System.arraycopy(ch, start, this.ch, 0, length);
537         }
538
539         public void send(ContentHandler JavaDoc contentHandler) throws SAXException JavaDoc {
540             contentHandler.ignorableWhitespace(ch, 0, ch.length);
541         }
542
543         public void dump(Writer JavaDoc writer) throws IOException JavaDoc {
544             writer.write("[IgnorableWhitespace] ch=" + new String JavaDoc(ch) + "\n");
545         }
546     }
547
548     public final static class XMLizableBit implements SaxBit, Serializable JavaDoc {
549         public final XMLizable xml;
550
551         public XMLizableBit(XMLizable xml) {
552             this.xml = xml;
553         }
554
555         public void send(ContentHandler JavaDoc contentHandler) throws SAXException JavaDoc {
556             this.xml.toSAX(new EmbeddedXMLPipe(contentHandler));
557         }
558
559         public void dump(Writer JavaDoc writer) throws IOException JavaDoc {
560             if (xml instanceof SaxBuffer) {
561                 writer.write("[XMLizable] Begin nested SaxBuffer\n");
562                 ((SaxBuffer)xml).dump(writer);
563                 writer.write("[XMLizable] End nested SaxBuffer\n");
564             } else {
565                 writer.write("[XMLizable] xml=" + xml + "\n");
566             }
567         }
568     }
569 }
570
Popular Tags