KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > eclipse > team > internal > ui > synchronize > LocalResourceSaveableComparison


1 /*******************************************************************************
2  * Copyright (c) 2006, 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.team.internal.ui.synchronize;
12
13 import org.eclipse.compare.*;
14 import org.eclipse.compare.internal.Utilities;
15 import org.eclipse.compare.structuremergeviewer.ICompareInput;
16 import org.eclipse.core.resources.IFile;
17 import org.eclipse.core.runtime.*;
18 import org.eclipse.jface.dialogs.IDialogConstants;
19 import org.eclipse.jface.dialogs.MessageDialog;
20 import org.eclipse.jface.resource.ImageDescriptor;
21 import org.eclipse.jface.text.IDocument;
22 import org.eclipse.jface.util.IPropertyChangeListener;
23 import org.eclipse.jface.util.PropertyChangeEvent;
24 import org.eclipse.swt.graphics.Image;
25 import org.eclipse.team.internal.ui.*;
26 import org.eclipse.team.ui.mapping.SaveableComparison;
27 import org.eclipse.ui.IEditorInput;
28 import org.eclipse.ui.Saveable;
29 import org.eclipse.ui.part.FileEditorInput;
30 import org.eclipse.ui.texteditor.IDocumentProvider;
31
32 /**
33  * A saveable that wraps a compare input in which the left side is a {@link LocalResourceTypedElement}
34  * and saves changes made to the file in compare when the viewers are flushed.
35  *
36  * @see LocalResourceTypedElement
37  * @since 3.3
38  */

39 public abstract class LocalResourceSaveableComparison extends SaveableComparison implements IPropertyChangeListener {
40
41     private final ICompareInput input;
42     private final CompareEditorInput editorInput;
43     private boolean isSaving;
44     private IContentChangeListener contentChangeListener;
45     private ITypedElement fileElement;
46     private IDocument document;
47     
48     /**
49      * Create the resource-based saveable comparison.
50      * @param input the compare input to be save
51      * @param editorInput the editor input containing the comparison
52      */

53     public LocalResourceSaveableComparison(ICompareInput input, CompareEditorInput editorInput) {
54         this(input, editorInput, input.getLeft());
55     }
56     
57     /**
58      * Create the resource-based saveable comparison.
59      * @param input the compare input to be save
60      * @param editorInput the editor input containing the comparison
61      * @param fileElement the file element that handles the saving and change notification
62      */

63     public LocalResourceSaveableComparison(ICompareInput input, CompareEditorInput editorInput, ITypedElement fileElement) {
64         this.input = input;
65         this.editorInput = editorInput;
66         this.fileElement = fileElement;
67         initializeContentChangeListeners();
68     }
69     
70     protected void initializeHashing() {
71         Object JavaDoc document= getAdapter(IDocument.class);
72         if (document != null) {
73             this.document = (IDocument)document;
74         }
75     }
76
77     private void initializeContentChangeListeners() {
78         // We need to listen to saves to the input to catch the case
79
// where Save was picked from the context menu
80
ITypedElement te = getFileElement();
81         if (te instanceof IContentChangeNotifier) {
82             if (contentChangeListener == null) {
83                 contentChangeListener = new IContentChangeListener() {
84                     public void contentChanged(IContentChangeNotifier source) {
85                         try {
86                             if(! isSaving) {
87                                 performSave(new NullProgressMonitor());
88                             }
89                         } catch (CoreException e) {
90                             TeamUIPlugin.log(e);
91                         }
92                     }
93                 };
94             }
95             ((IContentChangeNotifier) te).addContentChangeListener(contentChangeListener);
96         }
97     }
98     
99     /**
100      * Dispose of the saveable.
101      */

102     public void dispose() {
103         if (contentChangeListener != null) {
104             ITypedElement te = getFileElement();
105             if (te instanceof IContentChangeNotifier) {
106                 ((IContentChangeNotifier) te).removeContentChangeListener(contentChangeListener);
107             }
108         }
109         // Discard of the left buffer
110
ITypedElement left = getFileElement();
111         if (left instanceof LocalResourceTypedElement)
112              ((LocalResourceTypedElement) left).discardBuffer();
113     }
114
115     private ITypedElement getFileElement() {
116         return fileElement;
117     }
118     
119     /* (non-Javadoc)
120      * @see org.eclipse.team.ui.mapping.SaveableCompareModel#performSave(org.eclipse.core.runtime.IProgressMonitor)
121      */

122     protected void performSave(IProgressMonitor monitor) throws CoreException {
123         if (checkForUpdateConflicts()) {
124             return;
125         }
126         try {
127             isSaving = true;
128             monitor.beginTask(null, 100);
129             // First, we need to flush the viewers so the changes get buffered
130
// in the input
131
flushViewers(Policy.subMonitorFor(monitor, 40));
132             // Then we tell the input to commit its changes
133
// Only the left is ever saveable
134
ITypedElement left = getFileElement();
135             if (left instanceof LocalResourceTypedElement) {
136                 LocalResourceTypedElement te = (LocalResourceTypedElement) left;
137                 te.commit(Policy.subMonitorFor(monitor, 60));
138             }
139         } finally {
140             // Make sure we fire a change for the compare input to update the viewers
141
fireInputChange();
142             setDirty(false);
143             isSaving = false;
144             monitor.done();
145         }
146     }
147
148     /**
149      * Flush the contents of any viewers into the compare input.
150      * @param monitor a progress monitor
151      * @throws CoreException
152      */

153     protected void flushViewers(IProgressMonitor monitor) throws CoreException {
154         editorInput.saveChanges(monitor);
155     }
156
157     /**
158      * Fire an input change for the compare input after it has been
159      * saved.
160      */

161     protected abstract void fireInputChange();
162
163     /**
164      * Check whether there is a conflicting save on the file.
165      * @return <code>true</code> if there was and the user chose to cancel the operation
166      */

167     private boolean checkForUpdateConflicts() {
168         if(hasSaveConflict()) {
169             if (Utilities.RUNNING_TESTS)
170                 return !Utilities.TESTING_FLUSH_ON_COMPARE_INPUT_CHANGE;
171             final MessageDialog dialog =
172                 new MessageDialog(TeamUIPlugin.getStandardDisplay().getActiveShell(),
173                         TeamUIMessages.SyncInfoCompareInput_0,
174                         null,
175                         TeamUIMessages.SyncInfoCompareInput_1,
176                         MessageDialog.QUESTION,
177                     new String JavaDoc[] {
178                         TeamUIMessages.SyncInfoCompareInput_2,
179                         IDialogConstants.CANCEL_LABEL},
180                     0);
181             
182             int retval = dialog.open();
183             switch(retval) {
184                 // save
185
case 0:
186                     return false;
187                 // cancel
188
case 1:
189                     return true;
190             }
191         }
192         return false;
193     }
194
195     private boolean hasSaveConflict() {
196         ITypedElement left = getFileElement();
197         if (left instanceof LocalResourceTypedElement) {
198             LocalResourceTypedElement te = (LocalResourceTypedElement) left;
199             return !te.isSynchronized();
200         }
201         return false;
202     }
203
204     /* (non-Javadoc)
205      * @see org.eclipse.team.ui.mapping.SaveableCompareModel#isDirty()
206      */

207     public boolean isDirty() {
208         // We need to get the dirty state from the compare editor input
209
// since it is our only connection to the merge viewer
210
return editorInput.isSaveNeeded();
211     }
212     
213     /* (non-Javadoc)
214      * @see org.eclipse.team.ui.mapping.SaveableCompareModel#setDirty(boolean)
215      */

216     protected void setDirty(boolean dirty) {
217         // We need to set the dirty state on the compare editor input
218
// since it is our only connection to the merge viewer
219
editorInput.setDirty(dirty);
220     }
221
222     /* (non-Javadoc)
223      * @see org.eclipse.team.ui.mapping.SaveableCompareModel#performRevert(org.eclipse.core.runtime.IProgressMonitor)
224      */

225     protected void performRevert(IProgressMonitor monitor) {
226         // Only the left is ever editable
227
ITypedElement left = getFileElement();
228         if (left instanceof LocalResourceTypedElement)
229              ((LocalResourceTypedElement) left).discardBuffer();
230     }
231
232     /* (non-Javadoc)
233      * @see org.eclipse.ui.Saveable#getName()
234      */

235     public String JavaDoc getName() {
236         return input.getName();
237     }
238
239     /* (non-Javadoc)
240      * @see org.eclipse.ui.Saveable#getToolTipText()
241      */

242     public String JavaDoc getToolTipText() {
243         return editorInput.getToolTipText();
244     }
245
246     /* (non-Javadoc)
247      * @see org.eclipse.ui.Saveable#getImageDescriptor()
248      */

249     public ImageDescriptor getImageDescriptor() {
250         Image image = input.getImage();
251         if (image != null)
252             return ImageDescriptor.createFromImage(image);
253         return TeamUIPlugin.getImageDescriptor(ITeamUIImages.IMG_SYNC_VIEW);
254     }
255
256     /* (non-Javadoc)
257      * @see org.eclipse.jface.util.IPropertyChangeListener#propertyChange(org.eclipse.jface.util.PropertyChangeEvent)
258      */

259     public void propertyChange(PropertyChangeEvent e) {
260         String JavaDoc propertyName= e.getProperty();
261         if (CompareEditorInput.DIRTY_STATE.equals(propertyName)) {
262             boolean changed= false;
263             Object JavaDoc newValue= e.getNewValue();
264             if (newValue instanceof Boolean JavaDoc)
265                 changed= ((Boolean JavaDoc)newValue).booleanValue();
266             setDirty(changed);
267         }
268     }
269     
270     /*
271      * @see org.eclipse.ui.Saveable#hashCode()
272      */

273     public int hashCode() {
274         if (document != null) {
275             return document.hashCode();
276         }
277         return input.hashCode();
278     }
279
280     /*
281      * @see org.eclipse.ui.Saveable#equals(java.lang.Object)
282      */

283     public boolean equals(Object JavaDoc obj) {
284         if (this == obj)
285             return true;
286         
287         if (!(obj instanceof Saveable))
288             return false;
289         
290         if (document != null) {
291             Object JavaDoc otherDocument= ((Saveable)obj).getAdapter(IDocument.class);
292             
293             if (document == null && otherDocument == null)
294                 return false;
295             
296             return document != null && document.equals(otherDocument);
297         }
298         
299         if (obj instanceof LocalResourceSaveableComparison) {
300             LocalResourceSaveableComparison rscm = (LocalResourceSaveableComparison) obj;
301             return rscm.input.equals(input);
302         }
303         return false;
304     }
305     
306     public Object JavaDoc getAdapter(Class JavaDoc adapter) {
307         if (adapter == IDocument.class) {
308             if (document != null)
309                 return document;
310             if (fileElement instanceof LocalResourceTypedElement) {
311                 LocalResourceTypedElement lrte = (LocalResourceTypedElement) fileElement;
312                 if (lrte.isConnected()) {
313                     ISharedDocumentAdapter sda = (ISharedDocumentAdapter)Utils.getAdapter(lrte, ISharedDocumentAdapter.class);
314                     if (sda != null) {
315                         IEditorInput input = sda.getDocumentKey(lrte);
316                         if (input != null) {
317                             IDocumentProvider provider = SharedDocumentAdapter.getDocumentProvider(input);
318                             if (provider != null)
319                                 return provider.getDocument(input);
320                         }
321                     }
322                 }
323             }
324         }
325         if (adapter == IEditorInput.class) {
326             if (fileElement instanceof LocalResourceTypedElement) {
327                 LocalResourceTypedElement lrte = (LocalResourceTypedElement) fileElement;
328                 return new FileEditorInput((IFile)lrte.getResource());
329             }
330         }
331         return super.getAdapter(adapter);
332     }
333
334     /**
335      * Return the compare input that is managed by this saveable.
336      * @return the compare input that is managed by this saveable
337      */

338     public ICompareInput getInput() {
339         return input;
340     }
341
342     public boolean isConnectedToSharedDocument() {
343         if (fileElement instanceof LocalResourceTypedElement) {
344             LocalResourceTypedElement lrte = (LocalResourceTypedElement) fileElement;
345             return lrte.isConnected();
346         }
347         return false;
348     }
349 }
350
Popular Tags