KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > jetspeed > portal > portlets > NewRSSPortlet


1 /*
2  * Copyright 2000-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
17 package org.apache.jetspeed.portal.portlets;
18
19 //standard java stuff
20
import java.io.IOException JavaDoc;
21 import java.io.Reader JavaDoc;
22 import java.io.StringReader JavaDoc;
23 import java.util.Enumeration JavaDoc;
24 import java.util.Hashtable JavaDoc;
25 import java.util.Iterator JavaDoc;
26
27 //Element Construction Set
28
import org.apache.jetspeed.util.JetspeedClearElement;
29 import org.apache.ecs.ConcreteElement;
30
31 //standard Jetspeed stuff
32
import org.apache.jetspeed.util.MimeType;
33 import org.apache.jetspeed.util.SimpleTransform;
34 import org.apache.jetspeed.cache.disk.JetspeedDiskCache;
35 import org.apache.jetspeed.portal.PortletException;
36 import org.apache.jetspeed.xml.JetspeedXMLEntityResolver;
37 import org.apache.jetspeed.capability.CapabilityMap;
38 import org.apache.jetspeed.capability.CapabilityMapFactory;
39 import org.apache.jetspeed.services.logging.JetspeedLogFactoryService;
40 import org.apache.jetspeed.services.logging.JetspeedLogger;
41 import org.apache.jetspeed.services.rundata.JetspeedRunData;
42
43 //turbine
44
import org.apache.turbine.util.RunData;
45
46 //JAXP support
47
import javax.xml.parsers.DocumentBuilder JavaDoc;
48 import javax.xml.parsers.DocumentBuilderFactory JavaDoc;
49
50 //XML stuff
51
import org.w3c.dom.Document JavaDoc;
52 import org.w3c.dom.Node JavaDoc;
53 import org.w3c.dom.NodeList JavaDoc;
54 import org.xml.sax.InputSource JavaDoc;
55 import org.xml.sax.SAXException JavaDoc;
56
57 /**
58 <p>Portlet which renders RDF Site Summary.</p>
59 <p>This portlet uses XML stylesheet for transforming the RSS
60 content into display markup depending on the MimeType requested
61 by the user-agent</p>
62 <p>It accepts the following parameters :
63 <dl>
64 <dt>itemDisplayed</dt>
65 <dd>The number of items from the RSS file to display on screen. Default 15 for HTML, 5 for WML</dd>
66 <dt>showDescription</dt>
67 <dd>Should the portlet show the item descriptions. Must be true or false. Default: true for HTML, false for WML</dd>
68 <dt>showTitle</dt>
69 <dd>Should the portlet show the channel description. Must be true or false. Default: true for HTML, false for WML</dd>
70 <dt>stylesheet[.<mime>]</dt>
71 <dd>The stylesheet URL. If a mime-type is specified, the stylesheet
72 is only used for this mime-type</dd>
73 </dl>
74 @author <A HREF="mailto:raphael@apache.org">RaphaŽl Luta</A>
75 @version $Id: NewRSSPortlet.java,v 1.22 2004/02/23 04:03:34 jford Exp $
76 */

77 public class NewRSSPortlet extends FileWatchPortlet
78 {
79
80     /**
81      * Static initialization of the logger for this class
82      */

83     private static final JetspeedLogger logger = JetspeedLogFactoryService.getLogger(NewRSSPortlet.class.getName());
84     
85     public final static String JavaDoc ERROR_NOT_VALID = "This does not appear to be an RSS document";
86     public final static String JavaDoc INVALID_TYPE = "Unable to display for this browser";
87
88     private Document JavaDoc document = null;
89     private Hashtable JavaDoc stylesheets = null;
90     private Hashtable JavaDoc params = null;
91
92     /**
93         This method loads the init parameters and
94         parse the document tied to this portlet
95     */

96     public void init( ) throws PortletException {
97
98         // first make sure we propagate init
99
super.init();
100
101         DocumentBuilder JavaDoc parser = null;
102         String JavaDoc url = null;
103
104         // load stylesheets available
105
stylesheets = new Hashtable JavaDoc();
106         params = new Hashtable JavaDoc();
107         Iterator JavaDoc i = this.getPortletConfig().getInitParameterNames();
108         while (i.hasNext()) {
109             String JavaDoc name = (String JavaDoc)i.next();
110             String JavaDoc base = MimeType.HTML.toString();
111
112             if (name.startsWith("stylesheet")) {
113                 int idx=-1;
114                 if ((idx=name.indexOf("."))>-1) {
115                     base= name.substring(idx+1,name.length());
116                 }
117                 stylesheets.put(base, getPortletConfig().getInitParameter(name));
118             } else {
119                 params.put(name.toLowerCase(), getPortletConfig().getInitParameter(name));
120             }
121         }
122
123         // read content, clean it, parse it and cache the DOM
124
try
125         {
126             final DocumentBuilderFactory JavaDoc docfactory = DocumentBuilderFactory.newInstance();
127             //Have it non-validating
128
docfactory.setValidating(false);
129             parser= docfactory.newDocumentBuilder();
130             parser.setEntityResolver(new JetspeedXMLEntityResolver() );
131
132             url = getPortletConfig().getURL();
133             String JavaDoc content = JetspeedDiskCache.getInstance().getEntry( url ).getData();
134            CapabilityMap xmap =
135                CapabilityMapFactory.getCapabilityMap(CapabilityMapFactory.AGENT_XML);
136             setContent( new JetspeedClearElement(content), xmap );
137             InputSource JavaDoc isrc = new InputSource JavaDoc( this.cleanse( content ) );
138             isrc.setSystemId( url );
139             isrc.setEncoding("UTF-8");
140             this.document = parser.parse( isrc );
141             this.setMetainfo(document);
142
143         } catch ( Throwable JavaDoc t )
144         {
145
146             String JavaDoc message = "RSSPortlet: Couldn't parse out XML document -> " +
147                               url;
148
149             logger.error( message, t );
150             throw new PortletException( t.getMessage() );
151         }
152
153
154     }
155
156     /**
157      * Parse out title and description
158      *
159      * @param document
160      */

161     private void setMetainfo(Document JavaDoc document) throws PortletException
162     {
163         //Determine title and description for this portlet
164
String JavaDoc title = null;
165         String JavaDoc description = null;
166
167         //now find the channel node.
168
Node JavaDoc channel = null;
169
170         NodeList JavaDoc list = document.getElementsByTagName( "channel" );
171
172         if ( list.getLength() != 1 ) {
173             throw new PortletException( ERROR_NOT_VALID );
174         }
175
176         channel = list.item( 0 );
177
178         Node JavaDoc tn = getNode( channel, "title" );
179
180         if ( tn == null ) {
181             throw new PortletException( ERROR_NOT_VALID );
182         }
183         else
184         {
185             Node JavaDoc fc = tn.getFirstChild();
186             if (fc != null)
187             {
188                 title = fc.getNodeValue();
189             }
190         }
191
192         Node JavaDoc dn = getNode( channel, "description" );
193
194         if ( dn != null )
195         {
196             Node JavaDoc fc = dn.getFirstChild();
197             if (fc != null)
198             {
199                 description = fc.getNodeValue();
200             }
201         }
202
203         this.setTitle( title );
204         this.setDescription( description );
205     }
206
207     /**
208     This methods outputs the content of the portlet for a given
209     request.
210
211     @param data the RunData object for the request
212     @return the content to be displayed to the user-agent
213     */

214     public ConcreteElement getContent( RunData data )
215     {
216         if (org.apache.jetspeed.util.PortletSessionState.getPortletConfigChanged(this, data))
217         {
218             try
219             {
220                 init();
221             }
222             catch (PortletException pe)
223             {
224                 logger.error("Exception", pe);
225             }
226         }
227         CapabilityMap map = ((JetspeedRunData)data).getCapability();
228         String JavaDoc type = map.getPreferredType().toString();
229         ConcreteElement content = new JetspeedClearElement(INVALID_TYPE);
230         String JavaDoc stylesheet = (String JavaDoc)stylesheets.get(type);
231
232         if (stylesheet != null) {
233             content = getContent( data, map );
234             if ( content == null ) {
235                 try {
236                     content = new JetspeedClearElement(
237                         SimpleTransform.transform( this.document,
238                                                    stylesheet,
239                                                    this.params ) );
240                     setContent( content, map );
241                 } catch ( SAXException JavaDoc e ) {
242                     logger.error("Exception", e);
243                     content = new JetspeedClearElement(e.getMessage());
244                 }
245             }
246         }
247         else
248         {
249             if (map.getPreferredType().equals(MimeType.XML))
250             {
251                 return getContent( data, map );
252             }
253         }
254
255         return content;
256     }
257
258     /**
259     This portlet supports has many types as those
260     it has stylesheets defined for in its parameters
261
262     @see Portlet#supportsType
263     @param mimeType the MIME type queried
264     @return true if the portlet knows how to display
265     content for mimeType
266     */

267     public boolean supportsType( MimeType mimeType ) {
268
269         Enumeration JavaDoc en = stylesheets.keys();
270         while(en.hasMoreElements()) {
271             String JavaDoc type = (String JavaDoc)en.nextElement();
272             if (type.equals(mimeType.toString())) return true;
273         }
274
275         return false;
276     }
277
278     /**
279     Utility method for traversing the document parsed
280     DOM tree and retrieving a Node by tagname
281
282     @param start the parent node for the search
283     @param name the tag name to be searched for
284     @return the first child node of start whose tagname
285     is name
286     */

287     private final Node JavaDoc getNode( Node JavaDoc start, String JavaDoc name ) {
288
289         NodeList JavaDoc list = start.getChildNodes();
290
291         for ( int i = 0; i < list.getLength(); ++i ) {
292
293             Node JavaDoc node = list.item( i );
294
295             if ( node.getNodeName().equals( name ) ) {
296                 return node;
297             }
298         }
299         return null;
300     }
301
302     /**
303     Given a URL to some content, clean the content to Xerces can handle it
304     better. Right now this involves:
305     <ul>
306         <li>
307             If the document doesn't begin with "<?xml version=" truncate the
308             content until this is the first line
309         </li>
310
311     </ul>
312
313     */

314     private Reader JavaDoc cleanse( String JavaDoc content ) throws IOException JavaDoc {
315
316         String JavaDoc filtered = null;
317
318         //specify the XML declaration to search for... this is just a subset
319
//of the content but it will always exist.
320
String JavaDoc XMLDECL = "<?xml version=";
321
322         int start = content.indexOf( XMLDECL );
323
324         if ( start <= 0 ) {
325             filtered = content;
326         } else {
327             filtered = content.substring( start, content.length() );
328         }
329
330         return new StringReader JavaDoc( filtered );
331     }
332
333 }
334
335
Popular Tags