KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > cocoon > portal > serialization > IncludingHTMLSerializer


1 /*
2  * Copyright 2004,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.portal.serialization;
17
18 import java.io.IOException JavaDoc;
19 import java.io.OutputStream JavaDoc;
20 import java.util.HashMap JavaDoc;
21 import java.util.LinkedList JavaDoc;
22 import java.util.Map JavaDoc;
23
24 import org.apache.cocoon.serialization.HTMLSerializer;
25 import org.xml.sax.Attributes JavaDoc;
26 import org.xml.sax.SAXException JavaDoc;
27
28
29 /**
30  * This is a special serializer that allows to include content that is not XML at the
31  * last possible point.
32  * This is very useful for the portlets as they don't deliver valid XML but HTML.
33  *
34  * The trick is to insert a special token in the characters of the SAX stream: '~~'.
35  * This token is filtered later on and replaced with the complete content of the portlet.
36  *
37  * @author <a HREF="mailto:cziegeler@apache.org">Carsten Ziegeler</a>
38  *
39  * @version CVS $Id: IncludingHTMLSerializer.java 30932 2004-07-29 17:35:38Z vgritsenko $
40  */

41 public class IncludingHTMLSerializer
42     extends HTMLSerializer {
43     
44     public static final ThreadLocal JavaDoc portlets = new ThreadLocal JavaDoc();
45     
46     public static final String JavaDoc NAMESPACE = "http://apache.org/cocoon/portal/include";
47     
48     protected LinkedList JavaDoc orderedPortletList = new LinkedList JavaDoc();
49     
50     protected static final char token = '~';
51     
52     protected static final char[] tokens = new char[] {token, token};
53     
54     /* (non-Javadoc)
55      * @see org.apache.avalon.excalibur.pool.Recyclable#recycle()
56      */

57     public void recycle() {
58         super.recycle();
59         Map JavaDoc map = (Map JavaDoc)portlets.get();
60         if ( map != null ) {
61             map.clear();
62         }
63         this.orderedPortletList.clear();
64     }
65
66     /**
67      * Add a portlet
68      */

69     public static void addPortlet(String JavaDoc name, String JavaDoc content) {
70         Map JavaDoc map = (Map JavaDoc) portlets.get();
71         if ( map == null ) {
72             map = new HashMap JavaDoc();
73             portlets.set(map);
74         }
75         map.put(name, content);
76     }
77     
78     /* (non-Javadoc)
79      * @see org.xml.sax.ContentHandler#endElement(java.lang.String, java.lang.String, java.lang.String)
80      */

81     public void endElement(String JavaDoc uri, String JavaDoc loc, String JavaDoc raw)
82     throws SAXException JavaDoc {
83         if (!NAMESPACE.equals(uri)) {
84             super.endElement(uri, loc, raw);
85         }
86     }
87
88     /* (non-Javadoc)
89      * @see org.xml.sax.ContentHandler#startElement(java.lang.String, java.lang.String, java.lang.String, org.xml.sax.Attributes)
90      */

91     public void startElement(String JavaDoc uri, String JavaDoc loc, String JavaDoc raw, Attributes JavaDoc a)
92     throws SAXException JavaDoc {
93         if (!NAMESPACE.equals(uri)) {
94             super.startElement(uri, loc, raw, a);
95         } else {
96             final String JavaDoc portletId = a.getValue("portlet");
97
98             String JavaDoc value = null;
99             Map JavaDoc map = (Map JavaDoc)portlets.get();
100             if ( map != null ) {
101                 value = (String JavaDoc)map.get(portletId);
102             }
103             if ( value != null ) {
104                 this.orderedPortletList.addFirst(value);
105                 this.characters(tokens, 0, tokens.length);
106             }
107         }
108     }
109
110     /* (non-Javadoc)
111      * @see org.apache.cocoon.sitemap.SitemapOutputComponent#setOutputStream(java.io.OutputStream)
112      */

113     public void setOutputStream(OutputStream JavaDoc stream) throws IOException JavaDoc {
114         super.setOutputStream(new ReplacingOutputStream(stream, this.orderedPortletList));
115     }
116
117 }
118 class ReplacingOutputStream extends OutputStream JavaDoc {
119     
120     /** Stream */
121     protected final OutputStream JavaDoc stream;
122     
123     protected boolean inKey;
124     
125     protected final LinkedList JavaDoc orderedValues;
126     
127     /**
128      * Constructor
129      */

130     public ReplacingOutputStream(OutputStream JavaDoc stream, LinkedList JavaDoc values) {
131         this.stream = stream;
132         this.orderedValues = values;
133         this.inKey = false;
134     }
135     
136     /* (non-Javadoc)
137      * @see java.io.OutputStream#close()
138      */

139     public void close() throws IOException JavaDoc {
140         this.stream.close();
141     }
142
143     /* (non-Javadoc)
144      * @see java.io.OutputStream#flush()
145      */

146     public void flush() throws IOException JavaDoc {
147         this.stream.flush();
148     }
149
150     /* (non-Javadoc)
151      * @see java.io.OutputStream#write(byte[], int, int)
152      */

153     public void write(byte[] b, int off, int len) throws IOException JavaDoc {
154         if ( len == 0 ) {
155             return;
156         }
157         if ( this.inKey ) {
158             if ( b[off] == IncludingHTMLSerializer.token ) {
159                 this.writeNextValue();
160                 off++;
161                 len--;
162             } else {
163                 this.write(IncludingHTMLSerializer.token);
164             }
165             this.inKey = false;
166         }
167         // search for key
168
boolean end = false;
169         do {
170             int s = off;
171             int e = off+len;
172             while (s < e && b[s] != IncludingHTMLSerializer.token) {
173                 s++;
174             }
175             if ( s == e ) {
176                 this.stream.write(b, off, len);
177                 end = true;
178             } else if ( s == e-1 ) {
179                 this.stream.write(b, off, len-1);
180                 this.inKey = true;
181                 end = true;
182             } else {
183                 if ( b[s+1] == IncludingHTMLSerializer.token) {
184                     final int l = s-off;
185                     this.stream.write(b, off, l);
186                     off += (l+2);
187                     len -= (l+2);
188                     this.writeNextValue();
189                     
190                 } else {
191                     final int l = s-off+2;
192                     this.stream.write(b, off, l);
193                     off += l;
194                     len -= l;
195                 }
196                 end = (len == 0);
197             }
198         } while (!end);
199     }
200
201     /* (non-Javadoc)
202      * @see java.io.OutputStream#write(byte[])
203      */

204     public void write(byte[] b) throws IOException JavaDoc {
205         this.write(b, 0, b.length);
206     }
207
208     /* (non-Javadoc)
209      * @see java.io.OutputStream#write(int)
210      */

211     public void write(int b) throws IOException JavaDoc {
212         if ( b == IncludingHTMLSerializer.token ) {
213             if ( this.inKey ) {
214                 this.writeNextValue();
215             }
216             this.inKey = !this.inKey;
217         } else {
218             if ( this.inKey ) {
219                 this.inKey = false;
220                 this.stream.write(IncludingHTMLSerializer.token);
221             }
222             this.stream.write(b);
223         }
224     }
225
226     /**
227      * Write next value
228      */

229     protected void writeNextValue() throws IOException JavaDoc {
230         final String JavaDoc value = (String JavaDoc)this.orderedValues.removeLast();
231         if ( value != null ) {
232             this.stream.write(value.getBytes(), 0, value.length());
233         }
234     }
235 }
236
237
Popular Tags