com.seajas.search.attender.controller.FeedController.java Source code

Java tutorial

Introduction

Here is the source code for com.seajas.search.attender.controller.FeedController.java

Source

/**
 * Copyright (C) 2013 Seajas, the Netherlands.
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 3, as
 * published by the Free Software Foundation.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
package com.seajas.search.attender.controller;

import java.util.Arrays;
import java.util.List;
import java.util.Locale;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.cxf.common.util.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;

import com.seajas.search.attender.model.profile.Profile;
import com.seajas.search.attender.model.profile.ProfileSubscriber;
import com.seajas.search.attender.model.profile.ProfileSubscriber.NotificationType;
import com.seajas.search.attender.service.attender.AttenderService;
import com.seajas.search.attender.service.feed.FeedService;
import com.sun.syndication.feed.synd.SyndFeed;
import com.sun.syndication.io.SyndFeedOutput;

/**
 * Feed controller, which also writes out the result.
 * 
 * @author Jasper van Veghel <jasper@seajas.com>
 */
@RequestMapping("/feed/**")
@Controller
public class FeedController {
    /**
     * Constants.
     */
    private static final String PARAM_RESULTS = "results";
    private static final String PARAM_TYPE = "type";

    /**
     * The accepted feed types.
     */
    private static final List<String> availableFeedTypes = Arrays.asList(new String[] { "atom_0.3", "atom_1.0",
            "rss_0.90", "rss_0.91N", "rss_0.91U", "rss_0.92", "rss_0.93", "rss_0.94", "rss_1.0", "rss_2.0" });

    /**
     * Attender service.
     */
    @Autowired
    private AttenderService attenderService;

    /**
     * Feed service.
     */
    @Autowired
    private FeedService feedService;

    /**
     * Handle the request.
     * 
     * @param request
     * @param response
     * @param locale
     * @throws Exception
     */
    @RequestMapping(method = RequestMethod.GET)
    public void handleRequest(final HttpServletRequest request, final HttpServletResponse response,
            final Locale locale) throws Exception {
        String path = request.getPathInfo();

        Integer results = null;
        String feedType = null;

        // The number of results may be optionally provided

        if (!StringUtils.isEmpty(request.getParameter(PARAM_RESULTS)))
            try {
                results = Integer.valueOf(request.getParameter(PARAM_RESULTS));
            } catch (NumberFormatException e) {
                throw new Exception("Invalid result number given");
            }
        if (!StringUtils.isEmpty(request.getParameter(PARAM_TYPE)))
            feedType = request.getParameter(PARAM_TYPE);

        // Reconstruct the URL from the request

        String baseUrl = request.getRequestURL().toString();

        if (!StringUtils.isEmpty(request.getQueryString()))
            baseUrl += "?" + request.getQueryString();

        if (path != null && path.startsWith("/feed"))
            path = path.substring(5);
        if (path != null && path.startsWith("/"))
            path = path.substring(1);

        if (!StringUtils.isEmpty(path)) {
            String[] pathParts = path.split("/");

            // The first part should always indicate the UUID

            String profileUUID = pathParts[0];

            // The second part is optional and defines the notification type

            NotificationType notificationType = pathParts.length > 1
                    && pathParts[1].equalsIgnoreCase(NotificationType.Weekly.toString()) ? NotificationType.Weekly
                            : NotificationType.Daily;

            // First retrieve the profile and create the actual feed

            Profile profile = attenderService.getProfileByUUID(profileUUID);

            if (profile == null) {
                response.sendError(HttpServletResponse.SC_NOT_FOUND, "Unknown feed '" + profileUUID + "'");

                return;
            }

            // Must have at least one confirmed subscriber

            Boolean isConfirmedOnce = false;

            for (ProfileSubscriber subscriber : profile.getSubscribers())
                if (subscriber.getIsConfirmed()) {
                    isConfirmedOnce = true;

                    break;
                }

            if (!isConfirmedOnce) {
                response.sendError(HttpServletResponse.SC_FORBIDDEN, "This feed has no confirmed subscribers");

                return;
            }

            SyndFeed result = feedService.createFeed(profile, notificationType, results, baseUrl, locale);

            // Set the feed type, or revert to the default

            if (feedType != null && availableFeedTypes.contains(feedType))
                result.setFeedType(feedType);
            else
                result.setFeedType("rss_2.0");

            // Set the response type and write out the result

            response.setContentType("application/xml; charset=UTF-8");

            SyndFeedOutput output = new SyndFeedOutput();
            output.output(result, response.getWriter());
        } else
            response.sendError(HttpServletResponse.SC_NOT_FOUND, "No feed given");
    }
}