1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.apache.jetspeed.portal.portlets;
18
19
20 import java.io.IOException;
21 import java.io.Reader;
22 import java.io.StringReader;
23 import java.util.Vector;
24
25
26 import org.apache.jetspeed.util.JetspeedClearElement;
27
28
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
37 import javax.xml.parsers.DocumentBuilder;
38 import javax.xml.parsers.DocumentBuilderFactory;
39
40
41 import org.w3c.dom.Document;
42 import org.w3c.dom.Node;
43 import org.w3c.dom.NodeList;
44 import org.xml.sax.InputSource;
45 import org.xml.sax.SAXException;
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 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 parser = null;
76 Document document = null;
77 String url = null;
78
79 try {
80 final DocumentBuilderFactory docfactory = DocumentBuilderFactory.newInstance();
81
82 docfactory.setValidating(false);
83 parser= docfactory.newDocumentBuilder();
84
85 parser.setEntityResolver(new JetspeedXMLEntityResolver() );
86
87 url = this.getPortletConfig().getURL();
88
89 String content = JetspeedDiskCache.getInstance().getEntry( url ).getData();
90 InputSource is = new InputSource( this.cleanse( content ) );
91
92
93 is.setEncoding( "UTF8" );
94 is.setSystemId( url );
95
96
97
98 document = parser.parse( is );
99
100 } catch ( Throwable t )
101 {
102
103 String 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
112 try {
113
114
115 this.setItems( this.parseItems( document ) );
116
117 String title = null;
118 String description = null;
119
120
121 Node root = document.getFirstChild();
122
123 Node channel = null;
124
125 NodeList 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 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 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
152
153 String 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
161 String content = SimpleTransform.transform( document,
162 stylesheet,
163 this.getPortletConfig().getInitParameters() );
164
165 this.setContent( new JetspeedClearElement( content ) );
166
167
168 } catch ( SAXException e ) {
169 logger.error("Exception", e);
170 throw new PortletException( e.getMessage() );
171 }
172 } catch (Throwable t) {
173 String 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 getNode( Node start, String name ) {
191
192 NodeList list = start.getChildNodes();
193
194 for ( int i = 0; i < list.getLength(); ++i ) {
195
196 Node 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 cleanse( String content ) throws IOException, SAXException {
221
222 String filtered = null;
223
224
225
226 String 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( 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
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 doc ) {
265
266 String root = doc.getDocumentElement().getTagName();
267
268 if ( root.equals( "rdf:RDF" ) ) {
269
270 NodeList list = doc.getElementsByTagName( "item" );
271
272 return getItems( list );
273
274
275
276 } else if ( root.equals( "rss" ) ) {
277
278 NodeList list = doc.getElementsByTagName( "channel" );
279
280 if ( list.getLength() != 1 ) {
281
282 return new Item[0];
283 }
284
285 Node channel = list.item( 0 );
286
287
288
289 return getItems( channel.getChildNodes() );
290
291
292 } else if ( root.equals( "xml" ) ) {
293
294 NodeList list = doc.getElementsByTagName( "item" );
295
296 return getItems( list );
297
298
299
300 } else {
301
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 items ) {
311
312
313 Vector v = new Vector();
314
315 for ( int i = 0; i < items.getLength(); ++i ) {
316
317 Node node = items.item( i );
318
319
320 if ( node.getNodeName().equals( "item" ) == false ) {
321 continue;
322 }
323
324 NodeList itemChildren = node.getChildNodes();
325
326 String title = null;
327 String link = null;
328 String description = null;
329
330 for ( int j = 0; j < itemChildren.getLength(); ++j ) {
331
332
333 Node 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 title;
370 private String link;
371 private String description;
372
373 public Item( String title,
374 String link,
375 String description ) {
376 this( title, link );
377 this.description = description;
378
379 }
380
381 public Item ( String title,
382 String link ) {
383 this.title = title;
384 this.link = link;
385 }
386
387 public String getTitle() {
388 return this.title;
389 }
390
391 public String getLink() {
392 return this.link;
393 }
394
395 /***
396 Get the description for this item... it may be null.
397 */
398 public String getDescription() {
399 return this.description;
400 }
401
402 }
403
404 }