View Javadoc
1   /*
2    * Copyright (C) 2008-2009, Johannes E. Schindelin <johannes.schindelin@gmx.de> and others
3    *
4    * This program and the accompanying materials are made available under the
5    * terms of the Eclipse Distribution License v. 1.0 which is available at
6    * https://www.eclipse.org/org/documents/edl-v10.php.
7    *
8    * SPDX-License-Identifier: BSD-3-Clause
9    */
10  
11  package org.eclipse.jgit.diff;
12  
13  /**
14   * A modified region detected between two versions of roughly the same content.
15   * <p>
16   * An edit covers the modified region only. It does not cover a common region.
17   * <p>
18   * Regions should be specified using 0 based notation, so add 1 to the start and
19   * end marks for line numbers in a file.
20   * <p>
21   * An edit where {@code beginA == endA && beginB < endB} is an insert edit, that
22   * is sequence B inserted the elements in region <code>[beginB, endB)</code> at
23   * <code>beginA</code>.
24   * <p>
25   * An edit where {@code beginA < endA && beginB == endB} is a delete edit, that
26   * is sequence B has removed the elements between <code>[beginA, endA)</code>.
27   * <p>
28   * An edit where {@code beginA < endA && beginB < endB} is a replace edit, that
29   * is sequence B has replaced the range of elements between
30   * <code>[beginA, endA)</code> with those found in <code>[beginB, endB)</code>.
31   */
32  public class Edit {
33  	/** Type of edit */
34  	public enum Type {
35  		/** Sequence B has inserted the region. */
36  		INSERT,
37  
38  		/** Sequence B has removed the region. */
39  		DELETE,
40  
41  		/** Sequence B has replaced the region with different content. */
42  		REPLACE,
43  
44  		/** Sequence A and B have zero length, describing nothing. */
45  		EMPTY;
46  	}
47  
48  	int beginA;
49  
50  	int endA;
51  
52  	int beginB;
53  
54  	int endB;
55  
56  	/**
57  	 * Create a new empty edit.
58  	 *
59  	 * @param as
60  	 *            beginA: start and end of region in sequence A; 0 based.
61  	 * @param bs
62  	 *            beginB: start and end of region in sequence B; 0 based.
63  	 */
64  	public Edit(int as, int bs) {
65  		this(as, as, bs, bs);
66  	}
67  
68  	/**
69  	 * Create a new edit.
70  	 *
71  	 * @param as
72  	 *            beginA: start of region in sequence A; 0 based.
73  	 * @param ae
74  	 *            endA: end of region in sequence A; must be &gt;= as.
75  	 * @param bs
76  	 *            beginB: start of region in sequence B; 0 based.
77  	 * @param be
78  	 *            endB: end of region in sequence B; must be &gt; = bs.
79  	 */
80  	public Edit(int as, int ae, int bs, int be) {
81  		beginA = as;
82  		endA = ae;
83  
84  		beginB = bs;
85  		endB = be;
86  	}
87  
88  	/**
89  	 * Get type
90  	 *
91  	 * @return the type of this region
92  	 */
93  	public final Type getType() {
94  		if (beginA < endA) {
95  			if (beginB < endB) {
96  				return Type.REPLACE;
97  			}
98  			return Type.DELETE;
99  
100 		}
101 		if (beginB < endB) {
102 			return Type.INSERT;
103 		}
104 		// beginB == endB)
105 		return Type.EMPTY;
106 	}
107 
108 	/**
109 	 * Whether edit is empty
110 	 *
111 	 * @return {@code true} if the edit is empty (lengths of both a and b is
112 	 *         zero)
113 	 */
114 	public final boolean isEmpty() {
115 		return beginA == endA && beginB == endB;
116 	}
117 
118 	/**
119 	 * Get start point in sequence A
120 	 *
121 	 * @return start point in sequence A
122 	 */
123 	public final int getBeginA() {
124 		return beginA;
125 	}
126 
127 	/**
128 	 * Get end point in sequence A
129 	 *
130 	 * @return end point in sequence A
131 	 */
132 	public final int getEndA() {
133 		return endA;
134 	}
135 
136 	/**
137 	 * Get start point in sequence B
138 	 *
139 	 * @return start point in sequence B
140 	 */
141 	public final int getBeginB() {
142 		return beginB;
143 	}
144 
145 	/**
146 	 * Get end point in sequence B
147 	 *
148 	 * @return end point in sequence B
149 	 */
150 	public final int getEndB() {
151 		return endB;
152 	}
153 
154 	/**
155 	 * Get length of the region in A
156 	 *
157 	 * @return length of the region in A
158 	 */
159 	public final int getLengthA() {
160 		return endA - beginA;
161 	}
162 
163 	/**
164 	 * Get length of the region in B
165 	 *
166 	 * @return return length of the region in B
167 	 */
168 	public final int getLengthB() {
169 		return endB - beginB;
170 	}
171 
172 	/**
173 	 * Move the edit region by the specified amount.
174 	 *
175 	 * @param amount
176 	 *            the region is shifted by this amount, and can be positive or
177 	 *            negative.
178 	 * @since 4.8
179 	 */
180 	public final void shift(int amount) {
181 		beginA += amount;
182 		endA += amount;
183 		beginB += amount;
184 		endB += amount;
185 	}
186 
187 	/**
188 	 * Construct a new edit representing the region before cut.
189 	 *
190 	 * @param cut
191 	 *            the cut point. The beginning A and B points are used as the
192 	 *            end points of the returned edit.
193 	 * @return an edit representing the slice of {@code this} edit that occurs
194 	 *         before {@code cut} starts.
195 	 */
196 	public final Editref="../../../../org/eclipse/jgit/diff/Edit.html#Edit">Edit before(Edit cut) {
197 		return new Edit(beginA, cut.beginA, beginB, cut.beginB);
198 	}
199 
200 	/**
201 	 * Construct a new edit representing the region after cut.
202 	 *
203 	 * @param cut
204 	 *            the cut point. The ending A and B points are used as the
205 	 *            starting points of the returned edit.
206 	 * @return an edit representing the slice of {@code this} edit that occurs
207 	 *         after {@code cut} ends.
208 	 */
209 	public final Edithref="../../../../org/eclipse/jgit/diff/Edit.html#Edit">Edit after(Edit cut) {
210 		return new Edit(cut.endA, endA, cut.endB, endB);
211 	}
212 
213 	/**
214 	 * Increase {@link #getEndA()} by 1.
215 	 */
216 	public void extendA() {
217 		endA++;
218 	}
219 
220 	/**
221 	 * Increase {@link #getEndB()} by 1.
222 	 */
223 	public void extendB() {
224 		endB++;
225 	}
226 
227 	/**
228 	 * Swap A and B, so the edit goes the other direction.
229 	 */
230 	public void swap() {
231 		final int sBegin = beginA;
232 		final int sEnd = endA;
233 
234 		beginA = beginB;
235 		endA = endB;
236 
237 		beginB = sBegin;
238 		endB = sEnd;
239 	}
240 
241 	/** {@inheritDoc} */
242 	@Override
243 	public int hashCode() {
244 		return beginA ^ endA;
245 	}
246 
247 	/** {@inheritDoc} */
248 	@Override
249 	public boolean equals(Object o) {
250 		if (o instanceof Edit) {
251 			final Edit href="../../../../org/eclipse/jgit/diff/Edit.html#Edit">Edit e = (Edit) o;
252 			return this.beginA == e.beginA && this.endA == e.endA
253 					&& this.beginB == e.beginB && this.endB == e.endB;
254 		}
255 		return false;
256 	}
257 
258 	/** {@inheritDoc} */
259 	@SuppressWarnings("nls")
260 	@Override
261 	public String toString() {
262 		final Type t = getType();
263 		return t + "(" + beginA + "-" + endA + "," + beginB + "-" + endB + ")";
264 	}
265 }