KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > eclipse > compare > structuremergeviewer > DiffNode


1 /*******************************************************************************
2  * Copyright (c) 2000, 2006 IBM Corporation and others.
3  * All rights reserved. This program and the accompanying materials
4  * are made available under the terms of the Eclipse Public License v1.0
5  * which accompanies this distribution, and is available at
6  * http://www.eclipse.org/legal/epl-v10.html
7  *
8  * Contributors:
9  * IBM Corporation - initial API and implementation
10  *******************************************************************************/

11 package org.eclipse.compare.structuremergeviewer;
12
13 import com.ibm.icu.text.MessageFormat;
14
15 import org.eclipse.swt.graphics.Image;
16
17 import org.eclipse.core.runtime.ListenerList;
18
19 import org.eclipse.compare.*;
20 import org.eclipse.compare.internal.Utilities;
21
22 /**
23  * Diff node are used as the compare result of the differencing engine.
24  * Since it implements the <code>ITypedElement</code> and <code>ICompareInput</code>
25  * interfaces it can be used directly to display the
26  * compare result in a <code>DiffTreeViewer</code> and as the input to any other
27  * compare/merge viewer.
28  * <p>
29  * <code>DiffNode</code>s are typically created as the result of performing
30  * a compare with the <code>Differencer</code>.
31  * <p>
32  * Clients typically use this class as is, but may subclass if required.
33  *
34  * @see DiffTreeViewer
35  * @see Differencer
36  */

37 public class DiffNode extends DiffContainer implements ITypedElement, ICompareInput {
38
39     private ITypedElement fAncestor;
40     private ITypedElement fLeft;
41     private ITypedElement fRight;
42     private boolean fDontExpand;
43     private ListenerList fListener;
44     private boolean fSwapSides;
45
46     
47     /**
48      * Creates a new <code>DiffNode</code> and initializes with the given values.
49      *
50      * @param parent under which the new container is added as a child or <code>null</code>
51      * @param kind of difference (defined in <code>Differencer</code>)
52      * @param ancestor the common ancestor input to a compare
53      * @param left the left input to a compare
54      * @param right the right input to a compare
55      */

56     public DiffNode(IDiffContainer parent, int kind, ITypedElement ancestor, ITypedElement left, ITypedElement right) {
57         this(parent, kind);
58         fAncestor= ancestor;
59         fLeft= left;
60         fRight= right;
61     }
62
63     /**
64      * Creates a new <code>DiffNode</code> with diff kind <code>Differencer.CHANGE</code>
65      * and initializes with the given values.
66      *
67      * @param left the left input to a compare
68      * @param right the right input to a compare
69      */

70     public DiffNode(ITypedElement left, ITypedElement right) {
71         this(null, Differencer.CHANGE, null, left, right);
72     }
73
74     /**
75      * Creates a new <code>DiffNode</code> and initializes with the given values.
76      *
77      * @param kind of difference (defined in <code>Differencer</code>)
78      * @param ancestor the common ancestor input to a compare
79      * @param left the left input to a compare
80      * @param right the right input to a compare
81      */

82     public DiffNode(int kind, ITypedElement ancestor, ITypedElement left, ITypedElement right) {
83         this(null, kind, ancestor, left, right);
84     }
85
86     /**
87      * Creates a new <code>DiffNode</code> with the given diff kind.
88      *
89      * @param kind of difference (defined in <code>Differencer</code>)
90      */

91     public DiffNode(int kind) {
92         super(null, kind);
93     }
94
95     /**
96      * Creates a new <code>DiffNode</code> and initializes with the given values.
97      *
98      * @param parent under which the new container is added as a child or <code>null</code>
99      * @param kind of difference (defined in <code>Differencer</code>)
100      */

101     public DiffNode(IDiffContainer parent, int kind) {
102         super(parent, kind);
103     }
104
105     /**
106      * Registers a listener for changes of this <code>ICompareInput</code>.
107      * Has no effect if an identical listener is already registered.
108      *
109      * @param listener the listener to add
110      */

111     public void addCompareInputChangeListener(ICompareInputChangeListener listener) {
112         if (fListener == null)
113             fListener= new ListenerList();
114         fListener.add(listener);
115     }
116     
117     /**
118      * Unregisters a <code>ICompareInput</code> listener.
119      * Has no effect if listener is not registered.
120      *
121      * @param listener the listener to remove
122      */

123     public void removeCompareInputChangeListener(ICompareInputChangeListener listener) {
124         if (fListener != null) {
125             fListener.remove(listener);
126             if (fListener.isEmpty())
127                 fListener= null;
128         }
129     }
130     
131     /**
132      * Sends out notification that a change has occurred on the <code>ICompareInput</code>.
133      */

134     protected void fireChange() {
135         if (fListener != null) {
136             Object JavaDoc[] listeners= fListener.getListeners();
137             for (int i= 0; i < listeners.length; i++)
138                 ((ICompareInputChangeListener) listeners[i]).compareInputChanged(this);
139         }
140     }
141
142     //---- getters & setters
143

144     /**
145      * Returns <code>true</code> if this node shouldn't automatically be expanded in
146      * a </code>DiffTreeViewer</code>.
147      *
148      * @return <code>true</code> if node shouldn't automatically be expanded
149      */

150     public boolean dontExpand() {
151         return fDontExpand;
152     }
153
154     /**
155      * Controls whether this node is not automatically expanded when displayed in
156      * a </code>DiffTreeViewer</code>.
157      *
158      * @param dontExpand if <code>true</code> this node is not automatically expanded in </code>DiffTreeViewer</code>
159      */

160     public void setDontExpand(boolean dontExpand) {
161         fDontExpand= dontExpand;
162     }
163
164     /**
165      * Returns the first not-<code>null</code> input of this node.
166      * Method checks the three inputs in the order: ancestor, right, left.
167      *
168      * @return the first not-<code>null</code> input of this node
169      */

170     public ITypedElement getId() {
171         if (fAncestor != null)
172             return fAncestor;
173         if (fRight != null)
174             return fRight;
175         return fLeft;
176     }
177
178     /**
179      * Returns the (non-<code>null</code>) name of the left or right side if they are identical.
180      * Otherwise both names are concatenated (separated with a slash ('/')).
181      * <p>
182      * Subclasses may re-implement to provide a different name for this node.
183      * @return the name of this node.
184      */

185     public String JavaDoc getName() {
186         String JavaDoc right= null;
187         if (fRight != null)
188             right= fRight.getName();
189
190         String JavaDoc left= null;
191         if (fLeft != null)
192             left= fLeft.getName();
193
194         if (right == null && left == null) {
195             if (fAncestor != null)
196                 return fAncestor.getName();
197             return Utilities.getString("DiffNode.noName"); //$NON-NLS-1$
198
}
199
200         if (right == null)
201             return left;
202         if (left == null)
203             return right;
204
205         if (right.equals(left))
206             return right;
207             
208         String JavaDoc s1;
209         String JavaDoc s2;
210         
211         if (fSwapSides) {
212             s1= left;
213             s2= right;
214         } else {
215             s1= right;
216             s2= left;
217         }
218         
219         String JavaDoc fmt= Utilities.getString("DiffNode.nameFormat"); //$NON-NLS-1$
220
return MessageFormat.format(fmt, new String JavaDoc[] { s1, s2 });
221     }
222     
223     void swapSides(boolean swap) {
224         fSwapSides= swap;
225     }
226         
227     /* (non Javadoc)
228      * see ITypedElement.getImage
229      */

230     public Image getImage() {
231         ITypedElement id= getId();
232         if (id != null)
233             return id.getImage();
234         return null;
235     }
236
237     /* (non Javadoc)
238      * see ITypedElement.getType
239      */

240     public String JavaDoc getType() {
241         ITypedElement id= getId();
242         if (id != null)
243             return id.getType();
244         return ITypedElement.UNKNOWN_TYPE;
245     }
246
247     /**
248      * Sets the ancestor input to the given value.
249      *
250      * @param ancestor the new value for the ancestor input
251      * @since 3.0
252      */

253     public void setAncestor(ITypedElement ancestor) {
254         fAncestor= ancestor;
255     }
256     
257     /* (non Javadoc)
258      * see ICompareInput.getAncestor
259      */

260     public ITypedElement getAncestor() {
261         return fAncestor;
262     }
263     
264     /**
265      * Sets the left input to the given value.
266      *
267      * @param left the new value for the left input
268      */

269     public void setLeft(ITypedElement left) {
270         fLeft= left;
271     }
272     
273     /* (non Javadoc)
274      * see ICompareInput.getLeft
275      */

276     public ITypedElement getLeft() {
277         return fLeft;
278     }
279
280     /**
281      * Sets the right input to the given value.
282      *
283      * @param right the new value for the right input
284      */

285     public void setRight(ITypedElement right) {
286         fRight= right;
287     }
288     
289     /* (non Javadoc)
290      * see ICompareInput.getRight
291      */

292     public ITypedElement getRight() {
293         return fRight;
294     }
295
296     /* (non Javadoc)
297      * see ICompareInput.copy
298      */

299     public void copy(boolean leftToRight) {
300         //System.out.println("DiffNode.copy: " + leftToRight);
301

302         IDiffContainer pa= getParent();
303         if (pa instanceof ICompareInput) {
304             ICompareInput parent= (ICompareInput) pa;
305             Object JavaDoc dstParent= leftToRight ? parent.getRight() : parent.getLeft();
306             
307             if (dstParent instanceof IEditableContent) {
308                 ITypedElement dst= leftToRight ? getRight() : getLeft();
309                 ITypedElement SRC= leftToRight ? getLeft() : getRight();
310                 dst= ((IEditableContent)dstParent).replace(dst, src);
311                 if (leftToRight)
312                     setRight(dst);
313                 else
314                     setLeft(dst);
315                 
316                 //setKind(Differencer.NO_CHANGE);
317

318                 fireChange();
319             }
320         }
321     }
322     
323     /* (non Javadoc)
324      * see Object.hashCode
325      */

326     public int hashCode() {
327         String JavaDoc[] path= getPath(this, 0);
328         int hashCode= 1;
329         for (int i= 0; i < path.length; i++) {
330             String JavaDoc s= path[i];
331             hashCode= (31*hashCode) + (s != null ? s.hashCode() : 0);
332         }
333         return hashCode;
334     }
335     
336     /* (non Javadoc)
337      * see Object.equals
338      */

339     public boolean equals(Object JavaDoc other) {
340         if (other != null && getClass() == other.getClass()) {
341             String JavaDoc[] path1= getPath(this, 0);
342             String JavaDoc[] path2= getPath((DiffNode) other, 0);
343             if (path1.length != path2.length)
344                 return false;
345             for (int i= 0; i < path1.length; i++)
346                 if (! path1[i].equals(path2[i]))
347                     return false;
348             return true;
349         }
350         return super.equals(other);
351     }
352     
353     private static String JavaDoc[] getPath(ITypedElement el, int level) {
354         String JavaDoc[] path= null;
355         if (el instanceof IDiffContainer) {
356             IDiffContainer parent= ((IDiffContainer)el).getParent();
357             if (parent != null)
358                 path= getPath(parent, level+1);
359         }
360         if (path == null)
361             path= new String JavaDoc[level+1];
362         path[(path.length-1)-level]= el.getName();
363         return path;
364     }
365 }
366
Popular Tags