KickJava   Java API By Example, From Geeks To Geeks.

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


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.Vector JavaDoc;
24
25 //Element Construction Set
26
import org.apache.jetspeed.util.JetspeedClearElement;
27
28 //standard Jetspeed stuff
29
import org.apache.jetspeed.util.SimpleTransform;
30 import org.apache.jetspeed.cache.disk.JetspeedDiskCache;
31 import org.apache.jetspeed.portal.PortletException;
32 import org.apache.jetspeed.services.logging.JetspeedLogFactoryService;
33 import org.apache.jetspeed.services.logging.JetspeedLogger;
34 import org.apache.jetspeed.xml.JetspeedXMLEntityResolver;
35
36 //JAXP support
37
import javax.xml.parsers.DocumentBuilder JavaDoc;
38 import javax.xml.parsers.DocumentBuilderFactory JavaDoc;
39
40 //XML stuff
41
import org.w3c.dom.Document JavaDoc;
42 import org.w3c.dom.Node JavaDoc;
43 import org.w3c.dom.NodeList JavaDoc;
44 import org.xml.sax.InputSource JavaDoc;
45 import org.xml.sax.SAXException JavaDoc;
46
47 /**
48 Portlet to change RDF Site Summary into a portlet format for HTML presentation.
49
50 @author <A HREF="mailto:burton@apache.org">Kevin A. Burton</A>
51 @author <A HREF="mailto:sgala@hisitech.com">Santiago Gala</A>
52 @version $Id: RSSPortlet.java,v 1.52 2004/02/23 04:03:33 jford Exp $
53 */

54 public class RSSPortlet extends FileWatchPortlet
55 {
56
57     /**
58      * Static initialization of the logger for this class
59      */

60     private static final JetspeedLogger logger = JetspeedLogFactoryService.getLogger(RSSPortlet.class.getName());
61     
62     public final static String JavaDoc ERROR_NOT_VALID = "This does not appear to be an RSS document";
63
64     /**
65     The
66     */

67     private Item[] items = new Item[0];
68
69     /**
70     @author <A HREF="mailto:burton@apache.org">Kevin A. Burton</A>
71     @version $Id: RSSPortlet.java,v 1.52 2004/02/23 04:03:33 jford Exp $
72     */

73     public void init( ) throws PortletException {
74
75         DocumentBuilder JavaDoc parser = null;
76         Document JavaDoc document = null;
77         String JavaDoc url = null;
78
79         try {
80             final DocumentBuilderFactory JavaDoc docfactory = DocumentBuilderFactory.newInstance();
81             //Have it non-validating
82
docfactory.setValidating(false);
83             parser= docfactory.newDocumentBuilder();
84             //SGP Changing Resolver to enable Reading through cache
85
parser.setEntityResolver(new JetspeedXMLEntityResolver() );
86
87             url = this.getPortletConfig().getURL();
88
89             String JavaDoc content = JetspeedDiskCache.getInstance().getEntry( url ).getData();
90             InputSource JavaDoc is = new InputSource JavaDoc( this.cleanse( content ) );
91
92             //SGP Should make no difference ...
93
is.setEncoding( "UTF8" );
94             is.setSystemId( url );
95
96             //parser.setFeature( "http://apache.org/xml/features/allow-java-encodings",
97
// true );
98
document = parser.parse( is );
99
100         } catch ( Throwable JavaDoc t )
101         {
102
103             String JavaDoc message = "RSSPortlet: Couldn't parse out XML document -> " +
104                               url;
105
106             logger.error( message, t );
107             throw new PortletException( t.getMessage() );
108
109         }
110
111         //SGP giving NullPointer
112
try {
113             //now that we have the document set the items for this
114

115             this.setItems( this.parseItems( document ) );
116
117             String JavaDoc title = null;
118             String JavaDoc description = null;
119
120             //this a hack until DOM2 namespace support becomes better in Xerces.
121
Node JavaDoc root = document.getFirstChild();
122             //now find the channel node.
123
Node JavaDoc channel = null;
124
125             NodeList JavaDoc list = document.getElementsByTagName( "channel" );
126
127             if ( list.getLength() != 1 ) {
128                 throw new PortletException( ERROR_NOT_VALID );
129         }
130
131             channel = list.item( 0 );
132
133             Node JavaDoc tn = getNode( channel, "title" );
134
135             if ( tn == null ) {
136                 throw new PortletException( ERROR_NOT_VALID );
137             } else {
138                 title = tn.getFirstChild().getNodeValue();
139             }
140
141             Node JavaDoc dn = getNode( channel, "description" );
142
143             if ( dn != null ) {
144                 description = dn.getFirstChild().getNodeValue();
145             }
146
147             this.setTitle( title );
148             this.setDescription( description );
149
150
151             //now that we have the DOM we should be able to do a transform here.
152

153             String JavaDoc stylesheet = this.getPortletConfig().getInitParameter( "stylesheet" );
154
155             if ( stylesheet == null ) {
156                 throw new PortletException( "The 'stylesheet' parameter was not defined." );
157         }
158
159             try {
160                 //Set encoding for the document to utf-8...
161
String JavaDoc content = SimpleTransform.transform( document,
162                                                             stylesheet,
163                                                             this.getPortletConfig().getInitParameters() );
164
165                 this.setContent( new JetspeedClearElement( content ) );
166
167
168             } catch ( SAXException JavaDoc e ) {
169                 logger.error("Exception", e);
170                 throw new PortletException( e.getMessage() );
171             }
172         } catch (Throwable JavaDoc t) {
173             String JavaDoc message = "RSSPortlet: Couldn't set items for XML document -> " +
174                 url;
175
176
177             logger.error( message, t );
178             throw new PortletException( t.getMessage() );
179         }
180
181
182     }
183
184
185
186     /**
187     Given a base node... search this for a node with the given name and return
188     it or null if it does not exist
189     */

190     private static final Node JavaDoc getNode( Node JavaDoc start, String JavaDoc name ) {
191
192         NodeList JavaDoc list = start.getChildNodes();
193
194         for ( int i = 0; i < list.getLength(); ++i ) {
195
196             Node JavaDoc node = list.item( i );
197
198             if ( node.getNodeName().equals( name ) ) {
199                 return node;
200             }
201         }
202         return null;
203     }
204
205     /**
206     Given a URL to some content, clean the content to Xerces can handle it
207     better. Right now this involves:
208     <ul>
209         <li>
210             If the document doesn't begin with "<?xml version=" truncate the
211             content until this is the first line
212         </li>
213
214     </ul>
215
216     */

217     /**
218     test it...
219     */

220     private Reader JavaDoc cleanse( String JavaDoc content ) throws IOException JavaDoc, SAXException JavaDoc {
221
222         String JavaDoc filtered = null;
223
224         //specify the XML declaration to search for... this is just a subset
225
//of the content but it will always exist.
226
String JavaDoc XMLDECL = "<?xml version=";
227
228         int start = content.indexOf( XMLDECL );
229
230         if ( start <= 0 ) {
231             filtered = content;
232         } else {
233             filtered = content.substring( start, content.length() );
234         }
235
236         return new StringReader JavaDoc( filtered );
237     }
238
239     /**
240     Get the items that were defined by this XML content
241     */

242     public Item[] getItems() {
243         return this.items;
244     }
245
246     public void setItems( Item[] items ) {
247         this.items = items;
248     }
249
250
251     //Cacheable interface..
252

253     /**
254     @author <A HREF="mailto:burton@apache.org">Kevin A. Burton</A>
255     @version $Id: RSSPortlet.java,v 1.52 2004/02/23 04:03:33 jford Exp $
256     */

257     public boolean isCacheable() {
258         return true;
259     }
260
261     /**
262     Given a Document, find all the <item>'s and return them as peer's
263     */

264     private Item[] parseItems( Document JavaDoc doc ) {
265
266         String JavaDoc root = doc.getDocumentElement().getTagName();
267
268         if ( root.equals( "rdf:RDF" ) ) {
269
270             NodeList JavaDoc list = doc.getElementsByTagName( "item" );
271
272             return getItems( list );
273
274             //parse out each nodelist item and create
275

276         } else if ( root.equals( "rss" ) ) {
277
278             NodeList JavaDoc list = doc.getElementsByTagName( "channel" );
279
280             if ( list.getLength() != 1 ) {
281                 //if there aren't any channels there can't be any items.
282
return new Item[0];
283             }
284
285             Node JavaDoc channel = list.item( 0 );
286
287             //how get the items as a nodelist
288

289             return getItems( channel.getChildNodes() );
290
291
292           } else if ( root.equals( "xml" ) ) {
293
294             NodeList JavaDoc list = doc.getElementsByTagName( "item" );
295
296             return getItems( list );
297
298             //parse out each nodelist item and create
299

300           } else {
301             //don't know what to do...
302
return new Item[0];
303         }
304
305     }
306
307     /**
308     After you find the nodelist for items parse it out and get some Items
309     */

310     private Item[] getItems( NodeList JavaDoc items ) {
311
312
313         Vector JavaDoc v = new Vector JavaDoc();
314
315         for ( int i = 0; i < items.getLength(); ++i ) {
316
317             Node JavaDoc node = items.item( i );
318
319             //just make sure this is an <item> element
320
if ( node.getNodeName().equals( "item" ) == false ) {
321                 continue;
322             }
323
324             NodeList JavaDoc itemChildren = node.getChildNodes();
325
326             String JavaDoc title = null;
327             String JavaDoc link = null;
328             String JavaDoc description = null;
329
330             for ( int j = 0; j < itemChildren.getLength(); ++j ) {
331
332
333                 Node JavaDoc child = itemChildren.item( j );
334
335                 if ( child.getNodeName().equals( "title" ) ) {
336                     if ( child.getFirstChild() != null )
337                         title = child.getFirstChild().getNodeValue();
338                 }
339
340                 if ( child.getNodeName().equals( "link" ) ) {
341                     if ( child.getFirstChild() != null )
342                         link = child.getFirstChild().getNodeValue();
343                 }
344
345                 if ( child.getNodeName().equals( "description" ) ) {
346                     if (child.getFirstChild() != null) {
347                        description = child.getFirstChild().getNodeValue();
348                     }
349                 }
350
351
352             }
353
354             v.addElement( new Item( title, link, description ) );
355
356         }
357
358         Item[] foundItems = new Item[ v.size() ];
359         v.copyInto( foundItems );
360         return foundItems;
361
362     }
363
364     /**
365     Represents an RSS item.
366     */

367     public static class Item {
368
369         private String JavaDoc title;
370         private String JavaDoc link;
371         private String JavaDoc description;
372
373         public Item( String JavaDoc title,
374                      String JavaDoc link,
375                      String JavaDoc description ) {
376             this( title, link );
377             this.description = description;
378
379         }
380
381         public Item ( String JavaDoc title,
382                       String JavaDoc link ) {
383             this.title = title;
384             this.link = link;
385         }
386
387         public String JavaDoc getTitle() {
388             return this.title;
389         }
390
391         public String JavaDoc getLink() {
392             return this.link;
393         }
394
395         /**
396         Get the description for this item... it may be null.
397         */

398         public String JavaDoc getDescription() {
399             return this.description;
400         }
401
402     }
403
404 }
405
Popular Tags