1 /************************************************************** 2 * 3 * Licensed to the Apache Software Foundation (ASF) under one 4 * or more contributor license agreements. See the NOTICE file 5 * distributed with this work for additional information 6 * regarding copyright ownership. The ASF licenses this file 7 * to you under the Apache License, Version 2.0 (the 8 * "License"); you may not use this file except in compliance 9 * with the License. You may obtain a copy of the License at 10 * 11 * http://www.apache.org/licenses/LICENSE-2.0 12 * 13 * Unless required by applicable law or agreed to in writing, 14 * software distributed under the License is distributed on an 15 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16 * KIND, either express or implied. See the License for the 17 * specific language governing permissions and limitations 18 * under the License. 19 * 20 *************************************************************/ 21 22 23 24 package org.openoffice.xmerge.merger; 25 26 27 /** 28 * This is the <code>Difference</code> basic unit. Used by the 29 * <code>DiffAlgorithm</code> as a set of difference between two 30 * <code>Iterators</code> (the original and modified 31 * <code>Iterators</code>). 32 * 33 * @author smak 34 */ 35 public final class Difference { 36 37 /** 38 * Add operation. 39 */ 40 public static final int ADD = 1; 41 42 /** 43 * Delete operation. 44 */ 45 public static final int DELETE = 2; 46 47 /** 48 * Change operation. 49 */ 50 public static final int CHANGE = 3; 51 52 /** 53 * Unchange operation (i.e. no change). 54 */ 55 public static final int UNCHANGE = 4; 56 57 /** 58 * The action of the diff - either {@link #ADD} or {@link #DELETE}. 59 */ 60 private int operation; 61 62 /** 63 * <p>The position of the content that should be operated on (original 64 * iterator).</p> 65 * 66 * <p>For ADD, the orgPosition is the position of the original sequence 67 * where the diff will insert (the element count is starting from 0, and 68 * always insert before the element). The modPosition is the position 69 * of the diff in the modified sequence (also starting from 0).</p> 70 * 71 * <blockquote><pre> 72 * example: 73 * 74 * diff - <B D>and <A B C D E F> 75 * note: <B D>is original sequence and <A B C D E F> 76 * is the modified one. 77 * 78 * and here is the position of those sequence: 79 * <B D> <A B C D E F> 80 * 0 1 0 1 2 3 4 5 81 * 82 * result: 83 * <diff orgPos=0 modPos=0 operation=ADD> <-- element A 84 * <diff orgPos=1 modPos=2 operation=ADD> <-- element C 85 * <diff orgPos=2 modPos=4 operation=ADD> <-- element E 86 * <diff orgPos=2 modPos=5 operation=ADD> <-- element F 87 * 88 * </pre> </blockquote> 89 * <p>One can notice the add operation is inserted before the position. 90 * Hence, in order to append an element, we will have a position of 91 * original sequence length + 1 to denote an append.</p> 92 * 93 * <p>For DELETE, orgPosition is the position that the element 94 * will be deleted (starting from 0) and modPosition is the position 95 * where the deleted element should be (consider as an ADD).</p> 96 * 97 * <p>The modPosition is less useful and it is difficult to understand 98 * how the position is calculated. One can just skip this piece of 99 * information. It is useful if one wants to reverse the role 100 * of original sequence and modified sequence and find out the diff 101 * easily (just change add to delete and delete to add for operation 102 * and swap the orgPosition and modPosition).</p> 103 * 104 * <blockquote><pre> 105 * example: 106 * 107 * diff - <A B C D E F> and < B D> 108 * note: <A B C D E F> is original sequence and <B D> 109 * is the modified one. 110 * 111 * and here is the position of those sequence: 112 * <A B C D E F> <B D> 113 * 0 1 2 3 4 5 0 1 114 * 115 * result: 116 * <diff orgPos=0 modPos=0 operation=DELETE> <-- element A 117 * <diff orgPos=2 modPos=1 operation=DELETE> <-- element C 118 * <diff orgPos=4 modPos=2 operation=DELETE> <-- element E 119 * <diff orgPos=5 modPos=2 operation=DELETE> <-- element F 120 * </pre></blockquote> 121 */ 122 private int orgPosition; 123 124 /** 125 * The position of the content that should be operated (modified iterator). 126 * For explanation and examples, see {@link #orgPosition}. 127 */ 128 private int modPosition; 129 130 131 /** 132 * Constructor. This is the standard way to create a 133 * <code>Difference</code> object. 134 * 135 * @param operation Either {@link #ADD} or {@link #DELETE}. 136 * @param orgPosition The position in the original (first) 137 * <code>Iterator</code>. 138 * @param modPosition The position in the modified (second) 139 * <code>Iterator</code>. 140 */ Difference(int operation, int orgPosition, int modPosition)141 public Difference(int operation, int orgPosition, 142 int modPosition) { 143 this.operation = operation; 144 this.orgPosition = orgPosition; 145 this.modPosition = modPosition; 146 } 147 148 149 /** 150 * Get the operation of the <code>Difference</code>. 151 * 152 * @return the operation of the <code>Difference</code>, 153 * either {@link #ADD} or {@link #DELETE} 154 */ getOperation()155 public int getOperation() { 156 return operation; 157 } 158 159 /** 160 * Get the original <code>Iterator</code> position. 161 * 162 * @return The position in the original (first) <code>Iterator</code> 163 */ getOrgPosition()164 public int getOrgPosition() { 165 return orgPosition; 166 } 167 168 /** 169 * Get the modified <code>Iterator</code> position. 170 * 171 * @return The position in the modified (second) <code>Iterator</code> 172 */ getModPosition()173 public int getModPosition() { 174 return modPosition; 175 } 176 177 178 /** 179 * Two <code>Difference</code> objects will equal if and only if 180 * all operation, orgPosition, modPosition and content are equal. 181 * 182 * @param obj Object to compare. 183 * 184 * @return true if equal, false otherwise. 185 */ equals(Object obj)186 public boolean equals(Object obj) { 187 if (obj instanceof Difference) { 188 Difference diff = (Difference) obj; 189 if ((operation == diff.operation) && 190 (orgPosition == diff.orgPosition) && 191 (modPosition == diff.modPosition)) { 192 return true; 193 } 194 } 195 196 return false; 197 } 198 199 /** 200 * Display debug information. 201 * 202 * @return Debug string. 203 */ debug()204 public String debug() { 205 206 String opStr = ""; 207 208 switch (operation) { 209 case ADD: 210 opStr = "add"; 211 break; 212 case DELETE: 213 opStr = "del"; 214 break; 215 case CHANGE: 216 opStr = "chg"; 217 break; 218 case UNCHANGE: 219 opStr = "uch"; 220 break; 221 default: 222 break; 223 } 224 return "<diff orgPos=" + orgPosition + " modPos=" + modPosition + 225 " op=" + opStr + ">"; 226 } 227 228 /** 229 * Returns position and operation values as a single string. 230 * 231 * @return orgPosition, modPosition and operation as a single string. 232 */ toString()233 public String toString() { 234 235 return orgPosition + " " + modPosition + " " + operation; 236 } 237 } 238 239