1<?xml version="1.0" encoding="UTF-8"?>
2
3<%@ page import="java.util.*,com.ecyrd.jspwiki.*" %>
4<%@ page import="org.apache.log4j.*" %>
5<%@ page import="java.text.*" %>
6<%@ page import="com.ecyrd.jspwiki.rss.*" %>
7<%@ page import="com.ecyrd.jspwiki.util.*" %>
8<%@ page import="com.opensymphony.oscache.base.*" %>
9<%@ taglib uri="/WEB-INF/oscache.tld" prefix="oscache" %>
10
11<%!
12    Logger log = Logger.getLogger("JSPWiki");
13    Cache m_cache = new Cache( true, false, false, true,
14                               "com.opensymphony.oscache.base.algorithm.LRUCache", 256 );
15%>
16
17<%
18    WikiEngine wiki = WikiEngine.getInstance( getServletConfig() );
19    // Create wiki context and check for authorization
20    WikiContext wikiContext = wiki.createContext( request, "rss" );
21    if(!wikiContext.hasAccess( response )) return;
22    WikiPage    wikipage    = wikiContext.getPage();
23
24    // Redirect if baseURL not set or RSS generation not on
25    if( wiki.getBaseURL().length() == 0 )
26    {
27        response.sendError( 500, "The jspwiki.baseURL property has not been defined for this wiki - cannot generate RSS" );
28        return;
29    }
30
31    if( wiki.getRSSGenerator() == null )
32    {
33        response.sendError( 404, "RSS feeds are disabled at administrator request" );
34        return;
35    }
36
37    if( wikipage == null || !wiki.pageExists(wikipage.getName()) )
38    {
39        response.sendError( 404, "No such page "+wikipage.getName() );
40        return;
41    }
42
43    WatchDog w = wiki.getCurrentWatchDog();
44    w.enterState("Generating RSS",60);
45
46    // Set the mode and type for the feed
47    String      mode        = request.getParameter("mode");
48    String      type        = request.getParameter("type");
49
50    if( mode == null || !(mode.equals(RSSGenerator.MODE_BLOG) || mode.equals(RSSGenerator.MODE_WIKI)) )
51    	   mode = RSSGenerator.MODE_BLOG;
52    if( type == null || !(type.equals(RSSGenerator.RSS10) || type.equals(RSSGenerator.RSS20) || type.equals(RSSGenerator.ATOM)) )
53    	   type = RSSGenerator.RSS20;
54
55    // Force the TranslatorReader to output absolute URLs
56    // regardless of the current settings.
57    wikiContext.setVariable( WikiEngine.PROP_REFSTYLE, "absolute" );
58
59    // Set the content type and include the response content
60    response.setContentType( RSSGenerator.getContentType(type)+"; charset=UTF-8");
61
62    StringBuffer result = new StringBuffer();
63    SimpleDateFormat iso8601fmt = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'");
64
65    Properties properties = wiki.getWikiProperties();
66    String channelDescription = wiki.getRequiredProperty( properties, RSSGenerator.PROP_CHANNEL_DESCRIPTION );
67    String channelLanguage    = wiki.getRequiredProperty( properties, RSSGenerator.PROP_CHANNEL_LANGUAGE );
68
69    //
70    //  Now, list items.
71    //
72    List changed;
73
74    if( mode.equals("blog") )
75    {
76        com.ecyrd.jspwiki.plugin.WeblogPlugin plug = new com.ecyrd.jspwiki.plugin.WeblogPlugin();
77        changed = plug.findBlogEntries(wiki.getPageManager(),
78                                       wikipage.getName(),
79                                       new Date(0L),
80                                       new Date());
81    }
82    else
83    {
84        changed = wiki.getVersionHistory( wikipage.getName() );
85    }
86
87    //
88    //  Check if nothing has changed, so we can just return a 304
89    //
90    boolean hasChanged = false;
91    Date    latest     = new Date(0);
92
93    for( Iterator i = changed.iterator(); i.hasNext(); )
94    {
95        WikiPage p = (WikiPage) i.next();
96
97        if( !HttpUtil.checkFor304( request, p ) ) hasChanged = true;
98        if( p.getLastModified().after( latest ) ) latest = p.getLastModified();
99    }
100
101    if( !hasChanged && changed.size() > 0 )
102    {
103        response.sendError( HttpServletResponse.SC_NOT_MODIFIED );
104        w.exitState();
105        return;
106    }
107
108    response.addDateHeader("Last-Modified",latest.getTime());
109    response.addHeader("ETag", HttpUtil.createETag(wikipage) );
110
111    //
112    //  Try to get the RSS XML from the cache.  We build the hashkey
113    //  based on the LastModified-date, so whenever it changes, so does
114    //  the hashkey so we don't have to make any special modifications.
115    //
116    //  TODO: Figure out if it would be a good idea to use a disk-based
117    //        cache here.
118    //
119    String hashKey = wikipage.getName()+";"+mode+";"+type+";"+latest.getTime();
120
121    String rss = "";
122
123    try
124    {
125        rss = (String)m_cache.getFromCache(hashKey);
126    }
127    catch( NeedsRefreshException e )
128    {
129        try
130        {
131            rss = wiki.getRSSGenerator().generateFeed( wikiContext, changed, mode, type );
132            m_cache.putInCache(hashKey,rss);
133        }
134        catch( Exception e1 )
135        {
136            m_cache.cancelUpdate(hashKey);
137        }
138    }
139
140    out.println(rss);
141
142    w.exitState();
143    %>
144