View Javadoc

1   /**
2    * Copyright 2005-2006 the original author or authors.
3    *
4    * Licensed under the Gnu General Pubic License, Version 2.0 (the
5    * "License"); you may not use this file except in compliance with
6    * the License. You may obtain a copy of the License at
7    *
8    *      http://www.opensource.org/licenses/gpl-license.php
9    *
10   * This program is distributed in the hope that it will be useful,
11   * but WITHOUT ANY WARRANTY; without even the implied warranty of
12   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
13   * See the Gnu General Public License for more details.
14   */
15  package org.figure8.join.control;
16  
17  import org.figure8.join.core.ContainerContextHandler;
18  import org.figure8.join.core.InvalidParameterException;
19  import org.figure8.join.businessobjects.commons.Release;
20  import org.figure8.join.businessobjects.reporting.Message;
21  import org.figure8.join.businessfacades.commons.IntegrationProcessManager;
22  import org.figure8.join.businessfacades.reporting.ReportingManager;
23  import org.figure8.join.util.LogUtil;
24  
25  import org.apache.commons.logging.Log;
26  
27  import com.sun.syndication.io.FeedException;
28  import com.sun.syndication.io.SyndFeedOutput;
29  import com.sun.syndication.feed.synd.SyndFeed;
30  import com.sun.syndication.feed.synd.SyndEntry;
31  import com.sun.syndication.feed.synd.SyndContent;
32  import com.sun.syndication.feed.synd.SyndFeedImpl;
33  import com.sun.syndication.feed.synd.SyndEntryImpl;
34  import com.sun.syndication.feed.synd.SyndContentImpl;
35  
36  import javax.servlet.http.HttpServlet;
37  import javax.servlet.http.HttpServletRequest;
38  import javax.servlet.http.HttpServletResponse;
39  
40  import java.io.IOException;
41  import java.util.List;
42  import java.util.ArrayList;
43  /**
44   * This a servlet endpoint for news feed generation and distribution. Each
45   * request may contain 2 parameters : <b>type</b> may specify the format of
46   * syndication feed wanted by client (rss_0.9, rss_1.0, rss_2.0 and atom_0.3 are
47   * currently supported), <b>release</b> may contain the name of release to filter
48   * news for.
49   * @author  <a href="mailto:laurent.broudoux@free.fr">Laurent Broudoux</a>
50   * @version $Revision: 1.1 $
51   */
52  public class FeedServlet extends HttpServlet{
53  
54     // Static -------------------------------------------------------------------
55     
56     /** Get a commons logger. */
57     private static final Log log = LogUtil.getLog(FeedServlet.class);
58  
59     /** Constant denoting the request parameter specifying the type of feed to generate. */
60     public static final String FEED_TYPE_PARAM = "type";
61     /** Constant denoting the request parameter specifying the release for whom feed should be generated. */
62     public static final String RELEASE_PARAM = "release";
63  
64     /** Constant for the default feed type (RSS 2.0) */
65     public static final String DEFAULT_TYPE = "rss_2.0";
66     /** Constant for error message returned to client */
67     public static final String COULD_NOT_GENERATE_FEED_ERROR = "Could not generate feed for the moment. Service is unavailable.";
68  
69  
70     // Attributes ---------------------------------------------------------------
71     
72     /** The reporting manager implementation to use for retrieving messages. */
73     private ReportingManager reportingManager = null;
74     /** The integration process manager to use for retrieving releases. */
75     private IntegrationProcessManager processManager = null;
76  
77  
78     // Override of HttpServlet --------------------------------------------------
79  
80     /**
81      * Generate and render a syndication feed depending on request parameters
82      * (type and release). See this class Javadoc for more details.
83      * @param request The Http request wrapper
84      * @param response The Http response wrapper
85      * @throws IOException if something wrong occurs during writing of response stream
86      */
87     public void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException{
88        try{
89           // Retrieve reporting and process managers if necessary.
90           initializeManagers();
91  
92           // Retrieve the release (if specified).
93           Release release = null;
94           String releaseName = request.getParameter(RELEASE_PARAM);
95           if (releaseName != null && releaseName.length() > 0)
96              release = processManager.getRelease(releaseName);
97  
98           if (log.isDebugEnabled())
99              log.debug("Generating a syndication feed for release '" + releaseName + "'");
100 
101          // Retrieve the open messages.
102          List messages = reportingManager.getOpenMessages(release);
103          SyndFeed feed = createFeed(messages);
104 
105          // Set the type of this feed from request or apply default type.
106          String feedType = request.getParameter(FEED_TYPE_PARAM);
107          feedType = (feedType != null) ? feedType : DEFAULT_TYPE;
108          feed.setFeedType(feedType);
109 
110          // Output feed stream onto response writer.
111          response.setContentType("text/xml");
112          SyndFeedOutput output = new SyndFeedOutput();
113          output.output(feed, response.getWriter());
114       }
115       catch (Exception e){
116          // Log exception and tell user that feed cannot be generated.
117          log.error("Exception while generating a feed for release: " + request.getParameter(RELEASE_PARAM));
118          log.error("Here's the detailed message: " + e.getMessage());
119          response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, COULD_NOT_GENERATE_FEED_ERROR);
120       }
121    }
122    
123    
124    // Protected ----------------------------------------------------------------
125    
126    /**
127     * Retrieve the integration process and reporting managers if they have
128     * not been initialized yet.
129     * @throws InvalidParameterException if they cannot be retrieved
130     */
131    protected void initializeManagers() throws InvalidParameterException{
132       if (reportingManager == null || processManager == null){
133          ContainerContextHandler handler = ContainerContextHandler.getInstance();
134          processManager = (IntegrationProcessManager)handler.getComponent("processManager");
135          reportingManager = (ReportingManager)handler.getComponent("reportingManager");
136       }
137    }
138    
139    /**
140     * Create a feed using a list of messages.
141     * @param messages A list of {@code Message}s
142     * @return A SyndicationFeed corresponding to messages.
143     */
144    protected SyndFeed createFeed(List messages) throws FeedException{
145       // Create new feed.
146       SyndFeed feed = new SyndFeedImpl();
147       feed.setTitle("Integration Portal News Feeds");
148       feed.setLink("http://join.sourceforge.net");
149       feed.setDescription("This feed has been created using ROME (Java syndication utilities)");
150       // Browse messages and add corresponding entries.
151       List entries = new ArrayList(messages.size());
152       for (int i=0; i < messages.size(); i++){
153          Message message = (Message)messages.get(i);
154          SyndEntry entry = createFeedEntry(message);
155          entries.add(entry);
156       }
157       feed.setEntries(entries);
158       return feed;
159    }
160    
161    /**
162     * Create a feed entry from a message.
163     * @param message Message to use for creating entry
164     * @return A Syndication feed entry
165     */
166    protected SyndEntry createFeedEntry(Message message) throws FeedException{
167       // Create an entry for message.
168       SyndEntry entry = new SyndEntryImpl();
169       entry.setTitle(message.getTitle());
170       entry.setLink(message.getLink());
171       entry.setPublishedDate(message.getPublicationDate());
172       // Add description to entry.
173       SyndContent description = new SyndContentImpl();
174       description.setType("text/html");
175       description.setValue(message.getContent());
176       entry.setDescription(description);
177       return entry;
178    }
179 }