View Javadoc

1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one or more
3    * contributor license agreements.  See the NOTICE file distributed with
4    * this work for additional information regarding copyright ownership.
5    * The ASF licenses this file to You under the Apache License, Version 2.0
6    * (the "License"); you may not use this file except in compliance with
7    * the License.  You may obtain a copy of the License at
8    * 
9    *      http://www.apache.org/licenses/LICENSE-2.0
10   * 
11   * Unless required by applicable law or agreed to in writing, software
12   * distributed under the License is distributed on an "AS IS" BASIS,
13   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14   * See the License for the specific language governing permissions and
15   * limitations under the License.
16   */
17  package org.apache.portals.applications.rss;
18  
19  import java.io.BufferedInputStream;
20  import java.io.BufferedReader;
21  import java.io.IOException;
22  import java.io.InputStreamReader;
23  import java.io.Reader;
24  import java.io.StringReader;
25  import java.io.StringWriter;
26  import java.net.URL;
27  import java.net.URLConnection;
28  import java.util.Enumeration;
29  import java.util.HashMap;
30  import java.util.Map;
31  
32  import javax.portlet.PortletConfig;
33  import javax.portlet.PortletException;
34  import javax.portlet.PortletPreferences;
35  import javax.portlet.RenderRequest;
36  import javax.portlet.RenderResponse;
37  import javax.xml.parsers.DocumentBuilder;
38  import javax.xml.parsers.DocumentBuilderFactory;
39  
40  import org.apache.portals.applications.transform.TransformCacheEntry;
41  import org.apache.portals.applications.util.Streams;
42  import org.w3c.dom.Document;
43  import org.w3c.dom.Node;
44  import org.w3c.dom.NodeList;
45  import org.xml.sax.EntityResolver;
46  import org.xml.sax.InputSource;
47  
48  
49  /***
50   * RSSPortlet
51   * 
52   * @author <a href="mailto:taylor@apache.org">David Sean Taylor </a>
53   * @version $Id: RSSPortlet.java 517719 2007-03-13 15:05:48Z ate $
54   */
55  public class RSSPortlet extends AbstractRssPortlet implements EntityResolver
56  {
57  
58      private Document document = null;
59  
60      private Map stylesheets = null;
61      
62      public void init(PortletConfig config) throws PortletException
63      {
64          super.init(config);
65  
66          // load stylesheets available
67          stylesheets = new HashMap();
68  
69          Enumeration e = this.getPortletConfig().getInitParameterNames();
70          while (e.hasMoreElements())
71          {
72              String name = (String) e.nextElement();
73              String base = "text/html";
74  
75              if (name.startsWith("stylesheet"))
76              {
77                  int idx = -1;
78                  if ((idx = name.indexOf(".")) > -1)
79                  {
80                      base = name.substring(idx + 1, name.length());
81                  }
82                  stylesheets.put(base, getPortletConfig().getInitParameter(name));
83              }
84          }
85      }
86  
87      public InputSource resolveEntity(String publicId, String systemId)
88      {
89          try
90          {
91              //access Jetspeed cache and get a java.io.Reader
92              Reader rdr = openURL(publicId);
93              InputSource is = new InputSource(rdr);
94              is.setPublicId(publicId);
95              is.setSystemId(systemId);
96              return is;
97          }
98          catch (IOException x)
99          {
100             System.err.println("Entity Resolution error: ( " + publicId + " Taking " + systemId + " from cache throwed Exception: " + x);
101 
102         }
103         return null;
104     }
105 
106     private Reader openURL(String urlPath) throws IOException
107     {
108         URL url = new URL(urlPath);
109         URLConnection conn = url.openConnection();
110 
111         String enc = conn.getContentEncoding();
112         if (enc == null)
113         {
114             enc = "ISO-8859-1";
115         }
116 
117         BufferedInputStream is = new BufferedInputStream(conn.getInputStream());
118         is.mark(20480);
119         BufferedReader asciiReader = new BufferedReader(new InputStreamReader(is, "ASCII"));
120         String decl = asciiReader.readLine();
121         String key = "encoding=\"";
122         if (decl != null)
123         {
124             int off = decl.indexOf(key);
125             if (off > 0)
126             {
127                 enc = decl.substring(off + key.length(), decl.indexOf('"', off + key.length()));
128             }
129         }
130         //Reset the bytes read
131         is.reset();
132         Reader rdr = new InputStreamReader(is, enc);
133         return rdr;
134     }    
135     
136     public Document getDocument(String url)
137     throws Exception
138     {
139         DocumentBuilder parser = null;
140         
141         // read content, clean it, parse it and cache the DOM try { final
142         DocumentBuilderFactory docfactory = DocumentBuilderFactory.newInstance(); //Have it non-validating
143         docfactory.setValidating(false); 
144         parser = docfactory.newDocumentBuilder(); 
145         parser.setEntityResolver(this);
146 
147         Reader rdr = openURL(url);
148         InputSource isrc = new InputSource(rdr);
149         isrc.setSystemId(url);
150         this.document = parser.parse(isrc);
151         return document;        
152     }
153     
154     
155     public void doView(RenderRequest request, RenderResponse response) throws PortletException, IOException
156     {
157         response.setContentType("text/html");
158         
159         
160         PortletPreferences prefs = request.getPreferences();
161             
162         // TODO: use stylesheet based on mimetype            
163         String stylesheet = getPortletConfig().getInitParameter("stylesheet");
164         String realStylesheet = getPortletConfig().getPortletContext().getRealPath(stylesheet);
165         String url = prefs.getValue("url", "http://news.bbc.co.uk/rss/sportonline_uk_edition/football/internationals/england/squad_profiles/rss091.xml");        
166 
167         String key = cache.constructKey(url, stylesheet); // TODO: use the entire parameter list
168         TransformCacheEntry entry = cache.get(key);
169         if (entry != null)
170         {
171             byte[] bytes = (byte[])entry.getDocument();
172             Streams.drain(new StringReader(new String(bytes,"UTF-8")),  response.getWriter());
173         }
174         else
175         {
176             try
177             {
178                 Document document = getDocument(url);
179                 InputSource source = new InputSource(url);
180                 source.setSystemId(url); 
181                 source.setEncoding("UTF-8");                
182                 
183                 Map parameters = new HashMap();            
184                 parameters.put("itemdisplayed", prefs.getValue("itemdisplayed", "15"));
185                 parameters.put("openinpopup", prefs.getValue("openinpopup", "true"));
186                 parameters.put("showdescription", prefs.getValue("showdescription", "true"));
187                 parameters.put("showtitle", prefs.getValue("showtitle", "true"));
188                 parameters.put("showtextinput", prefs.getValue("showtextinput", "true"));
189                            
190                 StringWriter sw= new StringWriter();
191                 transform.transform(realStylesheet, source, sw, parameters); //response.getPortletOutputStream(), parameters);
192                 Streams.drain(new StringReader(sw.toString()), response.getWriter());
193                 try
194                 {
195                 	// Java 1.5 only
196                     // String t = document.getDocumentElement().getElementsByTagName("title").item(0).getTextContent();
197                     NodeList nodes = document.getDocumentElement().getElementsByTagName("title");
198                     if (nodes != null)
199                     {
200                         Node node = nodes.item(0);
201                         if (node != null)
202                         {
203                             Node title = node.getFirstChild();
204                             if (title != null)
205                                 response.setTitle(title.getNodeValue());
206                         }
207                     }
208                 }
209                 catch(Exception e)
210                 {
211                 	
212                 }
213                 
214                 cache.put(key, sw.toString().getBytes("UTF-8"), 15);                
215             }
216             catch (Exception ex)
217             {
218                 response.getPortletOutputStream().write(new String("Failed to process RSS Feed: " + url + ", " + ex).getBytes());
219             }
220         }
221     }
222     
223 }