KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > eclipse > jdt > internal > ui > compare > JavaMergeViewer


1 /*******************************************************************************
2  * Copyright (c) 2000, 2007 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.jdt.internal.ui.compare;
12
13 import java.util.ArrayList JavaDoc;
14 import java.util.Iterator JavaDoc;
15
16 import org.eclipse.core.resources.IResource;
17 import org.eclipse.core.resources.ProjectScope;
18
19 import org.eclipse.swt.SWT;
20 import org.eclipse.swt.widgets.Composite;
21 import org.eclipse.swt.events.DisposeEvent;
22 import org.eclipse.swt.graphics.RGB;
23
24 import org.eclipse.jface.preference.IPreferenceStore;
25 import org.eclipse.jface.util.*;
26 import org.eclipse.jface.text.*;
27 import org.eclipse.jface.text.source.SourceViewer;
28 import org.eclipse.jface.preference.PreferenceConverter;
29
30 import org.eclipse.compare.CompareConfiguration;
31 import org.eclipse.compare.IResourceProvider;
32 import org.eclipse.compare.contentmergeviewer.ITokenComparator;
33 import org.eclipse.compare.contentmergeviewer.TextMergeViewer;
34 import org.eclipse.compare.structuremergeviewer.*;
35 import org.eclipse.compare.ITypedElement;
36
37 import org.eclipse.jdt.core.IJavaElement;
38 import org.eclipse.jdt.core.IJavaProject;
39 import org.eclipse.jdt.core.JavaCore;
40
41 import org.eclipse.jdt.ui.text.*;
42
43 import org.eclipse.ui.texteditor.AbstractTextEditor;
44 import org.eclipse.ui.texteditor.ChainedPreferenceStore;
45
46 import org.eclipse.ui.editors.text.EditorsUI;
47
48 import org.eclipse.jdt.internal.ui.JavaPlugin;
49 import org.eclipse.jdt.internal.ui.compare.JavaTokenComparator.ITokenComparatorFactory;
50 import org.eclipse.jdt.internal.ui.text.PreferencesAdapter;
51
52
53 public class JavaMergeViewer extends TextMergeViewer {
54     
55     private IPropertyChangeListener fPreferenceChangeListener;
56     private IPreferenceStore fPreferenceStore;
57     private boolean fUseSystemColors;
58     private JavaSourceViewerConfiguration fSourceViewerConfiguration;
59     private ArrayList JavaDoc fSourceViewer;
60     
61         
62     public JavaMergeViewer(Composite parent, int styles, CompareConfiguration mp) {
63         super(parent, styles | SWT.LEFT_TO_RIGHT, mp);
64                 
65         getPreferenceStore();
66         
67         fUseSystemColors= fPreferenceStore.getBoolean(AbstractTextEditor.PREFERENCE_COLOR_BACKGROUND_SYSTEM_DEFAULT);
68         if (! fUseSystemColors) {
69             RGB bg= createColor(fPreferenceStore, AbstractTextEditor.PREFERENCE_COLOR_BACKGROUND);
70             setBackgroundColor(bg);
71             RGB fg= createColor(fPreferenceStore, IJavaColorConstants.JAVA_DEFAULT);
72             setForegroundColor(fg);
73         }
74     }
75     
76     private IPreferenceStore getPreferenceStore() {
77         if (fPreferenceStore == null)
78             setPreferenceStore(createChainedPreferenceStore(null));
79         return fPreferenceStore;
80     }
81     
82     protected void handleDispose(DisposeEvent event) {
83         setPreferenceStore(null);
84         fSourceViewer= null;
85         super.handleDispose(event);
86     }
87     
88     public IJavaProject getJavaProject(ICompareInput input) {
89         
90         if (input == null)
91             return null;
92         
93         IResourceProvider rp= null;
94         ITypedElement te= input.getLeft();
95         if (te instanceof IResourceProvider)
96             rp= (IResourceProvider) te;
97         if (rp == null) {
98             te= input.getRight();
99             if (te instanceof IResourceProvider)
100                 rp= (IResourceProvider) te;
101         }
102         if (rp == null) {
103             te= input.getAncestor();
104             if (te instanceof IResourceProvider)
105                 rp= (IResourceProvider) te;
106         }
107         if (rp != null) {
108             IResource resource= rp.getResource();
109             if (resource != null) {
110                 IJavaElement element= JavaCore.create(resource);
111                 if (element != null)
112                     return element.getJavaProject();
113             }
114         }
115         return null;
116     }
117
118     public void setInput(Object JavaDoc input) {
119         
120         if (input instanceof ICompareInput) {
121             IJavaProject project= getJavaProject((ICompareInput)input);
122             if (project != null) {
123                 setPreferenceStore(createChainedPreferenceStore(project));
124                 if (fSourceViewer != null) {
125                     Iterator JavaDoc iterator= fSourceViewer.iterator();
126                     while (iterator.hasNext()) {
127                         SourceViewer sourceViewer= (SourceViewer) iterator.next();
128                         sourceViewer.unconfigure();
129                         sourceViewer.configure(getSourceViewerConfiguration());
130                     }
131                 }
132             }
133         }
134             
135         super.setInput(input);
136     }
137     
138     private ChainedPreferenceStore createChainedPreferenceStore(IJavaProject project) {
139         ArrayList JavaDoc stores= new ArrayList JavaDoc(4);
140         if (project != null)
141             stores.add(new EclipsePreferencesAdapter(new ProjectScope(project.getProject()), JavaCore.PLUGIN_ID));
142         stores.add(JavaPlugin.getDefault().getPreferenceStore());
143         stores.add(new PreferencesAdapter(JavaCore.getPlugin().getPluginPreferences()));
144         stores.add(EditorsUI.getPreferenceStore());
145         return new ChainedPreferenceStore((IPreferenceStore[]) stores.toArray(new IPreferenceStore[stores.size()]));
146     }
147
148     private void handlePropertyChange(PropertyChangeEvent event) {
149         
150         String JavaDoc key= event.getProperty();
151         
152         if (key.equals(AbstractTextEditor.PREFERENCE_COLOR_BACKGROUND)) {
153
154             if (!fUseSystemColors) {
155                 RGB bg= createColor(fPreferenceStore, AbstractTextEditor.PREFERENCE_COLOR_BACKGROUND);
156                 setBackgroundColor(bg);
157             }
158                         
159         } else if (key.equals(AbstractTextEditor.PREFERENCE_COLOR_BACKGROUND_SYSTEM_DEFAULT)) {
160
161             fUseSystemColors= fPreferenceStore.getBoolean(AbstractTextEditor.PREFERENCE_COLOR_BACKGROUND_SYSTEM_DEFAULT);
162             if (fUseSystemColors) {
163                 setBackgroundColor(null);
164                 setForegroundColor(null);
165             } else {
166                 RGB bg= createColor(fPreferenceStore, AbstractTextEditor.PREFERENCE_COLOR_BACKGROUND);
167                 setBackgroundColor(bg);
168                 RGB fg= createColor(fPreferenceStore, IJavaColorConstants.JAVA_DEFAULT);
169                 setForegroundColor(fg);
170             }
171         } else if (key.equals(IJavaColorConstants.JAVA_DEFAULT)) {
172
173             if (!fUseSystemColors) {
174                 RGB fg= createColor(fPreferenceStore, IJavaColorConstants.JAVA_DEFAULT);
175                 setForegroundColor(fg);
176             }
177         }
178         
179         if (fSourceViewerConfiguration != null && fSourceViewerConfiguration.affectsTextPresentation(event)) {
180             fSourceViewerConfiguration.handlePropertyChangeEvent(event);
181             invalidateTextPresentation();
182         }
183     }
184     
185     /**
186      * Creates a color from the information stored in the given preference store.
187      * Returns <code>null</code> if there is no such information available.
188      * @param store preference store
189      * @param key preference key
190      * @return the color or <code>null</code>
191      */

192     private static RGB createColor(IPreferenceStore store, String JavaDoc key) {
193         if (!store.contains(key))
194             return null;
195         if (store.isDefault(key))
196             return PreferenceConverter.getDefaultColor(store, key);
197         return PreferenceConverter.getColor(store, key);
198     }
199     
200     public String JavaDoc getTitle() {
201         return CompareMessages.JavaMergeViewer_title;
202     }
203
204     public ITokenComparator createTokenComparator(String JavaDoc s) {
205         return new JavaTokenComparator(s, new ITokenComparatorFactory() {
206             public ITokenComparator createTokenComparator(String JavaDoc text) {
207                 return JavaMergeViewer.super.createTokenComparator(text);
208             }
209         });
210     }
211     
212     protected IDocumentPartitioner getDocumentPartitioner() {
213         return JavaCompareUtilities.createJavaPartitioner();
214     }
215     
216     protected String JavaDoc getDocumentPartitioning() {
217         return IJavaPartitions.JAVA_PARTITIONING;
218     }
219         
220     protected void configureTextViewer(TextViewer textViewer) {
221         if (textViewer instanceof SourceViewer) {
222             if (fSourceViewer == null)
223                 fSourceViewer= new ArrayList JavaDoc();
224             fSourceViewer.add(textViewer);
225             JavaTextTools tools= JavaCompareUtilities.getJavaTextTools();
226             if (tools != null)
227                 ((SourceViewer)textViewer).configure(getSourceViewerConfiguration());
228         }
229     }
230     
231     private JavaSourceViewerConfiguration getSourceViewerConfiguration() {
232         if (fSourceViewerConfiguration == null)
233             getPreferenceStore();
234         return fSourceViewerConfiguration;
235     }
236     
237     protected int findInsertionPosition(char type, ICompareInput input) {
238         
239         int pos= super.findInsertionPosition(type, input);
240         if (pos != 0)
241             return pos;
242         
243         if (input instanceof IDiffElement) {
244             
245             // find the other (not deleted) element
246
JavaNode otherJavaElement= null;
247             ITypedElement otherElement= null;
248             switch (type) {
249             case 'L':
250                 otherElement= input.getRight();
251                 break;
252             case 'R':
253                 otherElement= input.getLeft();
254                 break;
255             }
256             if (otherElement instanceof JavaNode)
257                 otherJavaElement= (JavaNode) otherElement;
258             
259             // find the parent of the deleted elements
260
JavaNode javaContainer= null;
261             IDiffElement diffElement= (IDiffElement) input;
262             IDiffContainer container= diffElement.getParent();
263             if (container instanceof ICompareInput) {
264                 
265                 ICompareInput parent= (ICompareInput) container;
266                 ITypedElement element= null;
267                 
268                 switch (type) {
269                 case 'L':
270                     element= parent.getLeft();
271                     break;
272                 case 'R':
273                     element= parent.getRight();
274                     break;
275                 }
276                 
277                 if (element instanceof JavaNode)
278                     javaContainer= (JavaNode) element;
279             }
280             
281             if (otherJavaElement != null && javaContainer != null) {
282                 
283                 Object JavaDoc[] children;
284                 Position p;
285                 
286                 switch (otherJavaElement.getTypeCode()) {
287                 
288                 case JavaNode.PACKAGE:
289                     return 0;
290
291                 case JavaNode.IMPORT_CONTAINER:
292                     // we have to find the place after the package declaration
293
children= javaContainer.getChildren();
294                     if (children.length > 0) {
295                         JavaNode packageDecl= null;
296                         for (int i= 0; i < children.length; i++) {
297                             JavaNode child= (JavaNode) children[i];
298                             switch (child.getTypeCode()) {
299                             case JavaNode.PACKAGE:
300                                 packageDecl= child;
301                                 break;
302                             case JavaNode.CLASS:
303                                 return child.getRange().getOffset();
304                             }
305                         }
306                         if (packageDecl != null) {
307                             p= packageDecl.getRange();
308                             return p.getOffset() + p.getLength();
309                         }
310                     }
311                     return javaContainer.getRange().getOffset();
312                 
313                 case JavaNode.IMPORT:
314                     // append after last import
315
p= javaContainer.getRange();
316                     return p.getOffset() + p.getLength();
317                 
318                 case JavaNode.CLASS:
319                     // append after last class
320
children= javaContainer.getChildren();
321                     if (children.length > 0) {
322                         for (int i= children.length-1; i >= 0; i--) {
323                             JavaNode child= (JavaNode) children[i];
324                             switch (child.getTypeCode()) {
325                             case JavaNode.CLASS:
326                             case JavaNode.IMPORT_CONTAINER:
327                             case JavaNode.PACKAGE:
328                             case JavaNode.FIELD:
329                                 p= child.getRange();
330                                 return p.getOffset() + p.getLength();
331                             }
332                         }
333                     }
334                     return javaContainer.getAppendPosition().getOffset();
335                     
336                 case JavaNode.METHOD:
337                     // append in next line after last child
338
children= javaContainer.getChildren();
339                     if (children.length > 0) {
340                         JavaNode child= (JavaNode) children[children.length-1];
341                         p= child.getRange();
342                         return findEndOfLine(javaContainer, p.getOffset() + p.getLength());
343                     }
344                     // otherwise use position from parser
345
return javaContainer.getAppendPosition().getOffset();
346                     
347                 case JavaNode.FIELD:
348                     // append after last field
349
children= javaContainer.getChildren();
350                     if (children.length > 0) {
351                         JavaNode method= null;
352                         for (int i= children.length-1; i >= 0; i--) {
353                             JavaNode child= (JavaNode) children[i];
354                             switch (child.getTypeCode()) {
355                             case JavaNode.METHOD:
356                                 method= child;
357                                 break;
358                             case JavaNode.FIELD:
359                                 p= child.getRange();
360                                 return p.getOffset() + p.getLength();
361                             }
362                         }
363                         if (method != null)
364                             return method.getRange().getOffset();
365                     }
366                     return javaContainer.getAppendPosition().getOffset();
367                 }
368             }
369             
370             if (javaContainer != null) {
371                 // return end of container
372
Position p= javaContainer.getRange();
373                 return p.getOffset() + p.getLength();
374             }
375         }
376
377         // we give up
378
return 0;
379     }
380     
381     private int findEndOfLine(JavaNode container, int pos) {
382         int line;
383         IDocument doc= container.getDocument();
384         try {
385             line= doc.getLineOfOffset(pos);
386             pos= doc.getLineOffset(line+1);
387         } catch (BadLocationException ex) {
388             // silently ignored
389
}
390         
391         // ensure that position is within container range
392
Position containerRange= container.getRange();
393         int start= containerRange.getOffset();
394         int end= containerRange.getOffset() + containerRange.getLength();
395         if (pos < start)
396             return start;
397         if (pos >= end)
398             return end-1;
399         
400         return pos;
401     }
402
403     private void setPreferenceStore(IPreferenceStore ps) {
404         if (fPreferenceChangeListener != null) {
405             if (fPreferenceStore != null)
406                 fPreferenceStore.removePropertyChangeListener(fPreferenceChangeListener);
407             fPreferenceChangeListener= null;
408         }
409         fPreferenceStore= ps;
410         if (fPreferenceStore != null) {
411             JavaTextTools tools= JavaCompareUtilities.getJavaTextTools();
412             fSourceViewerConfiguration= new JavaSourceViewerConfiguration(tools.getColorManager(), fPreferenceStore, null, getDocumentPartitioning());
413             fPreferenceChangeListener= new IPropertyChangeListener() {
414                 public void propertyChange(PropertyChangeEvent event) {
415                     handlePropertyChange(event);
416                 }
417             };
418             fPreferenceStore.addPropertyChangeListener(fPreferenceChangeListener);
419         }
420     }
421 }
422
Popular Tags