Exemplo n.º 1
0
 /**
  * If possible, append a few lines of unchanged text that appears after to the changed line in
  * order to add context to the current list of WikiDiff objects.
  *
  * @param currentDiff The current diff object.
  * @param nextDiff The diff object that immediately follows this object (if any).
  * @param oldArray The original array of string objects that was compared from in order to
  *     generate the diff.
  * @param newArray The original array of string objects that was compared to in order to generate
  *     the diff.
  * @param bufferAmount The number of unchanged elements to display after the diff, or -1 if all
  *     unchanged lines should be displayed.
  */
 private static List<WikiDiff> postBufferDifference(
     Difference currentDiff,
     Difference nextDiff,
     String[] oldArray,
     String[] newArray,
     int bufferAmount) {
   List<WikiDiff> wikiDiffs = new ArrayList<WikiDiff>();
   if (bufferAmount == 0) {
     // do not buffer
     return wikiDiffs;
   }
   int deletedCurrent =
       (currentDiff.getDeletedEnd() == -1)
           ? currentDiff.getDeletedStart()
           : (currentDiff.getDeletedEnd() + 1);
   int addedCurrent =
       (currentDiff.getAddedEnd() == -1)
           ? currentDiff.getAddedStart()
           : (currentDiff.getAddedEnd() + 1);
   int numIterations = bufferAmount;
   if (bufferAmount == -1) {
     // buffer everything
     numIterations =
         (nextDiff != null)
             ? Math.max(
                 nextDiff.getAddedStart() - addedCurrent,
                 nextDiff.getDeletedStart() - deletedCurrent)
             : Math.max(oldArray.length - deletedCurrent, newArray.length - addedCurrent);
   }
   String oldText = null;
   String newText = null;
   for (int i = 0; i < numIterations; i++) {
     int position = (deletedCurrent < 0) ? 0 : deletedCurrent;
     oldText = null;
     newText = null;
     if (canPostBuffer(nextDiff, deletedCurrent, oldArray, false)) {
       oldText = oldArray[deletedCurrent];
       deletedCurrent++;
     }
     if (canPostBuffer(nextDiff, addedCurrent, newArray, true)) {
       newText = newArray[addedCurrent];
       addedCurrent++;
     }
     if (oldText == null && newText == null) {
       logger.fine(
           "Possible DIFF bug: no elements post-buffered.  position: "
               + position
               + " / deletedCurrent: "
               + deletedCurrent
               + " / addedCurrent "
               + addedCurrent
               + " / numIterations: "
               + numIterations);
       break;
     }
     wikiDiffs.add(new WikiDiff(oldText, newText, position));
   }
   return wikiDiffs;
 }
Exemplo n.º 2
0
 /** Utility method for determining whether or not to prepend lines of context around a diff. */
 private static boolean canPreBuffer(
     Difference previousDiff,
     int current,
     int currentStart,
     String[] replacementArray,
     int bufferAmount,
     boolean adding) {
   if (current < 0 || current >= replacementArray.length) {
     // current position is out of range for buffering
     return false;
   }
   if (previousDiff == null) {
     // if no previous diff, buffer away
     return true;
   }
   if (bufferAmount == -1) {
     // if everything is being buffered and there was a previous diff do not pre-buffer
     return false;
   }
   int previousEnd = (adding) ? previousDiff.getAddedEnd() : previousDiff.getDeletedEnd();
   if (previousEnd != -1) {
     // if there was a previous diff but it was several lines previous, buffer away.
     // if there was a previous diff, and it overlaps with the current diff, don't buffer.
     return (current > (previousEnd + bufferAmount));
   }
   int previousStart = (adding) ? previousDiff.getAddedStart() : previousDiff.getDeletedStart();
   if (current <= (previousStart + bufferAmount)) {
     // the previous diff did not specify an end, and the current diff would overlap with
     // buffering from its start, don't buffer
     return false;
   }
   // the previous diff did not specify an end, and the current diff will not overlap
   // with buffering from its start, buffer away.  otherwise the default is not to buffer.
   return (currentStart > current);
 }
Exemplo n.º 3
0
 private static boolean hasMoreDiffInfo(
     int addedCurrent, int deletedCurrent, Difference currentDiff) {
   if (addedCurrent == -1) {
     addedCurrent = 0;
   }
   if (deletedCurrent == -1) {
     deletedCurrent = 0;
   }
   return (addedCurrent <= currentDiff.getAddedEnd()
       || deletedCurrent <= currentDiff.getDeletedEnd());
 }
Exemplo n.º 4
0
 /**
  * Process the diff object and add it to the output. Text will either have been deleted or added
  * (it cannot have remained the same, since a diff object represents a change). This method steps
  * through the diff result and converts it into an array of objects that can be used to easily
  * represent the diff.
  */
 private static List<WikiDiff> processDifference(
     Difference currentDiff, String[] oldArray, String[] newArray) {
   List<WikiDiff> wikiDiffs = new ArrayList<WikiDiff>();
   // if text was deleted then deletedCurrent represents the starting position of the deleted text.
   int deletedCurrent = currentDiff.getDeletedStart();
   // if text was added then addedCurrent represents the starting position of the added text.
   int addedCurrent = currentDiff.getAddedStart();
   // count is simply used to ensure that the loop is not infinite, which should never happen
   int count = 0;
   // the text of the element that changed
   String oldText = null;
   // the text of what the element was changed to
   String newText = null;
   while (hasMoreDiffInfo(addedCurrent, deletedCurrent, currentDiff)) {
     // the position within the diff array (line number, character, etc) at which the change
     // started (starting at 0)
     int position = ((deletedCurrent < 0) ? 0 : deletedCurrent);
     oldText = null;
     newText = null;
     if (currentDiff.getDeletedEnd() >= 0 && currentDiff.getDeletedEnd() >= deletedCurrent) {
       oldText = oldArray[deletedCurrent];
       deletedCurrent++;
     }
     if (currentDiff.getAddedEnd() >= 0 && currentDiff.getAddedEnd() >= addedCurrent) {
       newText = newArray[addedCurrent];
       addedCurrent++;
     }
     wikiDiffs.add(new WikiDiff(oldText, newText, position));
     // FIXME - this shouldn't be necessary
     count++;
     if (count > 5000) {
       logger.warning("Infinite loop in DiffUtils.processDifference");
       break;
     }
   }
   return wikiDiffs;
 }
Exemplo n.º 5
0
 /**
  * If possible, prepend a few lines of unchanged text that before after to the changed line in
  * order to add context to the current list of WikiDiff objects.
  *
  * @param currentDiff The current diff object.
  * @param previousDiff The diff object that immediately preceded this object (if any).
  * @param oldArray The original array of string objects that was compared from in order to
  *     generate the diff.
  * @param newArray The original array of string objects that was compared to in order to generate
  *     the diff.
  * @param bufferAmount The number of unchanged elements to display after the diff, or -1 if all
  *     unchanged lines should be displayed.
  */
 private static List<WikiDiff> preBufferDifference(
     Difference currentDiff,
     Difference previousDiff,
     String[] oldArray,
     String[] newArray,
     int bufferAmount) {
   List<WikiDiff> wikiDiffs = new ArrayList<WikiDiff>();
   if (bufferAmount == 0) {
     return wikiDiffs;
   }
   if (bufferAmount == -1 && previousDiff != null) {
     // when buffering everything, only pre-buffer for the first element as the post-buffer code
     // will handle everything else.
     return wikiDiffs;
   }
   // deletedCurrent is the current position in oldArray to start buffering from
   int deletedCurrent =
       (bufferAmount == -1 || bufferAmount > currentDiff.getDeletedStart())
           ? 0
           : (currentDiff.getDeletedStart() - bufferAmount);
   // addedCurrent is the current position in newArray to start buffering from
   int addedCurrent =
       (bufferAmount == -1 || bufferAmount > currentDiff.getAddedStart())
           ? 0
           : (currentDiff.getAddedStart() - bufferAmount);
   if (previousDiff != null) {
     // if there was a previous diff make sure that it is not being overlapped
     deletedCurrent = Math.max(previousDiff.getDeletedEnd() + 1, deletedCurrent);
     addedCurrent = Math.max(previousDiff.getAddedEnd() + 1, addedCurrent);
   }
   // number of iterations is number of loops required to fully buffer the added and deleted diff
   int numIterations =
       Math.max(
           currentDiff.getDeletedStart() - deletedCurrent,
           currentDiff.getAddedStart() - addedCurrent);
   String oldText = null;
   String newText = null;
   for (int i = 0; i < numIterations; i++) {
     int position = (deletedCurrent < 0) ? 0 : deletedCurrent;
     oldText = null;
     newText = null;
     // if diffs are close together, do not allow buffers to overlap
     if (canPreBuffer(
         previousDiff,
         deletedCurrent,
         currentDiff.getDeletedStart(),
         oldArray,
         bufferAmount,
         false)) {
       oldText = oldArray[deletedCurrent];
       deletedCurrent++;
     }
     if (canPreBuffer(
         previousDiff, addedCurrent, currentDiff.getAddedStart(), newArray, bufferAmount, true)) {
       newText = newArray[addedCurrent];
       addedCurrent++;
     }
     if (oldText == null && newText == null) {
       logger.fine(
           "Possible DIFF bug: no elements pre-buffered.  position: "
               + position
               + " / deletedCurrent: "
               + deletedCurrent
               + " / addedCurrent "
               + addedCurrent
               + " / numIterations: "
               + numIterations);
       break;
     }
     wikiDiffs.add(new WikiDiff(oldText, newText, position));
   }
   return wikiDiffs;
 }