/* * Copyright 2004 Sun Microsystems, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * */ package com.rometools.fetcher; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.io.OutputStream; import java.io.OutputStreamWriter; import java.text.DateFormat; import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.List; import java.util.zip.GZIPOutputStream; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import com.rometools.rome.feed.synd.SyndContent; import com.rometools.rome.feed.synd.SyndContentImpl; import com.rometools.rome.feed.synd.SyndEntry; import com.rometools.rome.feed.synd.SyndEntryImpl; import com.rometools.rome.feed.synd.SyndFeed; import com.rometools.rome.feed.synd.SyndFeedImpl; import com.rometools.rome.io.FeedException; import com.rometools.rome.io.SyndFeedOutput; public class FetcherTestServlet extends HttpServlet { private static final long serialVersionUID = 1L; public static final String ETAG_1 = "ETAG-1"; public static final String ETAG_2 = "ETAG-2"; public static final String DELTA_FEED_TITLE = "Delta Encoded Feed"; public static final String DELTA_FEED_ENTRY_TITLE = "Delta Encoded Feed Entry"; public static final String SERVLET_MAPPING = "/FetcherTestServlet/*"; public static final String SERVLET_MAPPING2 = "/FetcherTestServlet2/*"; /** * @throws IOException * @throws * @see javax.servlet.http.HttpServlet#doGet(javax.servlet.http.HttpServletRequest, * javax.servlet.http.HttpServletResponse) */ @Override protected void doGet(final HttpServletRequest request, final HttpServletResponse response) throws ServletException, IOException { if ("TRUE".equalsIgnoreCase(request.getParameter("redirect"))) { // testing redirection support response.sendRedirect("/rome/FetcherTestServlet2/"); return; } else if (request.getParameter("error") != null) { // response.sendError(HttpServletResponse.SC_NOT_FOUND); final int errorToThrow = Integer.parseInt(request.getParameter("error")); response.sendError(errorToThrow); return; } else { // We manually set the date headers using strings // instead of the get/setDateHeader methods because // those methods return longs, which has too much // precision for the real date headers // this is just a random date String lastModifiedDate = "Thu, 08 Jan 2009 23:06:39 GMT"; String eTag = ETAG_1; if ("TRUE".equalsIgnoreCase(request.getParameter("refreshfeed"))) { lastModifiedDate = "Fri, 09 Jan 2009 12:06:39 GMT"; eTag = ETAG_2; } final boolean serveFeed = checkModified(request, lastModifiedDate, eTag) || "TRUE".equalsIgnoreCase(request.getParameter("deltaencode")); final boolean gzip = "TRUE".equalsIgnoreCase(request.getParameter("gzipfeed")); if (serveFeed) { final String aimHeader = request.getHeader("A-IM"); final boolean serveDeltaEncodedFeed = aimHeader != null && aimHeader.indexOf("feed") >= 0 && "TRUE".equalsIgnoreCase(request.getParameter("deltaencode")); if (serveDeltaEncodedFeed) { try { sendDeltaEncodedData(response, lastModifiedDate, request.getHeader("If-None-Match"), eTag, gzip); } catch (final FeedException e) { throw new ServletException(e); } } else { sendFeedData(response, lastModifiedDate, eTag, gzip); } return; } else { response.sendError(HttpServletResponse.SC_NOT_MODIFIED); return; } } } private boolean checkModified(final HttpServletRequest request, final String lastModifiedDate, final String eTag) { final String requestedETag = request.getHeader("If-None-Match"); final String requestedLastModified = request.getHeader("If-Modified-Since"); boolean modified = true; boolean mustServer = false; if (requestedETag != null) { if (eTag.equals(requestedETag)) { modified = false; } else { modified = true; mustServer = true; } } if (requestedLastModified != null) { if (lastModifiedDate.equals(requestedLastModified)) { modified = false; } else { modified = true; mustServer = true; } } final boolean serveFeed = modified || mustServer; return serveFeed; } /** * @param request * @param lastModifiedDate * @param tag * @param gzip * @throws IOException * @throws FeedException */ private void sendDeltaEncodedData(final HttpServletResponse response, final String lastModifiedDate, final String requestedETag, final String responseETag, final boolean gzip) throws IOException, FeedException { if (ETAG_1.equals(requestedETag) || ETAG_2.equals(requestedETag)) { OutputStream out = null; if (gzip) { response.setHeader("Content-Encoding", "gzip"); out = new GZIPOutputStream(response.getOutputStream()); } else { out = response.getOutputStream(); } response.setContentType("text/xml"); response.setStatus(226); if (gzip) { response.setHeader("IM", "feed, gzip"); } else { response.setHeader("IM", "feed"); } if (responseETag != null) { response.setHeader("ETag", responseETag); } if (lastModifiedDate != null) { response.setHeader("Last-Modified", lastModifiedDate); } final SyndFeed feed = new SyndFeedImpl(); feed.setFeedType("atom_1.0"); feed.setTitle(DELTA_FEED_TITLE); feed.setLink("http://rome.dev.java.net"); feed.setDescription("This tests using rfc3229 delta encoding."); final List<SyndEntry> entries = new ArrayList<SyndEntry>(); SyndEntry entry; SyndContent description; entry = new SyndEntryImpl(); entry.setTitle(DELTA_FEED_ENTRY_TITLE); entry.setLink("http://bobwyman.pubsub.com/main/2004/09/using_rfc3229_w.html"); try { final DateFormat dateParser = new SimpleDateFormat("yyyy-MM-dd"); entry.setPublishedDate(dateParser.parse("2004-11-25")); } catch (final ParseException ex) { // } description = new SyndContentImpl(); description.setType("text/plain"); description.setValue("Test for RFC3229 Delta Encoding"); entry.setDescription(description); entries.add(entry); feed.setEntries(entries); final SyndFeedOutput output = new SyndFeedOutput(); output.output(feed, new OutputStreamWriter(out)); } else { sendFeedData(response, lastModifiedDate, responseETag, gzip); } } private void sendFeedData(final HttpServletResponse response, final String lastModifiedDate, final String eTag, final boolean gzip) throws IOException { OutputStream out = null; if (gzip) { response.setHeader("Content-Encoding", "gzip"); out = new GZIPOutputStream(response.getOutputStream()); } else { out = response.getOutputStream(); } response.setContentType("text/xml"); if (eTag != null) { response.setHeader("ETag", eTag); } if (lastModifiedDate != null) { response.setHeader("Last-Modified", lastModifiedDate); } InputStream inputStream = Thread.currentThread().getContextClassLoader().getResourceAsStream("/atom_1.0.xml"); if (inputStream == null) { inputStream = this.getClass().getResourceAsStream("/atom_1.0.xml"); } final BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream)); try { String line; while ((line = reader.readLine()) != null) { out.write(line.getBytes()); line = null; } } finally { if (reader != null) { reader.close(); } } out.close(); } }