// Copyright 2004-2014 Jim Voris // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // package com.qumasoft.guitools.compare; import com.qumasoft.qvcslib.CompareLineInfo; import com.qumasoft.qvcslib.QVCSOperationException; import com.qumasoft.qvcslib.QumaAssert; import org.apache.commons.jrcs.diff.AddDelta; import org.apache.commons.jrcs.diff.ChangeDelta; import org.apache.commons.jrcs.diff.DeleteDelta; import org.apache.commons.jrcs.diff.Delta; import org.apache.commons.jrcs.diff.Revision; final class CompareFilesForGUI extends com.qumasoft.qvcslib.CompareFilesWithApacheDiff { private Revision apacheRevision = null; private byte[] fileARowTypeArray; private byte[] fileBRowTypeArray; private Delta[] fileADeltaForRowArray; private Delta[] fileBDeltaForRowArray; CompareFilesForGUI(String[] args) { super(args); QumaAssert.isTrue(args.length == COMMAND_ARG_COUNT); } @Override protected void writeEditScript(Revision apacheRev, CompareLineInfo[] fileA, CompareLineInfo[] fileB) throws QVCSOperationException { this.apacheRevision = apacheRev; // deduce row types for lines in fileA and lines in fileB deduceRowTypes(apacheRev, fileA, fileB); } int getNumberOfChanges() { return this.apacheRevision.size(); } byte getRowType(int lineIndex, boolean firstFile) { byte rowType; if (firstFile) { rowType = fileARowTypeArray[lineIndex]; } else { rowType = fileBRowTypeArray[lineIndex]; } return rowType; } private void deduceRowTypes(Revision apacheRev, CompareLineInfo[] fileA, CompareLineInfo[] fileB) throws QVCSOperationException { // First get all the deltas... Delta[] deltas = new Delta[apacheRev.size()]; for (int i = 0; i < apacheRev.size(); i++) { deltas[i] = apacheRev.getDelta(i); } fileARowTypeArray = new byte[fileA.length]; fileBRowTypeArray = new byte[fileB.length]; fileADeltaForRowArray = new Delta[fileA.length]; fileBDeltaForRowArray = new Delta[fileB.length]; // Set all the rows to default to NORMAL. for (int i = 0; i < fileA.length; i++) { fileARowTypeArray[i] = ContentRow.ROWTYPE_NORMAL; } for (int i = 0; i < fileB.length; i++) { fileBRowTypeArray[i] = ContentRow.ROWTYPE_NORMAL; } for (Delta delta : deltas) { byte rowType; if (delta instanceof AddDelta) { rowType = ContentRow.ROWTYPE_INSERT; // We need to set the row type and delta here for fileA because the // for loop doesn't traverse any rows on fileA. if (delta.getOriginal().anchor() > 0) { fileARowTypeArray[delta.getOriginal().anchor() - 1] = ContentRow.ROWTYPE_NORMAL; fileADeltaForRowArray[delta.getOriginal().anchor() - 1] = delta; } } else if (delta instanceof ChangeDelta) { rowType = ContentRow.ROWTYPE_REPLACE; } else if (delta instanceof DeleteDelta) { rowType = ContentRow.ROWTYPE_DELETE; // We need to set the row type and delta here for fileB because the // for loop doesn't traverse any rows on fileB. if (delta.getRevised().anchor() > 0) { fileBRowTypeArray[delta.getRevised().anchor() - 1] = ContentRow.ROWTYPE_NORMAL; fileBDeltaForRowArray[delta.getRevised().anchor() - 1] = delta; } } else { throw new QVCSOperationException("Unknown delta type."); } @SuppressWarnings("unchecked") int firstA = delta.getOriginal().first(); int lastA = delta.getOriginal().last(); for (int j = firstA; j <= lastA; j++) { fileARowTypeArray[j] = rowType; fileADeltaForRowArray[j] = delta; } int firstB = delta.getRevised().first(); int lastB = delta.getRevised().last(); for (int j = firstB; j <= lastB; j++) { fileBRowTypeArray[j] = rowType; fileBDeltaForRowArray[j] = delta; } } } Delta getLastDelta() { return apacheRevision.getDelta(apacheRevision.size() - 1); } Delta getDelta(int rowIndex, boolean firstFileFlag) { Delta delta; if (firstFileFlag) { delta = fileADeltaForRowArray[rowIndex]; } else { delta = fileBDeltaForRowArray[rowIndex]; } return delta; } Delta getDelta(int deltaIndex) { return apacheRevision.getDelta(deltaIndex); } }