View Javadoc

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  //Element Construction Set
20  import org.apache.jetspeed.util.JetspeedClearElement;
21  import org.apache.ecs.ConcreteElement;
22  
23  //Jetspeed stuff
24  import org.apache.jetspeed.portal.PortletConfig;
25  import org.apache.jetspeed.portal.PortletException;
26  import org.apache.jetspeed.services.logging.JetspeedLogFactoryService;
27  import org.apache.jetspeed.services.logging.JetspeedLogger;
28  import org.apache.jetspeed.util.rewriter.Rewriter;
29  import org.apache.jetspeed.util.rewriter.HTMLRewriter;
30  import org.apache.jetspeed.util.Base64;
31  import org.apache.jetspeed.util.template.JetspeedLink;
32  import org.apache.jetspeed.util.template.JetspeedLinkFactory;
33  
34  //turbine
35  import org.apache.turbine.util.RunData;
36  
37  //standard java stuff
38  import java.io.InputStreamReader;
39  import java.io.IOException;
40  import java.io.Reader;
41  import java.net.URL;
42  import java.net.URLConnection;
43  
44  /***
45   * A class that loads a web page and filters it to have certain features
46   * deleted.
47   *
48   * @author <a href="mailto:taylor@apache.org">David Sean Taylor</a>
49   */
50  public class WebPagePortlet2 extends AbstractInstancePortlet 
51  {
52  
53      /***
54       * Static initialization of the logger for this class
55       */    
56      private static final JetspeedLogger logger = JetspeedLogFactoryService.getLogger(WebPagePortlet2.class.getName());
57      
58      protected Rewriter rewriter = null;
59      protected boolean initDone = false;
60      protected boolean contentStale = true;
61      protected boolean cacheContent = false;
62      protected String  username = null;
63      protected String  password = null;
64      
65      /***
66       * Initialize this portlet by defining a HTML rewriter.
67       * @throws PortletException Initialization failed
68       */    
69      public void init() throws PortletException 
70      {
71    
72          if (initDone) // Why is init called more than once per portlet?
73              return;
74  
75          PortletConfig config = this.getPortletConfig();
76          
77          try 
78          {
79              rewriter = new HTMLRewriter();
80  
81              // fetch username and password for HTTP Basic Autentication
82              username = config.getInitParameter("username");
83              password = config.getInitParameter("password");
84              
85              contentStale = true;
86              initDone = true;
87          } 
88          catch (Exception e) 
89          {
90              logger.info("Exception occurred:" + e.toString(), e);
91              throw new PortletException( e.toString() );
92          }
93      }
94      
95      /***
96       * took this from FileServerPortlet as it was private 
97       *
98      */
99  
100     // FIXME: Currently only the expiration the HTTP Response header is honored. 
101     //        Expiration information in <meta> tags are not honored 
102 
103     protected Reader getReader(String url) throws IOException 
104     {
105         URL            pageUrl = new URL(url);
106 
107         URLConnection  pageConn = pageUrl.openConnection();
108         try
109         {
110             // set HTTP Basic Authetication header if username and password are set
111             if (username != null && password !=null)
112             {
113                 pageConn.setRequestProperty("Authorization", "Basic " +
114                                         Base64.encodeAsString(username + ":" + password));
115             }
116                 
117         }
118         catch (Exception e)
119         {
120             logger.info("Exception occurred:" + e.toString(), e);
121         }
122         
123         long           pageExpiration = pageConn.getExpiration();
124         String         encoding = pageConn.getContentEncoding();
125         String         tempString = null;
126         String         noCache = "no-cache";
127         
128         if(encoding == null)
129         {
130             // Standard HTTP encoding
131             encoding = "iso-8859-1";
132         }
133 
134         /*
135          * Determing if content should be cached.
136          */
137         cacheContent = true; // Assume content is cached
138         if (pageExpiration == 0) 
139         {
140             cacheContent = false;
141         }
142         // Check header field CacheControl
143         tempString = pageConn.getHeaderField( "Cache-Control");
144         if (tempString != null)
145          {
146             if (tempString.toLowerCase().indexOf(noCache) >= 0) 
147             {
148                 cacheContent = false;
149             }
150         }
151         // Check header field Pragma
152         tempString = pageConn.getHeaderField( "Pragma");
153         if (tempString != null) 
154         {
155             if (tempString.toLowerCase().indexOf(noCache) >= 0) 
156             {
157                 cacheContent = false;
158             }
159         }
160             
161         // Assign a reader
162         Reader rdr = new InputStreamReader(pageConn.getInputStream(),
163                                            encoding );
164 
165         // Only set the page expiration it the page has not expired
166         if (pageExpiration > System.currentTimeMillis() && (cacheContent == true))
167         {
168             contentStale = false;
169             if ( logger.isDebugEnabled() )
170             {
171                 logger.debug( "WebPagePortlet caching URL: " + 
172                        url + 
173                        " Expiration: " + 
174                        pageExpiration +
175                        ", " +
176                        (pageExpiration - System.currentTimeMillis() ) +
177                        " milliseconds into the future" );
178             }
179             setExpirationMillis(pageExpiration);
180         } 
181         else 
182         {
183             contentStale = true;
184         }
185 
186         return rdr;
187     }
188 
189 
190     /***
191     This methods outputs the content of the portlet for a given 
192     request.
193 
194     @param data the RunData object for the request
195     @return the content to be displayed to the user-agent
196     */
197     public ConcreteElement getContent( RunData data ) 
198     {
199         PortletConfig config = this.getPortletConfig();
200         
201         if (contentStale == true)
202             return getWebPageContent(data, config);
203         
204         if (null == getExpirationMillis())
205             return getContent( data, null, true);
206         
207         if (getExpirationMillis().longValue() <= System.currentTimeMillis())
208             return getWebPageContent(data, config);
209 
210         return getContent( data, null , true );
211     }
212 
213     private ConcreteElement getWebPageContent( RunData data, PortletConfig config )
214     {    
215         
216         String convertedString = null;  // parsed and re-written HTML
217         JetspeedClearElement element = null;
218 
219         String url = selectUrl( data, config );
220 
221         try 
222         {
223             JetspeedLink jsLink = JetspeedLinkFactory.getInstance(data);            
224             Reader htmlReader = getReader( url );
225             convertedString = rewriter.rewrite(htmlReader, jsLink.toString());
226             element = new JetspeedClearElement(convertedString);
227             
228             System.out.println("js link = " + jsLink.toString());            
229             JetspeedLinkFactory.putInstance(jsLink);
230 
231             //FIXME: We should do a clearContent() for the media type, not ALL media types
232             this.clearContent();  // doing this because setContent() is not overwriting current content.
233             this.setContent(element);
234 
235             htmlReader.close();
236         } 
237         catch (Exception e) 
238         {
239             logger.info("Exception occurred:" + e.toString(), e);
240         }        
241 
242         return element;
243     }
244     
245     /***
246      * Usually called by caching system when portlet is marked as expired, but
247      * has not be idle longer then TimeToLive.
248      *
249      * Any cached content that is expired need to be refreshed.
250      */
251     public void refresh() 
252     {
253         if (cacheContent == true) 
254         {
255           getWebPageContent(null, this.getPortletConfig());
256         }
257     }
258 
259     /***
260     * Select the URL to use for this portlet.
261     * @return The URL to use for this portlet
262     */
263     protected String selectUrl( RunData data, PortletConfig config )
264     {
265         String url = config.getURL();
266 
267         return url;
268 
269     }   // selectUrl
270 
271 }
272