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 - &lt;B D&gt;and &lt;A B C D E F&gt;
75      *   note: &lt;B D&gt;is original sequence and &lt;A B C D E F&gt;
76      *   is the modified one.
77      *
78      *        and here is the position of those sequence:
79      *        &lt;B D&gt; &lt;A B C D E F&gt;
80      *         0 1   0 1 2 3 4 5
81      *
82      *   result:
83      *   &lt;diff orgPos=0 modPos=0 operation=ADD&gt;  &lt;-- element A
84      *   &lt;diff orgPos=1 modPos=2 operation=ADD&gt;  &lt;-- element C
85      *   &lt;diff orgPos=2 modPos=4 operation=ADD&gt;  &lt;-- element E
86      *   &lt;diff orgPos=2 modPos=5 operation=ADD&gt;  &lt;-- 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 - &lt;A B C D E F&gt; and &lt; B D&gt;
108      *  note: &lt;A B C D E F&gt; is original sequence and &lt;B D&gt;
109      *  is the modified one.
110      *
111      *        and here is the position of those sequence:
112      *        &lt;A B C D E F&gt; &lt;B D&gt;
113      *         0 1 2 3 4 5   0 1
114      *
115      *  result:
116      *  &lt;diff orgPos=0 modPos=0 operation=DELETE&gt;  &lt;--  element A
117      *  &lt;diff orgPos=2 modPos=1 operation=DELETE&gt;  &lt;--  element C
118      *  &lt;diff orgPos=4 modPos=2 operation=DELETE&gt;  &lt;--  element E
119      *  &lt;diff orgPos=5 modPos=2 operation=DELETE&gt;  &lt;--  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