Package org.jamwiki.servlets

Source Code of org.jamwiki.servlets.EditServlet

/**
* Licensed under the GNU LESSER GENERAL PUBLIC LICENSE, version 2.1, dated February 1999.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the latest version of the GNU Lesser General
* Public License 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 Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program (LICENSE.txt); if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
*/
package org.jamwiki.servlets;

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

import org.apache.commons.lang.StringUtils;
import org.jamwiki.WikiBase;
import org.jamwiki.WikiException;
import org.jamwiki.WikiMessage;
import org.jamwiki.authentication.RoleImpl;
import org.jamwiki.authentication.WikiUserDetails;
import org.jamwiki.model.Topic;
import org.jamwiki.model.TopicVersion;
import org.jamwiki.model.WikiUser;
import org.jamwiki.parser.ParserInput;
import org.jamwiki.parser.ParserOutput;
import org.jamwiki.parser.ParserUtil;
import org.jamwiki.utils.LinkUtil;
import org.jamwiki.utils.NamespaceHandler;
import org.jamwiki.utils.WikiLink;
import org.jamwiki.utils.WikiLogger;
import org.jamwiki.utils.WikiUtil;
import org.springframework.web.servlet.ModelAndView;

/**
* Used to process topic edits including saving an edit, preview, resolving
* conflicts and dealing with spam.
*/
public class EditServlet extends JAMWikiServlet {

  private static final WikiLogger logger = WikiLogger
      .getLogger(EditServlet.class.getName());
  /** The name of the JSP file used to render the servlet output. */
  protected static final String JSP_EDIT = "edit.jsp";

  /**
   *
   */
  protected ModelAndView handleJAMWikiRequest(HttpServletRequest request,
      HttpServletResponse response, ModelAndView next, WikiPageInfo pageInfo)
      throws Exception {
    ModelAndView loginRequired = loginRequired(request, pageInfo);
    if (loginRequired != null) {
      return loginRequired;
    }
    if (isSave(request)) {
      save(request, next, pageInfo);
    } else {
      edit(request, next, pageInfo);
    }
    return next;
  }

  /**
   *
   */
  private void edit(HttpServletRequest request, ModelAndView next,
      WikiPageInfo pageInfo) throws Exception {
    String topicName = WikiUtil.getTopicFromRequest(request);
    String virtualWiki = pageInfo.getVirtualWikiName();
    Topic topic = loadTopic(virtualWiki, topicName);
    // topic name might be updated by loadTopic
    topicName = topic.getName();
    // Integer lastTopicVersionId = retrieveLastTopicVersionId(request, topic);
    // next.addObject("lastTopicVersionId", lastTopicVersionId);
    String contents = (String) request.getParameter("contents");
    if (isPreview(request)) {
      preview(request, next, pageInfo);
    } else if (isShowChanges(request)) {
      // showChanges(request, next, pageInfo, virtualWiki, topicName,
      // lastTopicVersionId);
      // } else if
      // (!StringUtils.isBlank(request.getParameter("topicVersionId"))) {
      // // editing an older version
      // Integer topicVersionId =
      // Integer.valueOf(request.getParameter("topicVersionId"));
      // TopicVersion topicVersion =
      // WikiBase.getDataHandler().lookupTopicVersion(topicVersionId);
      // if (topicVersion == null) {
      // throw new WikiException(new WikiMessage("common.exception.notopic"));
      // }
      // contents = topicVersion.getVersionContent();
      // if (!lastTopicVersionId.equals(topicVersionId)) {
      // next.addObject("topicVersionId", topicVersionId);
      // }
    } else if (!StringUtils.isBlank(request.getParameter("section"))) {
      // editing a section of a topic
      int section = Integer.valueOf(request.getParameter("section"));
      String[] sliceResults = ParserUtil.parseSlice(request.getContextPath(),
          request.getLocale(), virtualWiki, topicName, section);
      contents = sliceResults[1];
      String sectionName = sliceResults[0];
      String editComment = "/* " + sectionName + " */ ";
      next.addObject("editComment", editComment);
    } else {
      // editing a full new or existing topic
      contents = (topic == null) ? "" : topic.getTopicContent();
    }
    this.loadEdit(request, next, pageInfo, contents, virtualWiki, topicName,
        true);
  }

  /**
   *
   */
  private boolean isPreview(HttpServletRequest request) {
    return !StringUtils.isBlank(request.getParameter("preview"));
  }

  /**
   *
   */
  private boolean isSave(HttpServletRequest request) {
    return !StringUtils.isBlank(request.getParameter("save"));
  }

  /**
   *
   */
  private boolean isShowChanges(HttpServletRequest request) {
    return !StringUtils.isBlank(request.getParameter("showChanges"));
  }

  /**
   *
   */
  private void loadDiff(HttpServletRequest request, ModelAndView next,
      WikiPageInfo pageInfo, String contents1, String contents2)
      throws Exception {
    // List<WikiDiff> diffs = DiffUtil.diff(contents1, contents2);
    // next.addObject("diffs", diffs);
  }

  /**
   *
   */
  private void loadEdit(HttpServletRequest request, ModelAndView next,
      WikiPageInfo pageInfo, String contents, String virtualWiki,
      String topicName, boolean useSection) throws Exception {
    pageInfo.setPageTitle(new WikiMessage("edit.title", topicName));
    pageInfo.setTopicName(topicName);
    WikiLink wikiLink = LinkUtil.parseWikiLink(topicName);
    String namespace = wikiLink.getNamespace();
    if (namespace != null
        && namespace.equals(NamespaceHandler.NAMESPACE_CATEGORY)) {
      ServletUtil.loadCategoryContent(next, virtualWiki, topicName);
    }
    if (request.getParameter("editComment") != null) {
      next.addObject("editComment", request.getParameter("editComment"));
    }
    if (useSection && request.getParameter("section") != null) {
      next.addObject("section", request.getParameter("section"));
    }
    next.addObject("minorEdit", (request.getParameter("minorEdit") != null));
    // Watchlist watchlist = ServletUtil.currentWatchlist(request, virtualWiki);
    // if (request.getParameter("watchTopic") != null ||
    // (watchlist.containsTopic(topicName) && !isPreview(request))) {
    // next.addObject("watchTopic", true);
    // }
    pageInfo.setContentJsp(JSP_EDIT);
    WikiUser user = ServletUtil.currentWikiUser();
    String editor = user.getEditor();
    next.addObject("editor", editor);
    next.addObject("contents", contents);
  }

  /**
   * Initialize topic values for the topic being edited. If a topic with the
   * specified name already exists then it will be initialized, otherwise a new
   * topic is created.
   */
  private Topic loadTopic(String virtualWiki, String topicName)
      throws Exception {
    Topic topic = ServletUtil.initializeTopic(virtualWiki, topicName);
    // if (topic.getReadOnly()) {
    // throw new WikiException(new WikiMessage("error.readonly"));
    // }
    return topic;
  }

  /**
   *
   */
  private ModelAndView loginRequired(HttpServletRequest request,
      WikiPageInfo pageInfo) throws Exception {
    String topicName = WikiUtil.getTopicFromRequest(request);
    String virtualWiki = pageInfo.getVirtualWikiName();
    WikiUserDetails user = ServletUtil.currentUserDetails();
    if (ServletUtil.isEditable(virtualWiki, topicName, user)) {
      return null;
    }
    if (!user.hasRole(RoleImpl.ROLE_EDIT_EXISTING)) {
      WikiMessage messageObject = new WikiMessage("login.message.edit");
      return ServletUtil.viewLogin(request, pageInfo, WikiUtil
          .getTopicFromURI(request), messageObject);
    }
    if (!user.hasRole(RoleImpl.ROLE_EDIT_NEW)
        && WikiBase.getDataHandler().lookupTopic(virtualWiki, topicName, false,
            null) == null) {
      WikiMessage messageObject = new WikiMessage("login.message.editnew");
      return ServletUtil.viewLogin(request, pageInfo, WikiUtil
          .getTopicFromURI(request), messageObject);
    }
    Topic topic = WikiBase.getDataHandler().lookupTopic(virtualWiki, topicName,
        false, null);
    if (topic == null) {
      // this should never trigger, but better safe than sorry...
      return null;
    }
    // if (topic.getAdminOnly()) {
    // WikiMessage messageObject = new WikiMessage("login.message.editadmin",
    // topicName);
    // return ServletUtil.viewLogin(request, pageInfo,
    // WikiUtil.getTopicFromURI(request), messageObject);
    // }
    // if (topic.getReadOnly()) {
    // throw new WikiException(new WikiMessage("error.readonly"));
    // }
    // it should be impossible to get here...
    throw new WikiException(new WikiMessage("error.unknown",
        "Unable to determine topic editing permissions"));
  }

  /**
   * Functionality to handle the "Preview" button being clicked.
   */
  private void preview(HttpServletRequest request, ModelAndView next,
      WikiPageInfo pageInfo) throws Exception {
    String topicName = WikiUtil.getTopicFromRequest(request);
    String virtualWiki = pageInfo.getVirtualWikiName();
    String contents = (String) request.getParameter("contents");
    Topic previewTopic = new Topic();
    previewTopic.setName(topicName);
    previewTopic.setTopicContent(contents);
    previewTopic.setVirtualWiki(virtualWiki);
    next.addObject("editPreview", "true");
    ServletUtil.viewTopic(request, next, pageInfo, null, previewTopic, false,
        false);
  }

  /**
   *
   */
  private void resolve(HttpServletRequest request, ModelAndView next,
      WikiPageInfo pageInfo) throws Exception {
    String topicName = WikiUtil.getTopicFromRequest(request);
    String virtualWiki = pageInfo.getVirtualWikiName();
    Topic lastTopic = WikiBase.getDataHandler().lookupTopic(virtualWiki,
        topicName, false, null);
    String contents1 = lastTopic.getTopicContent();
    String contents2 = request.getParameter("contents");
    // next.addObject("lastTopicVersionId", lastTopic.getCurrentVersionId());
    next.addObject("contentsResolve", contents2);
    this.loadDiff(request, next, pageInfo, contents1, contents2);
    this.loadEdit(request, next, pageInfo, contents1, virtualWiki, topicName,
        false);
    next.addObject("editResolve", "true");
  }

  /**
   *
   */
  private Long retrieveLastTopicVersionId(HttpServletRequest request,
      Topic topic) throws Exception {
    return (!StringUtils.isBlank(request.getParameter("lastTopicVersionId"))) ? Long
        .valueOf(request.getParameter("lastTopicVersionId"))
        : topic.getCurrentVersionId();
  }

  /**
   * Functionality to handle the "Save" button being clicked.
   */
  private void save(HttpServletRequest request, ModelAndView next,
      WikiPageInfo pageInfo) throws Exception {
    String topicName = WikiUtil.getTopicFromRequest(request);
    String virtualWiki = pageInfo.getVirtualWikiName();
    Topic topic = loadTopic(virtualWiki, topicName);
    Topic lastTopic = WikiBase.getDataHandler().lookupTopic(virtualWiki,
        topicName, false, null);
    if (lastTopic != null
        && !lastTopic.getCurrentVersionId().equals(
            retrieveLastTopicVersionId(request, topic))) {
      // someone else has edited the topic more recently
      resolve(request, next, pageInfo);
      return;
    }
    String contents = request.getParameter("contents");
    String sectionName = "";
    if (!StringUtils.isBlank(request.getParameter("section"))) {
      // load section of topic
      int section = Integer.valueOf(request.getParameter("section"));
      ParserOutput parserOutput = new ParserOutput();
      String[] spliceResult = ParserUtil.parseSplice(parserOutput, request
          .getContextPath(), request.getLocale(), virtualWiki, topicName,
          section, contents);
      contents = spliceResult[1];
      sectionName = parserOutput.getSectionName();
    }
    if (contents == null) {
      logger.warning("The topic " + topicName + " has no content");
      throw new WikiException(new WikiMessage("edit.exception.nocontent",
          topicName));
    }
    // strip line feeds
    contents = StringUtils.remove(contents, '\r');
    String lastTopicContent = (lastTopic != null) ? StringUtils.remove(
        lastTopic.getTopicContent(), '\r') : "";
    if (lastTopic != null && StringUtils.equals(lastTopicContent, contents)) {
      // topic hasn't changed. redirect to prevent user from refreshing and
      // re-submitting
      ServletUtil.redirect(next, virtualWiki, topic.getName());
      return;
    }
    if (handleSpam(request, next, topicName, contents)) {
      this.loadEdit(request, next, pageInfo, contents, virtualWiki, topicName,
          false);
      return;
    }
    // parse for signatures and other syntax that should not be saved in raw
    // form
    WikiUser user = ServletUtil.currentWikiUser();
    ParserInput parserInput = new ParserInput();
    parserInput.setContext(request.getContextPath());
    parserInput.setLocale(request.getLocale());
    parserInput.setWikiUser(user);
    parserInput.setTopicName(topicName);
    parserInput.setUserDisplay(ServletUtil.getIpAddress(request));
    parserInput.setVirtualWiki(virtualWiki);
    ParserOutput parserOutput = ParserUtil.parseMetadata(parserInput, contents);
    // parse signatures and other values that need to be updated prior to saving
    contents = ParserUtil.parseMinimal(parserInput, contents);
    topic.setTopicContent(contents);
    // if (!StringUtils.isBlank(parserOutput.getRedirect())) {
    // // set up a redirect
    // topic.setRedirectTo(parserOutput.getRedirect());
    // topic.setTopicType(Topic.TYPE_REDIRECT);
    // } else if (topic.getTopicType() == Topic.TYPE_REDIRECT) {
    // // no longer a redirect
    // topic.setRedirectTo(null);
    // topic.setTopicType(Topic.TYPE_ARTICLE);
    // }
    int charactersChanged = StringUtils.length(contents)
        - StringUtils.length(lastTopicContent);
    TopicVersion topicVersion = new TopicVersion(user, ServletUtil
        .getIpAddress(request), request.getParameter("editComment"), contents,
        charactersChanged);
    if (request.getParameter("minorEdit") != null) {
      topicVersion.setEditType(TopicVersion.EDIT_MINOR);
    }
    WikiBase.getDataHandler().writeTopic(topic, topicVersion,
        parserOutput.getCategories(), parserOutput.getLinks());
    // // update watchlist
    WikiUserDetails userDetails = ServletUtil.currentUserDetails();
    if (!userDetails.hasRole(RoleImpl.ROLE_ANONYMOUS)) {
      // Watchlist watchlist = ServletUtil.currentWatchlist(request,
      // virtualWiki);
      // boolean watchTopic = (request.getParameter("watchTopic") != null);
      // if (watchlist.containsTopic(topicName) != watchTopic) {
      // WikiBase.getDataHandler().writeWatchlistEntry(watchlist, virtualWiki,
      // topicName, user.getUserId());
      // }
    }
    // redirect to prevent user from refreshing and re-submitting
    String target = topic.getName();
    if (!StringUtils.isBlank(sectionName)) {
      target += "#" + sectionName;
    }
    ServletUtil.redirect(next, virtualWiki, target);
  }

  /**
   * Functionality to handle the "Show Changes" button being clicked.
   */
  private void showChanges(HttpServletRequest request, ModelAndView next,
      WikiPageInfo pageInfo, String virtualWiki, String topicName,
      Long lastTopicVersionId) throws Exception {
    String contents1 = request.getParameter("contents");
    String contents2 = "";
    if (!StringUtils.isBlank(request.getParameter("section"))) {
      // editing a section of a topic
      int section = Integer.valueOf(request.getParameter("section"));
      String[] sliceResults = ParserUtil.parseSlice(request.getContextPath(),
          request.getLocale(), virtualWiki, topicName, section);
      contents2 = sliceResults[1];
    } else if (lastTopicVersionId != null) {
      // get the full topic version
      TopicVersion lastTopicVersion = WikiBase.getDataHandler()
          .lookupTopicVersion(lastTopicVersionId);
      contents2 = lastTopicVersion.getVersionContent();
    }
    this.loadDiff(request, next, pageInfo, contents1, contents2);
    next.addObject("editShowChanges", "true");
  }
}
TOP

Related Classes of org.jamwiki.servlets.EditServlet

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.