@RequestMapping("EDIT")
  public String editPreferences(Model model, RenderRequest request) throws PortletException {

    List<TopicSubscription> myTopics = tss.getTopicSubscriptionEdit(request);

    if (request.getRemoteUser() == null
        || request.getRemoteUser().equalsIgnoreCase(GUEST_USERNAME)) {
      model.addAttribute("isGuest", Boolean.TRUE);
    } else {
      model.addAttribute("isGuest", Boolean.FALSE);
    }
    model.addAttribute("topicSubscriptions", myTopics);
    model.addAttribute("topicsToUpdate", myTopics.size());

    return viewNameSelector.select(request, "editDisplayPreferences");
  }
  /**
   * Default rendering of this portlet.
   *
   * @param request Request for getting logged user.
   * @param model Model for jsp view.
   * @return Path of jsp which will be showed.
   */
  @RenderMapping
  public final String renderDefault(final RenderRequest request, final Model model) {
    LOG.debug("Rendering default view.");

    final Quote quote = new Quote();
    final String userId = request.getRemoteUser();
    quote.setAuthorOfEntity(userId);

    final List<Quote> quotes = getQuoteService().readAll();

    model.addAttribute(FORM_MODEL, quote);
    model.addAttribute(QUOTES_LIST, quotes);
    model.addAttribute(QUOTES_LIST_SIZE, quotes.size());

    return MAIN_VIEW;
  }
  @Override
  public void doFilter(RenderRequest request, RenderResponse response, FilterChain chain)
      throws IOException, PortletException {
    String username = request.getRemoteUser();

    if (username == null) {
      request.setAttribute(
          ATTRIBUTE_ERROR_MESSAGE,
          "No content available for anonymous user. You need to login first.");
      PortletRequestDispatcher prd =
          filterConfig.getPortletContext().getRequestDispatcher("/jsp/error/error.jsp");
      prd.include(request, response);
      return;
    }

    OAuthProvider oauthProvider = getOAuthProvider();

    if (oauthProvider == null) {
      String errorMessage = "OAuth provider '" + oauthProviderKey + "' not available";
      request.setAttribute(ATTRIBUTE_ERROR_MESSAGE, errorMessage);
      PortletRequestDispatcher prd =
          filterConfig.getPortletContext().getRequestDispatcher("/jsp/error/error.jsp");
      prd.include(request, response);
      return;
    }

    AccessToken accessToken =
        loadAccessTokenOrRedirectToObtainIt(username, oauthProvider, request, response);
    if (accessToken != null) {
      accessToken = validateAccessToken(request, response, oauthProvider, accessToken);
      if (accessToken != null) {
        requestContext.saveOAuthInfo(oauthProvider, accessToken);
        chain.doFilter(request, response);
      }
    }
  }
  /**
   * Main method of this display controller. Calculates which topics should be shown to this user
   * and which announcements to show from those topics.
   *
   * @param model
   * @param request
   * @param from
   * @param to
   * @return
   * @throws PortletException
   */
  @SuppressWarnings("unchecked")
  @RequestMapping("VIEW")
  public String mainView(
      Model model,
      RenderRequest request,
      @RequestParam(value = "from", required = false) Integer from,
      @RequestParam(value = "to", required = false) Integer to)
      throws PortletException {

    PortletPreferences prefs = request.getPreferences();
    int pageSize = Integer.valueOf(prefs.getValue(PREFERENCE_PAGE_SIZE, "5"));
    ;

    if (from == null || to == null) {
      from = 0;
      to = pageSize;
    }

    boolean isGuest =
        (request.getRemoteUser() == null
            || request.getRemoteUser().equalsIgnoreCase(GUEST_USERNAME));
    logger.debug("isGuest is: " + Boolean.toString(isGuest));
    logger.debug("remoteUser is: " + request.getRemoteUser());

    List<Announcement> announcements;
    List<Announcement> emergencyAnnouncements;

    Element guestCacheElement = null;
    Element emergCacheElement = null;
    guestCacheElement = guestAnnouncementCache.get("guest");
    emergCacheElement = guestAnnouncementCache.get("emergency");

    if (!isGuest || (guestCacheElement == null || emergCacheElement == null)) {

      // create a new announcement list
      announcements = new ArrayList<Announcement>();
      emergencyAnnouncements = new ArrayList<Announcement>();

      // fetch the user's topic subscription from the database
      List<TopicSubscription> myTopics = tss.getTopicSubscription(request);

      // add all the published announcements of each subscribed topic to the announcement list
      // to emergency announcements into their own list
      for (TopicSubscription ts : myTopics) {
        if (ts.getSubscribed() && ts.getTopic().getSubscriptionMethod() != Topic.EMERGENCY) {
          announcements.addAll(ts.getTopic().getPublishedAnnouncements());
        } else if (ts.getSubscribed() && ts.getTopic().getSubscriptionMethod() == Topic.EMERGENCY) {
          emergencyAnnouncements.addAll(ts.getTopic().getPublishedAnnouncements());
        }
      }

      // sort the list (since they are not sorted from the database)
      Collections.sort(announcements);
      Collections.sort(emergencyAnnouncements);

      if (isGuest) {
        if (logger.isDebugEnabled()) logger.debug("Guest cache expired. Regenerating guest cache.");

        guestAnnouncementCache.put(new Element("guest", announcements));
        guestAnnouncementCache.put(new Element("emergency", emergencyAnnouncements));
      }
    } else {
      // we're a guest and we're within the cache timeout period, so return the cached announcements
      if (logger.isDebugEnabled()) logger.debug("Guest cache valid. Using guest cache.");
      announcements = (List<Announcement>) guestCacheElement.getObjectValue();
      emergencyAnnouncements = (List<Announcement>) emergCacheElement.getObjectValue();
    }

    // create a shortened list
    List<Announcement> announcementsShort = new ArrayList<Announcement>();

    // if the announcement list is already short, then just reference it
    if (announcements.size() < to - from) {
      announcementsShort = announcements;
    }
    // otherwise, just take the range requested and pass it along to the view
    else {
      for (int i = from; i < to && announcements.size() > i; i++) {
        if (announcements.get(i) != null) {
          announcementsShort.add(announcements.get(i));
        }
      }
    }

    // add a marker to the view to render different content for guest user
    model.addAttribute("isGuest", Boolean.valueOf(isGuest));

    // Disable the edit link where appropriate
    Boolean disableEdit = Boolean.valueOf(prefs.getValue(PREFERENCE_DISABLE_EDIT, "false"));
    model.addAttribute("disableEdit", disableEdit);

    model.addAttribute("showDate", showDate);
    model.addAttribute("from", new Integer(from));
    model.addAttribute("to", new Integer(to));
    model.addAttribute("hasMore", (announcements.size() > to));
    model.addAttribute("increment", new Integer(pageSize));
    model.addAttribute("announcements", announcementsShort);
    model.addAttribute("emergency", emergencyAnnouncements);

    return viewNameSelector.select(request, "displayAnnouncements");
  }