KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > eclipse > ltk > internal > core > refactoring > MultiStateUndoChange


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.ltk.internal.core.refactoring;
12
13 import java.util.LinkedList JavaDoc;
14
15 import org.eclipse.text.edits.TextEdit;
16 import org.eclipse.text.edits.UndoEdit;
17
18 import org.eclipse.core.runtime.Assert;
19 import org.eclipse.core.runtime.CoreException;
20 import org.eclipse.core.runtime.IProgressMonitor;
21 import org.eclipse.core.runtime.NullProgressMonitor;
22 import org.eclipse.core.runtime.SubProgressMonitor;
23
24 import org.eclipse.core.filebuffers.FileBuffers;
25 import org.eclipse.core.filebuffers.ITextFileBuffer;
26 import org.eclipse.core.filebuffers.ITextFileBufferManager;
27 import org.eclipse.core.filebuffers.LocationKind;
28
29 import org.eclipse.core.resources.IFile;
30
31 import org.eclipse.jface.text.BadLocationException;
32 import org.eclipse.jface.text.IDocument;
33
34 import org.eclipse.ltk.core.refactoring.Change;
35 import org.eclipse.ltk.core.refactoring.ContentStamp;
36 import org.eclipse.ltk.core.refactoring.NullChange;
37 import org.eclipse.ltk.core.refactoring.RefactoringStatus;
38 import org.eclipse.ltk.core.refactoring.TextFileChange;
39
40 /**
41  * A change to perform the reverse change of a {@link org.eclipse.ltk.core.refactoring.MultiStateTextFileChange}.
42  * <p>
43  * This class is not intended to be instantiated by clients. It is usually
44  * created by a <code>MultiStateTextFileChange</code> object.
45  * </p>
46  * <p>
47  * The class should be subclassed by clients also subclassing <code>
48  * MultiStateTextFileChange</code>
49  * to provide a proper undo change object.
50  * </p>
51  *
52  * @since 3.2
53  */

54 public class MultiStateUndoChange extends Change {
55
56     private ContentStamp fContentStampToRestore;
57
58     private boolean fDirty;
59
60     private IFile fFile;
61
62     private String JavaDoc fName;
63
64     private int fSaveMode;
65
66     private UndoEdit[] fUndos;
67
68     private BufferValidationState fValidationState;
69
70     /**
71      * Create a new multi state undo change object.
72      *
73      * @param name
74      * the human readable name of the change
75      * @param file
76      * the file the change is working on
77      * @param stamp
78      * the content stamp to restore when the undo is executed
79      * @param undos
80      * the edit representing the undo modifications
81      * @param saveMode
82      * the save mode as specified by {@link TextFileChange}
83      *
84      * @see TextFileChange#KEEP_SAVE_STATE
85      * @see TextFileChange#FORCE_SAVE
86      * @see TextFileChange#LEAVE_DIRTY
87      */

88     public MultiStateUndoChange(String JavaDoc name, IFile file, UndoEdit[] undos, ContentStamp stamp, int saveMode) {
89         Assert.isNotNull(name);
90         Assert.isNotNull(file);
91         Assert.isNotNull(undos);
92         fName= name;
93         fFile= file;
94         fUndos= undos;
95         fContentStampToRestore= stamp;
96         fSaveMode= saveMode;
97     }
98
99     /**
100      * Hook to create an undo change for the given undo edit. This hook gets
101      * called while performing the change to construct the corresponding undo
102      * change object.
103      * <p>
104      * Subclasses may override it to create a different undo change.
105      * </p>
106      *
107      * @param edits
108      * the {@link UndoEdit undo edit} to create a undo change for
109      * @param stampToRestore
110      * the content stamp to restore when the undo edit is executed.
111      *
112      * @return the undo change
113      *
114      * @throws CoreException
115      * if an undo change can't be created
116      */

117     protected Change createUndoChange(UndoEdit[] edits, ContentStamp stampToRestore) throws CoreException {
118         return new MultiStateUndoChange(getName(), fFile, edits, stampToRestore, fSaveMode);
119     }
120
121     /**
122      * {@inheritDoc}
123      */

124     public void dispose() {
125         fValidationState.dispose();
126     }
127
128     /**
129      * {@inheritDoc}
130      */

131     public final Object JavaDoc[] getAffectedObjects() {
132         Object JavaDoc modifiedElement= getModifiedElement();
133         if (modifiedElement == null)
134             return null;
135         return new Object JavaDoc[] { modifiedElement};
136     }
137
138     /**
139      * {@inheritDoc}
140      */

141     public final Object JavaDoc getModifiedElement() {
142         return fFile;
143     }
144
145     /**
146      * {@inheritDoc}
147      */

148     public final String JavaDoc getName() {
149         return fName;
150     }
151
152     /**
153      * Returns the change's save mode.
154      *
155      * @return the change's save mode
156      *
157      * @see TextFileChange#KEEP_SAVE_STATE
158      * @see TextFileChange#FORCE_SAVE
159      * @see TextFileChange#LEAVE_DIRTY
160      */

161     public final int getSaveMode() {
162         return fSaveMode;
163     }
164
165     /**
166      * {@inheritDoc}
167      */

168     public void initializeValidationData(IProgressMonitor pm) {
169         if (pm == null)
170             pm= new NullProgressMonitor();
171         pm.beginTask("", 1); //$NON-NLS-1$
172
fValidationState= BufferValidationState.create(fFile);
173         pm.worked(1);
174     }
175
176     /**
177      * {@inheritDoc}
178      */

179     public RefactoringStatus isValid(IProgressMonitor pm) throws CoreException {
180         if (pm == null)
181             pm= new NullProgressMonitor();
182         pm.beginTask("", 1); //$NON-NLS-1$
183
ITextFileBuffer buffer= FileBuffers.getTextFileBufferManager().getTextFileBuffer(fFile.getFullPath(), LocationKind.IFILE);
184         fDirty= buffer != null && buffer.isDirty();
185         RefactoringStatus result= fValidationState.isValid(needsSaving(), true);
186         pm.worked(1);
187         return result;
188     }
189
190     public final boolean needsSaving() {
191         return (fSaveMode & TextFileChange.FORCE_SAVE) != 0 || (!fDirty && (fSaveMode & TextFileChange.KEEP_SAVE_STATE) != 0);
192     }
193
194     /**
195      * {@inheritDoc}
196      */

197     public Change perform(IProgressMonitor pm) throws CoreException {
198         if (fValidationState.isValid(needsSaving(), false).hasFatalError())
199             return new NullChange();
200         if (pm == null)
201             pm= new NullProgressMonitor();
202         ITextFileBufferManager manager= FileBuffers.getTextFileBufferManager();
203         pm.beginTask("", 2); //$NON-NLS-1$
204
ITextFileBuffer buffer= null;
205         try {
206             manager.connect(fFile.getFullPath(), LocationKind.IFILE, new SubProgressMonitor(pm, 1));
207             buffer= manager.getTextFileBuffer(fFile.getFullPath(), LocationKind.IFILE);
208             IDocument document= buffer.getDocument();
209             ContentStamp currentStamp= ContentStamps.get(fFile, document);
210             // perform the changes
211
LinkedList JavaDoc list= new LinkedList JavaDoc();
212             for (int index= 0; index < fUndos.length; index++) {
213                 UndoEdit edit= fUndos[index];
214                 UndoEdit redo= edit.apply(document, TextEdit.CREATE_UNDO);
215                 list.addFirst(redo);
216
217             }
218
219             // try to restore the document content stamp
220
boolean success= ContentStamps.set(document, fContentStampToRestore);
221             if (needsSaving()) {
222                 buffer.commit(pm, false);
223                 if (!success) {
224                     // We weren't able to restore document stamp.
225
// Since we save restore the file stamp instead
226
ContentStamps.set(fFile, fContentStampToRestore);
227                 }
228             }
229             return createUndoChange((UndoEdit[]) list.toArray(new UndoEdit[list.size()]), currentStamp);
230         } catch (BadLocationException e) {
231             throw Changes.asCoreException(e);
232         } finally {
233             if (buffer != null)
234                 manager.disconnect(fFile.getFullPath(), LocationKind.IFILE, new SubProgressMonitor(pm, 1));
235         }
236     }
237 }
238
Popular Tags