| /************************************************************************* |
| * Licensed to the Apache Software Foundation (ASF) under one or more |
| * contributor license agreements. See the NOTICE file distributed with |
| * this work for additional information regarding copyright ownership. |
| * The ASF licenses this file to You 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 org.apache.jackrabbit.vault.util.diff; |
| |
| import java.util.Arrays; |
| import java.util.List; |
| |
| import difflib.Chunk; |
| import difflib.Delta; |
| import difflib.DiffUtils; |
| import difflib.Patch; |
| |
| /** |
| * A class to compare vectors of objects. |
| */ |
| public class Diff { |
| |
| /** |
| * Left list of elements |
| */ |
| private final List<?> left; |
| |
| /** |
| * Right list of elements |
| */ |
| private final List<?> right; |
| |
| |
| /** |
| * Constructor to find differences between two arrays. |
| * @param a left "document" |
| * @param b right document |
| */ |
| public Diff(Object[] a, Object[] b) { |
| left = Arrays.asList(a); |
| right = Arrays.asList(b); |
| } |
| |
| /** |
| * When set to true, the comparison uses a heuristic to speed it up. |
| * With this heuristic, for files with a constant small density |
| * of changes, the algorithm is linear in the file size. |
| */ |
| @Deprecated |
| public boolean heuristic = false; |
| |
| /** |
| * When set to true, the algorithm returns a guaranteed minimal |
| * set of changes. This makes things slower, sometimes much slower. |
| */ |
| @Deprecated |
| public boolean no_discards = false; |
| |
| /** |
| * Compute the difference between the 2 arrays. |
| * @param reverse Indicates reverse diff |
| * @return the change |
| */ |
| public Change diff_2(final boolean reverse) { |
| Change prev = new Change(0,0,0,0, null); |
| Change ret = prev; |
| Patch p = DiffUtils.diff(left, right); |
| |
| // recompute the changes based on the deltas. |
| // todo: use the deltas directly in the DocumentDiff. |
| for (Delta d: p.getDeltas()) { |
| Chunk c0 = d.getOriginal(); |
| Chunk c1 = d.getRevised(); |
| Change next = new Change( |
| c0.getPosition(), c1.getPosition(), |
| c0.getLines().size(), c1.getLines().size(), |
| null); |
| |
| if (reverse) { |
| next.nextChange = ret; |
| ret = next; |
| } else { |
| prev.nextChange = next; |
| prev = next; |
| } |
| } |
| return reverse ? ret : ret.nextChange; |
| } |
| |
| /** |
| * The result of the diff. |
| */ |
| public static class Change { |
| |
| /** |
| * Previous or next edit command. |
| */ |
| public Change nextChange; |
| |
| /** |
| * # lines of file 1 changed here. |
| */ |
| public final int inserted; |
| |
| /** |
| * # lines of file 0 changed here. |
| */ |
| public final int deleted; |
| |
| /** |
| * Line number of 1st deleted line. |
| */ |
| public final int line0; |
| |
| /** |
| * Line number of 1st inserted line. |
| */ |
| public final int line1; |
| |
| /** |
| * Creates a new change entry. If {@code deleted} is 0, then {@code line0} is the number of the line before the |
| * insertion was done. If {@code inserted} is 0, then {@code line1} is the number of the line before the deletion |
| * was done. |
| * |
| * @param line0 first affected line in the left file. |
| * @param line1 first affected line in the right file. |
| * @param deleted number of deleted lines from left file. |
| * @param inserted number of inserted lines in right file |
| * @param old previous change. |
| */ |
| Change(int line0, int line1, int deleted, int inserted, Change old) { |
| this.line0 = line0; |
| this.line1 = line1; |
| this.inserted = inserted; |
| this.deleted = deleted; |
| this.nextChange = old; |
| } |
| } |
| |
| |
| } |