KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > commons > jrcs > diff > Diff


1 /*
2  * ====================================================================
3  *
4  * The Apache Software License, Version 1.1
5  *
6  * Copyright (c) 1999-2003 The Apache Software Foundation.
7  * All rights reserved.
8  *
9  * Redistribution and use in source and binary forms, with or without
10  * modification, are permitted provided that the following conditions
11  * are met:
12  *
13  * 1. Redistributions of source code must retain the above copyright
14  * notice, this list of conditions and the following disclaimer.
15  *
16  * 2. Redistributions in binary form must reproduce the above copyright
17  * notice, this list of conditions and the following disclaimer in
18  * the documentation and/or other materials provided with the
19  * distribution.
20  *
21  * 3. The end-user documentation included with the redistribution, if
22  * any, must include the following acknowledgement:
23  * "This product includes software developed by the
24  * Apache Software Foundation (http://www.apache.org/)."
25  * Alternately, this acknowledgement may appear in the software itself,
26  * if and wherever such third-party acknowledgements normally appear.
27  *
28  * 4. The names "The Jakarta Project", "Commons", and "Apache Software
29  * Foundation" must not be used to endorse or promote products derived
30  * from this software without prior written permission. For written
31  * permission, please contact apache@apache.org.
32  *
33  * 5. Products derived from this software may not be called "Apache"
34  * nor may "Apache" appear in their names without prior written
35  * permission of the Apache Software Foundation.
36  *
37  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
38  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
39  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
40  * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
41  * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
42  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
43  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
44  * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
45  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
46  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
47  * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
48  * SUCH DAMAGE.
49  * ====================================================================
50  *
51  * This software consists of voluntary contributions made by many
52  * individuals on behalf of the Apache Software Foundation. For more
53  * information on the Apache Software Foundation, please see
54  * <http://www.apache.org/>.
55  *
56  */

57
58 package org.apache.commons.jrcs.diff;
59
60 import java.util.*;
61
62 import org.apache.commons.jrcs.diff.myers.MyersDiff;
63 import org.apache.commons.jrcs.util.ToString;
64
65 /**
66  * Implements a differencing engine that works on arrays of {@link Object Object}.
67  *
68  * <p>Within this library, the word <i>text</i> means a unit of information
69  * subject to version control.
70  *
71  * <p>Text is represented as <code>Object[]</code> because
72  * the diff engine is capable of handling more than plain ascci. In fact,
73  * arrays of any type that implements
74  * {@link java.lang.Object#hashCode hashCode()} and
75  * {@link java.lang.Object#equals equals()}
76  * correctly can be subject to differencing using this
77  * library.</p>
78  *
79  * <p>This library provides a framework in which different differencing
80  * algorithms may be used. If no algorithm is specififed, a default
81  * algorithm is used.</p>
82  *
83  * @version $Revision: 1.1 $ $Date: 2004/10/06 09:47:23 $
84  * @author <a HREF="mailto:juanco@suigeneris.org">Juanco Anez</a>
85  * @see Delta
86  * @see DiffAlgorithm
87  *
88  * modifications:
89  *
90  * 27 Apr 2003 bwm
91  *
92  * Added some comments whilst trying to figure out the algorithm
93  *
94  * 03 May 2003 bwm
95  *
96  * Factored out the algorithm implementation into a separate difference
97  * algorithm class to allow pluggable algorithms.
98  */

99
100 public class Diff
101     extends ToString
102 {
103     /** The standard line separator. */
104     public static final String JavaDoc NL = System.getProperty("line.separator");
105
106     /** The line separator to use in RCS format output. */
107     public static final String JavaDoc RCS_EOL = "\n";
108
109     /** The original sequence. */
110     protected final Object JavaDoc[] orig;
111
112     /** The differencing algorithm to use. */
113     protected DiffAlgorithm algorithm;
114
115     /**
116      * Create a differencing object using the default algorithm
117      *
118      * @param the original text that will be compared
119      */

120     public Diff(Object JavaDoc[] original)
121     {
122         this(original, null);
123     }
124
125     /**
126      * Create a differencing object using the given algorithm
127      *
128      * @param o the original text which will be compared against
129      * @param algorithm the difference algorithm to use.
130      */

131     public Diff(Object JavaDoc[] original, DiffAlgorithm algorithm)
132     {
133         if (original == null)
134         {
135             throw new IllegalArgumentException JavaDoc();
136         }
137
138         this.orig = original;
139         if (algorithm != null)
140             this.algorithm = algorithm;
141         else
142             this.algorithm = defaultAlgorithm();
143     }
144
145     protected DiffAlgorithm defaultAlgorithm()
146     {
147         return new MyersDiff();
148     }
149
150     /**
151      * compute the difference between an original and a revision.
152      *
153      * @param orig the original
154      * @param rev the revision to compare with the original.
155      * @return a Revision describing the differences
156      */

157     public static Revision diff(Object JavaDoc[] orig, Object JavaDoc[] rev)
158         throws DifferentiationFailedException
159     {
160         if (orig == null || rev == null)
161         {
162             throw new IllegalArgumentException JavaDoc();
163         }
164
165         return diff(orig, rev, null);
166     }
167
168     /**
169      * compute the difference between an original and a revision.
170      *
171      * @param orig the original
172      * @param rev the revision to compare with the original.
173      * @param algorithm the difference algorithm to use
174      * @return a Revision describing the differences
175      */

176     public static Revision diff(Object JavaDoc[] orig, Object JavaDoc[] rev,
177                                 DiffAlgorithm algorithm)
178         throws DifferentiationFailedException
179     {
180         if (orig == null || rev == null)
181         {
182             throw new IllegalArgumentException JavaDoc();
183         }
184
185         return new Diff(orig, algorithm).diff(rev);
186     }
187
188     /**
189      * compute the difference between the original and a revision.
190      *
191      * @param rev the revision to compare with the original.
192      * @return a Revision describing the differences
193      */

194     public Revision diff(Object JavaDoc[] rev)
195         throws DifferentiationFailedException
196     {
197         if (orig.length == 0 && rev.length == 0)
198             return new Revision();
199         else
200             return algorithm.diff(orig, rev);
201     }
202
203     /**
204      * Compares the two input sequences.
205      * @param orig The original sequence.
206      * @param rev The revised sequence.
207      * @return true if the sequences are identical. False otherwise.
208      */

209     public static boolean compare(Object JavaDoc[] orig, Object JavaDoc[] rev)
210     {
211         if (orig.length != rev.length)
212         {
213             return false;
214         }
215         else
216         {
217             for (int i = 0; i < orig.length; i++)
218             {
219                 if (!orig[i].equals(rev[i]))
220                 {
221                     return false;
222                 }
223             }
224             return true;
225         }
226     }
227
228     /**
229      * Converts an array of {@link Object Object} to a string
230      * using {@link Diff#NL Diff.NL}
231      * as the line separator.
232      * @param o the array of objects.
233      */

234     public static String JavaDoc arrayToString(Object JavaDoc[] o)
235     {
236         return arrayToString(o, Diff.NL);
237     }
238
239     /**
240      * Edits all of the items in the input sequence.
241      * @param text The input sequence.
242      * @return A sequence of the same length with all the lines
243      * differing from the corresponding ones in the input.
244      */

245     public static Object JavaDoc[] editAll(Object JavaDoc[] text)
246     {
247         Object JavaDoc[] result = new String JavaDoc[text.length];
248
249         for(int i = 0; i < text.length; i++)
250             result[i] = text[i] + " <edited>";
251
252         return result;
253     }
254
255     /**
256      * Performs random edits on the input sequence. Useful for testing.
257      * @param text The input sequence.
258      * @return The sequence with random edits performed.
259      */

260     public static Object JavaDoc[] randomEdit(Object JavaDoc[] text)
261     {
262         return randomEdit(text, text.length);
263     }
264
265     /**
266      * Performs random edits on the input sequence. Useful for testing.
267      * @param text The input sequence.
268      * @param seed A seed value for the randomizer.
269      * @return The sequence with random edits performed.
270      */

271     public static Object JavaDoc[] randomEdit(Object JavaDoc[] text, long seed)
272     {
273         List result = new ArrayList(Arrays.asList(text));
274         Random r = new Random(seed);
275         int nops = r.nextInt(10);
276         for (int i = 0; i < nops; i++)
277         {
278             boolean del = r.nextBoolean();
279             int pos = r.nextInt(result.size() + 1);
280             int len = Math.min(result.size() - pos, 1 + r.nextInt(4));
281             if (del && result.size() > 0)
282             { // delete
283
result.subList(pos, pos + len).clear();
284             }
285             else
286             {
287                 for (int k = 0; k < len; k++, pos++)
288                 {
289                     result.add(pos,
290                                "[" + i + "] random edit[" + i + "][" + i + "]");
291                 }
292             }
293         }
294         return result.toArray();
295     }
296
297     /**
298      * Shuffles around the items in the input sequence.
299      * @param text The input sequence.
300      * @return The shuffled sequence.
301      */

302     public static Object JavaDoc[] shuffle(Object JavaDoc[] text)
303     {
304         return shuffle(text, text.length);
305     }
306
307     /**
308     * Shuffles around the items in the input sequence.
309     * @param text The input sequence.
310     * @param seed A seed value for randomizing the suffle.
311     * @return The shuffled sequence.
312     */

313    public static Object JavaDoc[] shuffle(Object JavaDoc[] text, long seed)
314     {
315         List result = new ArrayList(Arrays.asList(text));
316         Collections.shuffle(result);
317         return result.toArray();
318     }
319
320     /**
321      * Generate a random sequence of the given size.
322      * @param The size of the sequence to generate.
323      * @return The generated sequence.
324      */

325     public static Object JavaDoc[] randomSequence(int size)
326     {
327         return randomSequence(size, size);
328     }
329
330     /**
331      * Generate a random sequence of the given size.
332      * @param The size of the sequence to generate.
333      * @param seed A seed value for randomizing the generation.
334      * @return The generated sequence.
335      */

336     public static Object JavaDoc[] randomSequence(int size, long seed)
337     {
338         Integer JavaDoc[] result = new Integer JavaDoc[size];
339         Random r = new Random(seed);
340         for(int i = 0; i < result.length; i++)
341         {
342             result[i] = new Integer JavaDoc(r.nextInt(size));
343         }
344         return result;
345     }
346
347 }
Popular Tags