KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > eclipse > ltk > core > refactoring > UndoTextFileChange


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

49 public class UndoTextFileChange extends Change {
50     
51     private String JavaDoc fName;
52     private UndoEdit fUndo;
53     private IFile fFile;
54     private ContentStamp fContentStampToRestore;
55     private int fSaveMode;
56     
57     private boolean fDirty;
58     private BufferValidationState fValidationState;
59     
60     /**
61      * Create a new undo text file change object.
62      *
63      * @param name the human readable name of the change
64      * @param file the file the change is working on
65      * @param stamp the content stamp to restore when the undo is executed
66      * @param undo the edit representing the undo modifications
67      * @param saveMode the save mode as specified by {@link TextFileChange}
68      *
69      * @see TextFileChange#KEEP_SAVE_STATE
70      * @see TextFileChange#FORCE_SAVE
71      * @see TextFileChange#LEAVE_DIRTY
72      */

73     protected UndoTextFileChange(String JavaDoc name, IFile file, UndoEdit undo, ContentStamp stamp, int saveMode) {
74         Assert.isNotNull(name);
75         Assert.isNotNull(file);
76         Assert.isNotNull(undo);
77         fName= name;
78         fFile= file;
79         fUndo= undo;
80         fContentStampToRestore= stamp;
81         fSaveMode= saveMode;
82     }
83     
84     /**
85      * Returns the change's save mode.
86      *
87      * @return the change's save mode
88      *
89      * @see TextFileChange#KEEP_SAVE_STATE
90      * @see TextFileChange#FORCE_SAVE
91      * @see TextFileChange#LEAVE_DIRTY
92      */

93     public int getSaveMode() {
94         return fSaveMode;
95     }
96     
97     /**
98      * {@inheritDoc}
99      */

100     public String JavaDoc getName() {
101         return fName;
102     }
103     
104     /**
105      * Hook to create an undo change for the given undo edit. This hook
106      * gets called while performing the change to construct the corresponding
107      * undo change object.
108      * <p>
109      * Subclasses may override it to create a different undo change.
110      * </p>
111      * @param edit the {@link UndoEdit undo edit} to create a undo change for
112      * @param stampToRestore the content stamp to restore when the undo
113      * edit is executed.
114      *
115      * @return the undo change
116      *
117      * @throws CoreException if an undo change can't be created
118      */

119     protected Change createUndoChange(UndoEdit edit, ContentStamp stampToRestore) throws CoreException {
120         return new UndoTextFileChange(getName(), fFile, edit, stampToRestore, fSaveMode);
121     }
122     
123     /**
124      * {@inheritDoc}
125      */

126     public Object JavaDoc getModifiedElement() {
127         return fFile;
128     }
129     
130     /**
131      * {@inheritDoc}
132      */

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

143     public void initializeValidationData(IProgressMonitor pm) {
144         if (pm == null)
145             pm= new NullProgressMonitor();
146         pm.beginTask("", 1); //$NON-NLS-1$
147
fValidationState= BufferValidationState.create(fFile);
148         pm.worked(1);
149     }
150     
151     /**
152      * {@inheritDoc}
153      */

154     public RefactoringStatus isValid(IProgressMonitor pm) throws CoreException {
155         if (pm == null)
156             pm= new NullProgressMonitor();
157         pm.beginTask("", 1); //$NON-NLS-1$
158
ITextFileBuffer buffer= FileBuffers.getTextFileBufferManager().getTextFileBuffer(fFile.getFullPath(), LocationKind.IFILE);
159         fDirty= buffer != null && buffer.isDirty();
160         RefactoringStatus result= fValidationState.isValid(needsSaving(), true);
161         pm.worked(1);
162         return result;
163     }
164     
165     /**
166      * {@inheritDoc}
167      */

168     public Change perform(IProgressMonitor pm) throws CoreException {
169         if (pm == null)
170             pm= new NullProgressMonitor();
171         ITextFileBufferManager manager= FileBuffers.getTextFileBufferManager();
172         pm.beginTask("", 2); //$NON-NLS-1$
173
ITextFileBuffer buffer= null;
174         try {
175             manager.connect(fFile.getFullPath(), LocationKind.IFILE, new SubProgressMonitor(pm, 1));
176             buffer= manager.getTextFileBuffer(fFile.getFullPath(), LocationKind.IFILE);
177             IDocument document= buffer.getDocument();
178             ContentStamp currentStamp= ContentStamps.get(fFile, document);
179             // perform the changes
180
UndoEdit redo= fUndo.apply(document, TextEdit.CREATE_UNDO);
181             // try to restore the document content stamp
182
boolean success= ContentStamps.set(document, fContentStampToRestore);
183             if (needsSaving()) {
184                 buffer.commit(pm, false);
185                 if (!success) {
186                     // We weren't able to restore document stamp.
187
// Since we save restore the file stamp instead
188
ContentStamps.set(fFile, fContentStampToRestore);
189                 }
190             }
191             return createUndoChange(redo, currentStamp);
192         } catch (BadLocationException e) {
193             if (! fValidationState.wasDerived())
194                 throw Changes.asCoreException(e);
195             else
196                 return new NullChange();
197         } catch (MalformedTreeException e) {
198             if (! fValidationState.wasDerived())
199                 throw Changes.asCoreException(e);
200             else
201                 return new NullChange();
202         } catch (CoreException e) {
203             if (! fValidationState.wasDerived())
204                 throw e;
205             else
206                 return new NullChange();
207         } finally {
208             if (buffer != null)
209                 manager.disconnect(fFile.getFullPath(), LocationKind.IFILE, new SubProgressMonitor(pm, 1));
210         }
211     }
212     
213     /**
214      * {@inheritDoc}
215      */

216     public void dispose() {
217         fValidationState.dispose();
218     }
219     
220     private boolean needsSaving() {
221         return (fSaveMode & TextFileChange.FORCE_SAVE) != 0 || (!fDirty && (fSaveMode & TextFileChange.KEEP_SAVE_STATE) != 0);
222     }
223 }
224
Popular Tags