/** * @param newVersion The String that is being compared to. * @param oldVersion The String that is being compared against. */ private static List<WikiDiff> process(String newVersion, String oldVersion) { logger.finer("Diffing: " + oldVersion + " against: " + newVersion); if (newVersion.equals(oldVersion)) { return new ArrayList<WikiDiff>(); } String[] oldArray = DiffUtil.split(oldVersion); String[] newArray = DiffUtil.split(newVersion); Diff<String> diffObject = new Diff<String>(oldArray, newArray); List<Difference> diffs = diffObject.diff(); return DiffUtil.generateWikiDiffs(diffs, oldArray, newArray); }
/** * Format the list of Difference objects into a list of WikiDiff objects, which will include * information about what values are different and also include some unchanged values surrounded * the changed values, thus giving some context. */ private static List<WikiDiff> generateWikiDiffs( List<Difference> diffs, String[] oldArray, String[] newArray) { List<WikiDiff> wikiDiffs = new ArrayList<WikiDiff>(); Difference previousDiff = null; Difference nextDiff = null; List<WikiDiff> changedLineWikiDiffs = null; String[] oldLineArray = null; String[] newLineArray = null; List<Difference> changedLineDiffs = null; List<WikiDiff> wikiSubDiffs = null; Difference nextLineDiff = null; int i = 0; for (Difference currentDiff : diffs) { i++; wikiDiffs.addAll( DiffUtil.preBufferDifference( currentDiff, previousDiff, oldArray, newArray, DIFF_UNCHANGED_LINE_DISPLAY)); changedLineWikiDiffs = DiffUtil.processDifference(currentDiff, oldArray, newArray); // loop through the difference and diff the individual lines so that it is possible to // highlight the exact // text that was changed for (WikiDiff changedLineWikiDiff : changedLineWikiDiffs) { oldLineArray = DiffUtil.stringToArray(changedLineWikiDiff.getOldText()); newLineArray = DiffUtil.stringToArray(changedLineWikiDiff.getNewText()); changedLineDiffs = new Diff<String>(oldLineArray, newLineArray).diff(); wikiSubDiffs = new ArrayList<WikiDiff>(); int j = 0; for (Difference changedLineDiff : changedLineDiffs) { // build sub-diff list, which is the difference for the individual // line item j++; if (j == 1) { // pre-buffering is only necessary for the first element as post-buffering // will handle all further buffering when bufferAmount is -1. wikiSubDiffs.addAll( DiffUtil.preBufferDifference( changedLineDiff, null, oldLineArray, newLineArray, -1)); } wikiSubDiffs.addAll( DiffUtil.processDifference(changedLineDiff, oldLineArray, newLineArray)); nextLineDiff = (j < changedLineDiffs.size()) ? changedLineDiffs.get(j) : null; wikiSubDiffs.addAll( DiffUtil.postBufferDifference( changedLineDiff, nextLineDiff, oldLineArray, newLineArray, -1)); } changedLineWikiDiff.setSubDiffs(wikiSubDiffs); } wikiDiffs.addAll(changedLineWikiDiffs); nextDiff = (i < diffs.size()) ? diffs.get(i) : null; wikiDiffs.addAll( DiffUtil.postBufferDifference( currentDiff, nextDiff, oldArray, newArray, DIFF_UNCHANGED_LINE_DISPLAY)); previousDiff = currentDiff; } return wikiDiffs; }
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); }
/** * Return a list of WikiDiff objects that can be used to create a display of the diff content. * * @param newVersion The String that is to be compared to, ie the later version of a topic. * @param oldVersion The String that is to be considered as having changed, ie the earlier version * of a topic. * @return Returns a list of WikiDiff objects that correspond to the changed text. */ public static List<WikiDiff> diff(String newVersion, String oldVersion) throws DataAccessException { List<WikiDiff> result = DiffUtil.retrieveFromCache(newVersion, oldVersion); if (result != null) { return result; } String version1 = newVersion; String version2 = oldVersion; if (version2 == null) { version2 = ""; } if (version1 == null) { version1 = ""; } // remove line-feeds to avoid unnecessary noise in the diff due to // cut & paste or other issues version2 = StringUtils.remove(version2, '\r'); version1 = StringUtils.remove(version1, '\r'); result = DiffUtil.process(version1, version2); DiffUtil.addToCache(newVersion, oldVersion, result); return result; }
private void resolve(HttpServletRequest request, ModelAndView next, WikiPageInfo pageInfo) throws Exception { String topicName = JAMWikiServlet.getTopicFromRequest(request); String virtualWiki = JAMWikiServlet.getVirtualWikiFromURI(request); TopicVersion version = WikiBase.getHandler().lookupLastTopicVersion(virtualWiki, topicName); String contents1 = version.getVersionContent(); String contents2 = request.getParameter("contents"); next.addObject("lastTopicVersionId", new Integer(version.getTopicVersionId())); next.addObject("contents", contents1); next.addObject("contentsResolve", contents2); Vector diffs = DiffUtil.diff(contents1, contents2); next.addObject("diffs", diffs); loadEdit(request, next, pageInfo, virtualWiki, topicName, false); pageInfo.setAction(WikiPageInfo.ACTION_EDIT_RESOLVE); }