Java tutorial
/** * 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"); } }