@Test public void testImportFromFileWithUnsortedHistory() throws Throwable { String virtualWiki = VIRTUAL_WIKI_EN; List<String> results = this.importTestFile(FILE_ONE_TOPIC_WITH_UNSORTED_HISTORY); Topic topic = WikiBase.getDataHandler().lookupTopic(virtualWiki, TOPIC_NAME3, false, null); // validate that the current topic content is correct assertEquals( "Incorrect topic ordering: " + topic.getTopicId() + " / " + topic.getCurrentVersionId(), "Newest Revision", topic.getTopicContent()); }
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"); }
/** 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; } String editComment = request.getParameter("editComment"); if (handleSpam(request, next, topicName, contents, editComment)) { 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(TopicType.REDIRECT); } else if (topic.getTopicType() == TopicType.REDIRECT) { // no longer a redirect topic.setRedirectTo(null); topic.setTopicType(TopicType.ARTICLE); } int charactersChanged = StringUtils.length(contents) - StringUtils.length(lastTopicContent); TopicVersion topicVersion = new TopicVersion( user, ServletUtil.getIpAddress(request), editComment, contents, charactersChanged); if (request.getParameter("minorEdit") != null) { topicVersion.setEditType(TopicVersion.EDIT_MINOR); } WikiBase.getDataHandler() .writeTopic(topic, topicVersion, parserOutput.getCategories(), parserOutput.getLinks()); // update watchlist WikiUserDetailsImpl userDetails = ServletUtil.currentUserDetails(); if (!userDetails.hasRole(Role.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); }
private Integer retrieveLastTopicVersionId(HttpServletRequest request, Topic topic) throws Exception { return (!StringUtils.isBlank(request.getParameter("lastTopicVersionId"))) ? Integer.valueOf(request.getParameter("lastTopicVersionId")) : topic.getCurrentVersionId(); }
private void writePages( Writer writer, String virtualWiki, List<String> topicNames, boolean excludeHistory) throws DataAccessException, IOException, MigrationException { // note that effort is being made to re-use temporary objects as this // code can generate an OOM "GC overhead limit exceeded" with HUGE (500MB) topics // since the garbage collector ends up being invoked excessively. TopicVersion topicVersion; Topic topic; WikiUser user; // choose 100,000 as an arbitrary max Pagination pagination = new Pagination(100000, 0); List<Integer> topicVersionIds; Map<String, String> textAttributes = new HashMap<String, String>(); textAttributes.put("xml:space", "preserve"); for (String topicName : topicNames) { topicVersionIds = new ArrayList<Integer>(); topic = WikiBase.getDataHandler().lookupTopic(virtualWiki, topicName, false); if (topic == null) { throw new MigrationException( "Failure while exporting: topic " + topicName + " does not exist"); } writer.append("\n<page>"); writer.append('\n'); XMLUtil.buildTag(writer, "title", topic.getName(), true); writer.append('\n'); XMLUtil.buildTag(writer, "id", topic.getTopicId()); if (excludeHistory) { // only include the most recent version topicVersionIds.add(topic.getCurrentVersionId()); } else { // FIXME - changes sorted newest-to-oldest, should be reverse List<RecentChange> changes = WikiBase.getDataHandler().getTopicHistory(topic, pagination, true); for (int i = (changes.size() - 1); i >= 0; i--) { topicVersionIds.add(changes.get(i).getTopicVersionId()); } } for (int topicVersionId : topicVersionIds) { topicVersion = WikiBase.getDataHandler().lookupTopicVersion(topicVersionId); writer.append("\n<revision>"); writer.append('\n'); XMLUtil.buildTag(writer, "id", topicVersion.getTopicVersionId()); writer.append('\n'); XMLUtil.buildTag( writer, "timestamp", this.parseJAMWikiTimestamp(topicVersion.getEditDate()), true); writer.append("\n<contributor>"); user = (topicVersion.getAuthorId() != null) ? WikiBase.getDataHandler().lookupWikiUser(topicVersion.getAuthorId()) : null; if (user != null) { writer.append('\n'); XMLUtil.buildTag(writer, "username", user.getUsername(), true); writer.append('\n'); XMLUtil.buildTag(writer, "id", user.getUserId()); } else if (Utilities.isIpAddress(topicVersion.getAuthorDisplay())) { writer.append('\n'); XMLUtil.buildTag(writer, "ip", topicVersion.getAuthorDisplay(), true); } else { writer.append('\n'); XMLUtil.buildTag(writer, "username", topicVersion.getAuthorDisplay(), true); } writer.append("\n</contributor>"); writer.append('\n'); XMLUtil.buildTag(writer, "comment", topicVersion.getEditComment(), true); writer.append('\n'); XMLUtil.buildTag(writer, "text", topicVersion.getVersionContent(), textAttributes, true); writer.append("\n</revision>"); // explicitly null out temp variables to improve garbage collection and // avoid OOM "GC overhead limit exceeded" errors on HUGE (500MB) topics topicVersion = null; user = null; } writer.append("\n</page>"); } }