File Source: PlanetFeedServlet.java
1 /*
2 * Licensed to the Apache Software Foundation (ASF) under one or more
3 * contributor license agreements. The ASF licenses this file to You
4 * under the Apache License, Version 2.0 (the "License"); you may not
5 * 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. For additional information regarding
15 * copyright in this work, please see the NOTICE file in the top level
16 * directory of this distribution.
17 */
18
19 package org.apache.roller.weblogger.ui.rendering.servlets;
20
21 import java.io.IOException;
22 import java.util.Date;
23 import java.util.HashMap;
24 import javax.servlet.ServletConfig;
25 import javax.servlet.ServletException;
26 import javax.servlet.http.HttpServlet;
27 import javax.servlet.http.HttpServletRequest;
28 import javax.servlet.http.HttpServletResponse;
29 import org.apache.commons.lang.StringUtils;
30 import org.apache.commons.logging.Log;
31 import org.apache.commons.logging.LogFactory;
32 import org.apache.roller.weblogger.config.WebloggerRuntimeConfig;
33 import org.apache.roller.planet.business.PlanetFactory;
34 import org.apache.roller.planet.business.PlanetManager;
35 import org.apache.roller.planet.config.PlanetRuntimeConfig;
36 import org.apache.roller.planet.pojos.Planet;
37 import org.apache.roller.weblogger.pojos.StaticTemplate;
38 import org.apache.roller.weblogger.pojos.Template;
39 import org.apache.roller.weblogger.ui.rendering.Renderer;
40 import org.apache.roller.weblogger.ui.rendering.RendererManager;
41 import org.apache.roller.weblogger.ui.rendering.model.UtilitiesModel;
42 import org.apache.roller.weblogger.ui.rendering.util.cache.PlanetCache;
43 import org.apache.roller.weblogger.ui.rendering.util.PlanetRequest;
44 import org.apache.roller.weblogger.ui.rendering.util.ModDateHeaderUtil;
45 import org.apache.roller.weblogger.util.cache.CachedContent;
46
47
48 /**
49 * Planet Roller (i.e. NOT for Planet Tool) RSS feed.
50 *
51 * @web.servlet name="PlanetFeedServlet" load-on-startup="7"
52 * @web.servlet-mapping url-pattern="/planetrss/*"
53 */
/*
P/P * Method: void org.apache.roller.weblogger.ui.rendering.servlets.PlanetFeedServlet()
*
* Postconditions:
* this.planetCache == null
*/
54 public class PlanetFeedServlet extends HttpServlet {
55
/*
P/P * Method: org.apache.roller.weblogger.ui.rendering.servlets.PlanetFeedServlet__static_init
*
* Postconditions:
* init'ed(log)
*/
56 private static Log log = LogFactory.getLog(PlanetFeedServlet.class);
57 private PlanetCache planetCache = null;
58
59 /**
60 * Init method for this servlet
61 */
62 public void init(ServletConfig servletConfig) throws ServletException {
63
/*
P/P * Method: void init(ServletConfig)
*
* Preconditions:
* log != null
* init'ed(org/apache/roller/weblogger/ui/rendering/util/cache/PlanetCache.singletonInstance)
*
* Postconditions:
* this.planetCache == org/apache/roller/weblogger/ui/rendering/util/cache/PlanetCache.singletonInstance
* init'ed(this.planetCache)
*/
64 super.init(servletConfig);
65
66 log.info("Initializing PlanetRssServlet");
67
68 this.planetCache = PlanetCache.getInstance();
69 }
70
71 /**
72 * Handle GET requests for weblog pages.
73 */
74 public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
75
/*
P/P * Method: void doGet(HttpServletRequest, HttpServletResponse)
*
* Preconditions:
* log != null
* (soft) init'ed(this.planetCache.lastUpdateTime)
* (soft) org/apache/roller/weblogger/ui/rendering/util/PlanetRequest.log != null
* (soft) org/apache/roller/weblogger/ui/rendering/util/cache/PlanetCache.log != null
* (soft) request != null
* (soft) response != null
* (soft) this.planetCache != null
* (soft) init'ed(this.planetCache.cacheEnabled)
* (soft) this.planetCache.contentCache != null
* (soft) init'ed(this.planetCache.timeout)
*
* Presumptions:
* java.util.Date:getTime(...)@94 - java.util.Date:getTime(...)@94%1_000 in -263..264-1
* javax.servlet.http.HttpServletResponse:getOutputStream(...)@118 != null
* javax.servlet.http.HttpServletResponse:getOutputStream(...)@215 != null
* org.apache.roller.planet.business.Planet:getPlanetManager(...)@78 != null
* org.apache.roller.planet.business.PlanetFactory:getPlanet(...)@78 != null
* ...
*
* Postconditions:
* this.planetCache.lastUpdateTime == One-of{old this.planetCache.lastUpdateTime, &new ExpiringCacheEntry(getLastModified#2)}
* (soft) init'ed(this.planetCache.lastUpdateTime)
* new ExpiringCacheEntry(getLastModified#2) num objects <= 1
*
* Test Vectors:
* java.lang.String:indexOf(...)@101: {-1}, {-231..-2, 0..232-1}
* java.lang.String:startsWith(...)@101: {0}, {1}
* javax.servlet.http.HttpServletRequest:getHeader(...)@100: Addr_Set{null}, Inverse{null}
* javax.servlet.http.HttpServletRequest:getHeader(...)@99: Addr_Set{null}, Inverse{null}
* javax.servlet.http.HttpServletRequest:getParameter(...)@128: Addr_Set{null}, Inverse{null}
* javax.servlet.http.HttpServletRequest:getParameter(...)@147: Addr_Set{null}, Inverse{null}
* org.apache.commons.lang.StringUtils:isNotEmpty(...)@138: {0}, {1}
*/
76 log.debug("Entering");
77
78 PlanetManager planet = PlanetFactory.getPlanet().getPlanetManager();
79
80 PlanetRequest planetRequest = null;
81 try {
82 planetRequest = new PlanetRequest(request);
83 } catch (Exception e) {
84 // some kind of error parsing the request
85 log.debug("error creating planet request", e);
86 response.sendError(HttpServletResponse.SC_NOT_FOUND);
87 return;
88 }
89
90 // figure planet last modified date
91 Date lastModified = planetCache.getLastModified();
92
93 // Respond with 304 Not Modified if it is not modified.
94 if (ModDateHeaderUtil.respondIfNotModified(request, response, lastModified.getTime())) {
95 return;
96 }
97
98 // set content type
99 String accepts = request.getHeader("Accept");
100 String userAgent = request.getHeader("User-Agent");
101 if (accepts != null && userAgent != null && accepts.indexOf("*/*") != -1 && userAgent.startsWith("Mozilla")) {
102 // client is a browser and now that we offer styled feeds we want
103 // browsers to load the page rather than popping up the download
104 // dialog, so we provide a content-type that browsers will display
105 response.setContentType("text/xml");
106 } else {
107 response.setContentType("application/rss+xml; charset=utf-8");
108 }
109
110 // set last-modified date
111 ModDateHeaderUtil.setLastModifiedHeader(response, lastModified.getTime());
112
113 // cached content checking
114 String cacheKey = PlanetCache.CACHE_ID + ":" + this.generateKey(planetRequest);
115 CachedContent entry = (CachedContent) planetCache.get(cacheKey);
116 if (entry != null) {
117 response.setContentLength(entry.getContent().length);
118 response.getOutputStream().write(entry.getContent());
119 return;
120 }
121
122
123 // looks like we need to render content
124 @SuppressWarnings("unchecked")
125 HashMap<String, Object> model = new HashMap();
126 try {
127 // populate the rendering model
128 if (request.getParameter("group") != null) {
129 Planet planetObject = planet.getPlanet("default");
130 model.put("group", planet.getGroup(planetObject, request.getParameter("group")));
131 }
132 model.put("planet", planet);
133 model.put("date", new Date());
134 model.put("utils", new UtilitiesModel());
135 model.put("siteName", PlanetRuntimeConfig.getProperty("site.name"));
136 model.put("siteDescription", PlanetRuntimeConfig.getProperty("site.description"));
137 model.put("lastModified", lastModified);
138 if (StringUtils.isNotEmpty(PlanetRuntimeConfig.getProperty("site.absoluteurl"))) {
139 model.put("absoluteSite", PlanetRuntimeConfig.getProperty("site.absoluteurl"));
140 } else {
141 model.put("absoluteSite", WebloggerRuntimeConfig.getAbsoluteContextURL());
142 }
143 model.put("feedStyle", new Boolean(WebloggerRuntimeConfig.getBooleanProperty("site.newsfeeds.styledFeeds")));
144
145 int numEntries = WebloggerRuntimeConfig.getIntProperty("site.newsfeeds.defaultEntries");
146 int entryCount = numEntries;
147 String sCount = request.getParameter("count");
148 if (sCount != null) {
149 try {
150 entryCount = Integer.parseInt(sCount);
151 } catch (NumberFormatException e) {
152 log.warn("Improperly formatted count parameter");
153 }
154 if (entryCount > numEntries) {
155 entryCount = numEntries;
156 }
157 if (entryCount < 0) {
158 entryCount = 0;
159 }
160 }
161 model.put("entryCount", new Integer(entryCount));
162 } catch (Exception ex) {
163 log.error("Error loading model objects for page", ex);
164
165 if (!response.isCommitted()) {
166 response.reset();
167 }
168 response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
169 return;
170 }
171
172
173 // lookup Renderer we are going to use
174 Renderer renderer = null;
175 try {
176 log.debug("Looking up renderer");
177 Template template = new StaticTemplate("templates/planet/planetrss.vm", "velocity");
178 renderer = RendererManager.getRenderer(template);
179 } catch (Exception e) {
180 // nobody wants to render my content :(
181 log.error("Couldn't find renderer for planet rss", e);
182
183 if (!response.isCommitted()) {
184 response.reset();
185 }
186 response.sendError(HttpServletResponse.SC_NOT_FOUND);
187 return;
188 }
189
190 // render content. use default size of about 24K for a standard page
191 CachedContent rendererOutput = new CachedContent(24567);
192 try {
193 log.debug("Doing rendering");
194 renderer.render(model, rendererOutput.getCachedWriter());
195
196 // flush rendered output and close
197 rendererOutput.flush();
198 rendererOutput.close();
199 } catch (Exception e) {
200 // bummer, error during rendering
201 log.error("Error during rendering for planet rss", e);
202
203 if (!response.isCommitted()) {
204 response.reset();
205 }
206 response.sendError(HttpServletResponse.SC_NOT_FOUND);
207 return;
208 }
209
210
211 // post rendering process
212 // flush rendered content to response
213 log.debug("Flushing response output");
214 response.setContentLength(rendererOutput.getContent().length);
215 response.getOutputStream().write(rendererOutput.getContent());
216
217 // cache rendered content.
218 this.planetCache.put(cacheKey, rendererOutput);
219
220 log.debug("Exiting");
221 }
222
223 /**
224 * Generate a cache key from a parsed planet request.
225 * This generates a key of the form ...
226 *
227 * <context>/<type>/<language>[/user]
228 * or
229 * <context>/<type>[/flavor]/<language>[/excerpts]
230 *
231 *
232 * examples ...
233 *
234 * planet/page/en
235 * planet/feed/rss/en/excerpts
236 *
237 */
238 private String generateKey(PlanetRequest planetRequest) {
239
/*
P/P * Method: String generateKey(PlanetRequest)
*
* Preconditions:
* planetRequest != null
* init'ed(planetRequest.context)
* init'ed(planetRequest.flavor)
* init'ed(planetRequest.group)
* init'ed(planetRequest.language)
* init'ed(planetRequest.type)
* (soft) init'ed(planetRequest.excerpts)
*
* Postconditions:
* init'ed(java.lang.StringBuffer:toString(...)._tainted)
* return_value == &java.lang.StringBuffer:toString(...)
*
* Test Vectors:
* planetRequest.excerpts: {0}, {1}
* planetRequest.flavor: Addr_Set{null}, Inverse{null}
* planetRequest.group: Addr_Set{null}, Inverse{null}
* org.apache.roller.weblogger.ui.rendering.util.PlanetRequest:getAuthenticUser(...)@259: Addr_Set{null}, Inverse{null}
*/
240 StringBuffer key = new StringBuffer();
241 key.append(planetRequest.getContext());
242 key.append("/");
243 key.append(planetRequest.getType());
244
245 if (planetRequest.getFlavor() != null) {
246 key.append("/").append(planetRequest.getFlavor());
247 }
248
249 // add language
250 key.append("/").append(planetRequest.getLanguage());
251
252 if (planetRequest.getFlavor() != null) {
253 // add excerpts
254 if (planetRequest.isExcerpts()) {
255 key.append("/excerpts");
256 }
257 } else {
258 // add login state
259 if (planetRequest.getAuthenticUser() != null) {
260 key.append("/user=").append(planetRequest.getAuthenticUser());
261 }
262 }
263
264 // add group
265 if (planetRequest.getGroup() != null) {
266 key.append("/group=").append(planetRequest.getGroup());
267 }
268
269 return key.toString();
270 }
271 }
SofCheck Inspector Build Version : 2.18479
| PlanetFeedServlet.java |
2009-Jan-02 14:25:24 |
| PlanetFeedServlet.class |
2009-Sep-04 03:12:45 |