Package org.jamwiki.servlets

Source Code of org.jamwiki.servlets.BlikiServlet

package org.jamwiki.servlets;

import java.util.LinkedHashMap;

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

import org.apache.commons.lang.StringUtils;
import org.jamwiki.Environment;
import org.jamwiki.WikiBase;
import org.jamwiki.WikiException;
import org.jamwiki.WikiMessage;
import org.jamwiki.model.VirtualWiki;
import org.jamwiki.utils.WikiLogger;
import org.jamwiki.utils.WikiUtil;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.mvc.AbstractController;

public abstract class BlikiServlet extends AbstractController {
  private static final WikiLogger logger = WikiLogger
      .getLogger(BlikiServlet.class.getName());

  /**
   * Flag to indicate whether or not the servlet should load the nav bar and
   * other layout elements.
   */
  protected boolean layout = true;
  /** The prefix of the JSP file used to display the servlet output. */
  protected String displayJSP = "wiki";
  /**
   * The name of the JSP file used to render the servlet output in case of
   * errors.
   */
  private static final String JSP_ERROR = "error-display.jsp";
  /**
   * Any page that take longer than this value (specified in milliseconds) will
   * print a warning to the log.
   */
  protected static final int SLOW_PAGE_LIMIT = 1000;
  /**
   * Parameter used to indicate that a topic should be the target of a
   * successful login.
   */
  protected static final String PARAM_LOGIN_SUCCESS_TARGET = "returnto";

  /**
   * This method ensures that the left menu, logo, and other required values
   * have been loaded into the session object.
   *
   * @param request
   *          The servlet request object.
   * @param next
   *          A ModelAndView object corresponding to the page being constructed.
   */
  private void buildLayout(HttpServletRequest request, ModelAndView next,
      WikiPageInfo pageInfo) {
    String virtualWikiName = pageInfo.getVirtualWikiName();
    if (virtualWikiName == null) {
      logger.severe("No virtual wiki available for page request "
          + request.getRequestURI());
      virtualWikiName = WikiBase.DEFAULT_VWIKI;
    }
    VirtualWiki virtualWiki = ServletUtil.retrieveVirtualWiki(virtualWikiName);
    // build the layout contents
    String leftMenu = ServletUtil.cachedContent(request.getContextPath(),
        request.getLocale(), virtualWikiName, WikiBase.SPECIAL_PAGE_LEFT_MENU,
        true);
    next.addObject("leftMenu", leftMenu);
    next.addObject("defaultTopic", virtualWiki.getDefaultTopicName());
    next.addObject("virtualWiki", virtualWiki.getName());
    next.addObject("logo", Environment
        .getValue(Environment.PROP_BASE_LOGO_IMAGE));
    String bottomArea = ServletUtil.cachedContent(request.getContextPath(),
        request.getLocale(), virtualWiki.getName(),
        WikiBase.SPECIAL_PAGE_BOTTOM_AREA, true);
    next.addObject("bottomArea", bottomArea);
    next.addObject(WikiUtil.PARAMETER_VIRTUAL_WIKI, virtualWiki.getName());
    // int cssRevision = 0;
    // try {
    // cssRevision =
    // WikiBase.getDataHandler().lookupTopic(virtualWiki.getName(),
    // WikiBase.SPECIAL_PAGE_STYLESHEET, false, null).getCurrentVersionId();
    // } catch (DataAccessException e) {}
    // next.addObject("cssRevision", cssRevision);
  }

  /**
   * Implement the handleRequestInternal method specified by the Spring
   * AbstractController class.
   *
   * @param request
   *          The servlet request object.
   * @param response
   *          The servlet response object.
   * @return A ModelAndView object corresponding to the information to be
   *         rendered, or <code>null</code> if the method directly handles its
   *         own output, for example by writing directly to the output response.
   * @throws Exception
   *           Thrown if any error occurs during method execution.
   */
  public ModelAndView handleRequestInternal(HttpServletRequest request,
      HttpServletResponse response) {
    long start = System.currentTimeMillis();
    initParams();
    ModelAndView next = new ModelAndView(this.displayJSP);
    WikiPageInfo pageInfo = new WikiPageInfo(request);
    try {
      next = this.handleBlikiRequest(request, response, next, pageInfo);
      if (next != null && this.layout) {
        this.loadLayout(request, next, pageInfo);
      }
      if (next != null) {
        next.addObject(ServletUtil.PARAMETER_PAGE_INFO, pageInfo);
      }
    } catch (Throwable t) {
      return this.viewError(request, t);
    }
    long execution = System.currentTimeMillis() - start;
    if (execution > SLOW_PAGE_LIMIT) {
      logger.warning("Slow page loading time: " + request.getRequestURI()
          + " (" + (execution / 1000.000) + " s.)");
    }
    if (logger.isInfoEnabled()) {
      String url = request.getRequestURI()
          + (!StringUtils.isEmpty(request.getQueryString()) ? "?"
              + request.getQueryString() : "");
      logger
          .info("Loaded page " + url + " (" + (execution / 1000.000) + " s.)");
    }
    return next;
  }

  /**
   * Build a map of links and the corresponding link text to be used as the tab
   * menu links for the WikiPageInfo object.
   */
  private LinkedHashMap buildTabMenu(HttpServletRequest request,
      WikiPageInfo pageInfo) {
    LinkedHashMap<String, WikiMessage> links = new LinkedHashMap<String, WikiMessage>();
    // WikiUserDetails userDetails = ServletUtil.currentUserDetails();
    // String pageName = pageInfo.getTopicName();
    // String virtualWiki = pageInfo.getVirtualWikiName();
    // if (pageInfo.getAdmin()) {
    // if (userDetails.hasRole(RoleImpl.ROLE_SYSADMIN)) {
    // links.put("Special:Admin", new WikiMessage("tab.admin.configuration"));
    // links.put("Special:Maintenance", new
    // WikiMessage("tab.admin.maintenance"));
    // links.put("Special:Roles", new WikiMessage("tab.admin.roles"));
    // }
    // if (userDetails.hasRole(RoleImpl.ROLE_TRANSLATE)) {
    // links.put("Special:Translation", new
    // WikiMessage("tab.admin.translations"));
    // }
    // } else if (pageInfo.getSpecial()) {
    // // append query params for pages such as Special:Contributions that need
    // it
    // String specialUrl = pageName;
    // if (!StringUtils.isBlank(request.getQueryString())) {
    // specialUrl = pageName + "?" + request.getQueryString();
    // }
    // links.put(specialUrl, new WikiMessage("tab.common.special"));
    // } else {
    // try {
    // String article = WikiUtil.extractTopicLink(pageName);
    // String comments = WikiUtil.extractCommentsLink(pageName);
    // links.put(article, new WikiMessage("tab.common.article"));
    // links.put(comments, new WikiMessage("tab.common.comments"));
    // if (ServletUtil.isEditable(virtualWiki, pageName, userDetails)) {
    // String editLink = "Special:Edit?topic=" +
    // Utilities.encodeAndEscapeTopicName(pageName);
    // if (!StringUtils.isBlank(request.getParameter("topicVersionId"))) {
    // editLink += "&topicVersionId=" + request.getParameter("topicVersionId");
    // }
    // links.put(editLink, new WikiMessage("tab.common.edit"));
    // }
    // String historyLink = "Special:History?topic=" +
    // Utilities.encodeAndEscapeTopicName(pageName);
    // links.put(historyLink, new WikiMessage("tab.common.history"));
    // if (ServletUtil.isMoveable(virtualWiki, pageName, userDetails)) {
    // String moveLink = "Special:Move?topic=" +
    // Utilities.encodeAndEscapeTopicName(pageName);
    // links.put(moveLink, new WikiMessage("tab.common.move"));
    // }
    // if (!userDetails.hasRole(RoleImpl.ROLE_ANONYMOUS)) {
    // Watchlist watchlist = ServletUtil.currentWatchlist(request, virtualWiki);
    // boolean watched = watchlist.containsTopic(pageName);
    // String watchlistLabel = (watched) ? "tab.common.unwatch" :
    // "tab.common.watch";
    // String watchlistLink = "Special:Watchlist?topic=" +
    // Utilities.encodeAndEscapeTopicName(pageName);
    // links.put(watchlistLink, new WikiMessage(watchlistLabel));
    // }
    // if (pageInfo.isUserPage()) {
    // WikiLink wikiLink = LinkUtil.parseWikiLink(pageName);
    // String contributionsLink = "Special:Contributions?contributor=" +
    // Utilities.encodeAndEscapeTopicName(wikiLink.getArticle());
    // links.put(contributionsLink, new
    // WikiMessage("tab.common.contributions"));
    // }
    // String linkToLink = "Special:LinkTo?topic=" +
    // Utilities.encodeAndEscapeTopicName(pageName);
    // links.put(linkToLink, new WikiMessage("tab.common.links"));
    // if (userDetails.hasRole(RoleImpl.ROLE_ADMIN)) {
    // String manageLink = "Special:Manage?topic=" +
    // Utilities.encodeAndEscapeTopicName(pageName);
    // links.put(manageLink, new WikiMessage("tab.common.manage"));
    // }
    // String printLink = "Special:Print?topic=" +
    // Utilities.encodeAndEscapeTopicName(pageName);
    // links.put(printLink, new WikiMessage("tab.common.print"));
    // } catch (WikiException e) {
    // logger.severe("Unable to build tabbed menu links", e);
    // }
    // }
    return links;
  }

  /**
   * Build a map of links and the corresponding link text to be used as the user
   * menu links for the WikiPageInfo object.
   */
  private LinkedHashMap buildUserMenu(WikiPageInfo pageInfo) {
    LinkedHashMap<String, WikiMessage> links = new LinkedHashMap<String, WikiMessage>();
    // WikiUserDetails userDetails = ServletUtil.currentUserDetails();
    // if (userDetails.hasRole(RoleImpl.ROLE_ANONYMOUS) &&
    // !userDetails.hasRole(RoleImpl.ROLE_EMBEDDED)) {
    // // include the current page in the login link
    // String loginLink = "Special:Login";
    // if (!StringUtils.startsWith(pageInfo.getTopicName(), "Special:Login")) {
    // loginLink += LinkUtil.appendQueryParam("", PARAM_LOGIN_SUCCESS_TARGET,
    // pageInfo.getTopicName());
    // }
    // links.put(loginLink, new WikiMessage("common.login"));
    // links.put("Special:Account", new WikiMessage("usermenu.register"));
    // }
    // if (!userDetails.hasRole(RoleImpl.ROLE_ANONYMOUS)) {
    // WikiUser user = ServletUtil.currentWikiUser();
    // String userPage = NamespaceHandler.NAMESPACE_USER +
    // NamespaceHandler.NAMESPACE_SEPARATOR + user.getUsername();
    // String userCommentsPage = NamespaceHandler.NAMESPACE_USER_COMMENTS +
    // NamespaceHandler.NAMESPACE_SEPARATOR + user.getUsername();
    // String username = user.getUsername();
    // if (!StringUtils.isBlank(user.getDisplayName())) {
    // username = user.getDisplayName();
    // }
    // // user name will be escaped by the jamwiki:link tag
    // WikiMessage userMenuMessage = new WikiMessage("usermenu.user");
    // userMenuMessage.setParamsWithoutEscaping(new String[]{username});
    // links.put(userPage, userMenuMessage);
    // links.put(userCommentsPage, new WikiMessage("usermenu.usercomments"));
    // links.put("Special:Watchlist", new WikiMessage("usermenu.watchlist"));
    // }
    // if (!userDetails.hasRole(RoleImpl.ROLE_ANONYMOUS) &&
    // !userDetails.hasRole(RoleImpl.ROLE_NO_ACCOUNT)) {
    // links.put("Special:Account", new WikiMessage("usermenu.account"));
    // }
    // if (!userDetails.hasRole(RoleImpl.ROLE_ANONYMOUS) &&
    // !userDetails.hasRole(RoleImpl.ROLE_EMBEDDED)) {
    // links.put("Special:Logout", new WikiMessage("common.logout"));
    // }
    // if (userDetails.hasRole(RoleImpl.ROLE_SYSADMIN)) {
    // links.put("Special:Admin", new WikiMessage("usermenu.admin"));
    // } else if (userDetails.hasRole(RoleImpl.ROLE_TRANSLATE)) {
    // links.put("Special:Translation", new
    // WikiMessage("tab.admin.translations"));
    // }
    return links;
  }

  /**
   * Abstract method that must be implemented by all sub-classes to handle
   * servlet requests.
   *
   * @param request
   *          The servlet request object.
   * @param response
   *          The servlet response object.
   * @param next
   *          A ModelAndView object that has been initialized to the view
   *          specified by the <code>displayJSP</code> member variable.
   * @param pageInfo
   *          A WikiPageInfo object that will hold output parameters to be
   *          passed to the output JSP.
   * @return A ModelAndView object corresponding to the information to be
   *         rendered, or <code>null</code> if the method directly handles its
   *         own output, for example by writing directly to the output response.
   */
  protected abstract ModelAndView handleBlikiRequest(
      HttpServletRequest request, HttpServletResponse response,
      ModelAndView next, WikiPageInfo pageInfo) throws Exception;

  /**
   * If any special servlet initialization needs to be performed it can be done
   * by overriding this method. In particular, this method can be used to
   * override the defaults for the <code>layout</code> member variable, which
   * determines whether or not the output JSP should include the left navigation
   * and other layout values, and the <code>displayJSP</code> member variable,
   * which determine the JSP file used to render output.
   */
  protected void initParams() {
  }

  /**
   * This method ensures that values required for rendering a JSP page have been
   * loaded into the ModelAndView object. Examples of values that may be handled
   * by this method include topic name, username, etc.
   *
   * @param request
   *          The current servlet request object.
   * @param next
   *          The current ModelAndView object.
   * @param pageInfo
   *          The current WikiPageInfo object, containing basic page rendering
   *          information.
   */
  private void loadLayout(HttpServletRequest request, ModelAndView next,
      WikiPageInfo pageInfo) throws Exception {
    if (next.getViewName() != null
        && next.getViewName().startsWith(ServletUtil.SPRING_REDIRECT_PREFIX)) {
      // if this is a redirect, no need to load anything
      return;
    }
    // load cached top area, nav bar, etc.
    this.buildLayout(request, next, pageInfo);
    if (StringUtils.isBlank(pageInfo.getTopicName())) {
      pageInfo.setTopicName(WikiUtil.getTopicFromURI(request));
    }
    pageInfo.setUserMenu(this.buildUserMenu(pageInfo));
    pageInfo.setTabMenu(this.buildTabMenu(request, pageInfo));
  }

  /**
   * Method used when redirecting to an error page.
   *
   * @param request
   *          The servlet request object.
   * @param t
   *          The exception that is the source of the error.
   * @return Returns a ModelAndView object corresponding to the error page
   *         display.
   */
  private ModelAndView viewError(HttpServletRequest request, Throwable t) {
    if (!(t instanceof WikiException)) {
      logger.severe("Servlet error", t);
    }
    ModelAndView next = new ModelAndView("wiki");
    WikiPageInfo pageInfo = new WikiPageInfo(request);
    pageInfo.setPageTitle(new WikiMessage("error.title"));
    pageInfo.setContentJsp(JSP_ERROR);
    pageInfo.setSpecial(true);
    if (t instanceof WikiException) {
      WikiException we = (WikiException) t;
      next.addObject("messageObject", we.getWikiMessage());
    } else {
      next.addObject("messageObject", new WikiMessage("error.unknown", t
          .toString()));
    }
    try {
      this.loadLayout(request, next, pageInfo);
    } catch (Exception err) {
      logger.severe("Unable to load default layout", err);
    }
    next.addObject(ServletUtil.PARAMETER_PAGE_INFO, pageInfo);
    return next;
  }
}
TOP

Related Classes of org.jamwiki.servlets.BlikiServlet

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.