KickJava   Java API By Example, From Geeks To Geeks.

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


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 org.eclipse.core.runtime.CoreException;
14 import org.eclipse.core.runtime.IPath;
15
16 import org.eclipse.core.filebuffers.FileBuffers;
17 import org.eclipse.core.filebuffers.IFileBuffer;
18 import org.eclipse.core.filebuffers.IFileBufferListener;
19 import org.eclipse.core.filebuffers.ITextFileBuffer;
20 import org.eclipse.core.filebuffers.ITextFileBufferManager;
21 import org.eclipse.core.filebuffers.LocationKind;
22
23 import org.eclipse.core.resources.IFile;
24 import org.eclipse.core.resources.IResource;
25
26 import org.eclipse.jface.text.DocumentEvent;
27 import org.eclipse.jface.text.IDocument;
28 import org.eclipse.jface.text.IDocumentExtension4;
29 import org.eclipse.jface.text.IDocumentListener;
30
31 import org.eclipse.ltk.core.refactoring.RefactoringStatus;
32
33 public abstract class BufferValidationState {
34     
35     protected final IFile fFile;
36     protected final boolean fExisted;
37     protected final boolean fDerived;
38     protected final boolean fWasDirty;
39     protected final String JavaDoc fEncoding;
40
41     protected static class ModificationStamp {
42         private int fKind;
43         private long fValue;
44         public static final int FILE= 1;
45         public static final int DOCUMENT= 2;
46         
47         public static ModificationStamp createFile(long value) {
48             return new ModificationStamp(FILE, value);
49         }
50         public static ModificationStamp createDocument(long value) {
51             return new ModificationStamp(DOCUMENT, value);
52         }
53         private ModificationStamp(int kind, long value) {
54             fKind= kind;
55             fValue= value;
56         }
57         public boolean isFileStamp() {
58             return fKind == FILE;
59         }
60         public boolean isDocumentStamp() {
61             return fKind == DOCUMENT;
62         }
63         public int getKind() {
64             return fKind;
65         }
66         public long getValue() {
67             return fValue;
68         }
69     }
70
71     public static BufferValidationState create(IFile file) {
72         ITextFileBuffer buffer= getBuffer(file);
73         if (buffer == null) {
74             return new ModificationStampValidationState(file);
75         } else {
76             IDocument document= buffer.getDocument();
77             if (document instanceof IDocumentExtension4) {
78                 return new ModificationStampValidationState(file);
79             } else {
80                 if (buffer.isDirty()) {
81                     return new NoStampValidationState(file);
82                 } else {
83                     return new ModificationStampValidationState(file);
84                 }
85             }
86         }
87     }
88     
89     public boolean wasDirty() {
90         return fWasDirty;
91     }
92     
93     public boolean wasDerived() {
94         return fDerived;
95     }
96     
97     public RefactoringStatus isValid(boolean needsSaving) throws CoreException {
98         return isValid(needsSaving, false);
99     }
100     
101     public RefactoringStatus isValid(boolean needsSaving, boolean resilientForDerived) throws CoreException {
102         if (resilientForDerived && fDerived) {
103             return new RefactoringStatus();
104         }
105         if (!fExisted) {
106             if (fFile.exists())
107                 return RefactoringStatus.createFatalErrorStatus(Messages.format(
108                     RefactoringCoreMessages.TextChanges_error_existing,
109                     fFile.getFullPath().toString()));
110         } else {
111             if (!fFile.exists())
112                 return RefactoringStatus.createFatalErrorStatus(Messages.format(
113                     RefactoringCoreMessages.TextChanges_error_not_existing,
114                     fFile.getFullPath().toString()));
115         }
116         if (needsSaving) {
117             if (fFile.isReadOnly()) {
118                 return RefactoringStatus.createFatalErrorStatus(Messages.format(
119                     RefactoringCoreMessages.TextChanges_error_read_only,
120                     fFile.getFullPath().toString()));
121             } else if (!fFile.isSynchronized(IResource.DEPTH_ZERO)) {
122                 return RefactoringStatus.createFatalErrorStatus(Messages.format(
123                     RefactoringCoreMessages.TextChanges_error_outOfSync,
124                     fFile.getFullPath().toString()));
125             }
126         }
127         if (fEncoding == null) {
128             return RefactoringStatus.createFatalErrorStatus(Messages.format(
129                 RefactoringCoreMessages.BufferValidationState_no_character_encoding,
130                 fFile.getFullPath().toString()));
131         } else if (!fEncoding.equals(fFile.getCharset(true))) {
132             return RefactoringStatus.createFatalErrorStatus(Messages.format(
133                 RefactoringCoreMessages.BufferValidationState_character_encoding_changed,
134                 fFile.getFullPath().toString()));
135         }
136         return new RefactoringStatus();
137     }
138     
139     public void dispose() {
140     }
141     
142     
143     protected BufferValidationState(IFile file) {
144         fFile= file;
145         fExisted= file.exists();
146         fDerived= file.isDerived();
147         fWasDirty= isDirty(fFile);
148         String JavaDoc encoding;
149         try {
150             encoding= file.getCharset(true);
151         } catch (CoreException e) {
152             encoding= null;
153         }
154         fEncoding= encoding;
155     }
156     
157     protected IDocument getDocument() {
158         ITextFileBuffer buffer= getBuffer(fFile);
159         if (buffer == null)
160             return null;
161         return buffer.getDocument();
162         
163     }
164     
165     protected static boolean isDirty(IFile file) {
166         ITextFileBuffer buffer= getBuffer(file);
167         if (buffer == null)
168             return false;
169         return buffer.isDirty();
170     }
171     
172     protected static ITextFileBuffer getBuffer(IFile file) {
173         ITextFileBufferManager manager= FileBuffers.getTextFileBufferManager();
174         IPath path= file.getFullPath();
175         ITextFileBuffer buffer= manager.getTextFileBuffer(path, LocationKind.IFILE);
176         return buffer;
177     }
178     
179     protected ModificationStamp getModificationStamp() {
180         ITextFileBuffer buffer= getBuffer(fFile);
181         if (buffer == null) {
182             return ModificationStamp.createFile(fFile.getModificationStamp());
183         } else {
184             IDocument document= buffer.getDocument();
185             if (document instanceof IDocumentExtension4) {
186                 return ModificationStamp.createDocument(((IDocumentExtension4)document).getModificationStamp());
187             } else {
188                 return ModificationStamp.createFile(fFile.getModificationStamp());
189             }
190         }
191     }
192 }
193
194 /**
195  * Buffer validation state for dirty files whose document does not support
196  * modification stamps.
197  */

198 class NoStampValidationState extends BufferValidationState {
199     
200     private IDocumentListener fDocumentListener;
201     private FileBufferListener fFileBufferListener;
202     private boolean fChanged;
203     private long fContentStamp= IResource.NULL_STAMP;
204     
205     class DocumentChangedListener implements IDocumentListener {
206         public void documentAboutToBeChanged(DocumentEvent event) {
207         }
208         public void documentChanged(DocumentEvent event) {
209             NoStampValidationState.this.documentChanged();
210         }
211     }
212     
213     class FileBufferListener implements IFileBufferListener {
214         public void bufferCreated(IFileBuffer buffer) {
215             // begin https://bugs.eclipse.org/bugs/show_bug.cgi?id=67821
216
if (buffer.getLocation().equals(fFile.getFullPath()) && buffer instanceof ITextFileBuffer) {
217                 ITextFileBuffer textBuffer= (ITextFileBuffer)buffer;
218                 if (fDocumentListener == null)
219                     fDocumentListener= new DocumentChangedListener();
220                 textBuffer.getDocument().addDocumentListener(fDocumentListener);
221             }
222             // end fix https://bugs.eclipse.org/bugs/show_bug.cgi?id=67821
223
}
224         public void bufferDisposed(IFileBuffer buffer) {
225             // begin fix https://bugs.eclipse.org/bugs/show_bug.cgi?id=67821
226
if (fDocumentListener != null && buffer.getLocation().equals(fFile.getFullPath())) {
227                 if (buffer instanceof ITextFileBuffer) {
228                     ITextFileBuffer textBuffer= (ITextFileBuffer)buffer;
229                     textBuffer.getDocument().removeDocumentListener(fDocumentListener);
230                     fDocumentListener= null;
231                 }
232                 fContentStamp= fFile.getModificationStamp();
233             }
234             // end fix https://bugs.eclipse.org/bugs/show_bug.cgi?id=67821
235
}
236         public void bufferContentAboutToBeReplaced(IFileBuffer buffer) {
237         }
238         public void bufferContentReplaced(IFileBuffer buffer) {
239         }
240         public void stateChanging(IFileBuffer buffer) {
241         }
242         public void dirtyStateChanged(IFileBuffer buffer, boolean isDirty) {
243         }
244         public void stateValidationChanged(IFileBuffer buffer, boolean isStateValidated) {
245         }
246         public void underlyingFileMoved(IFileBuffer buffer, IPath path) {
247         }
248         public void underlyingFileDeleted(IFileBuffer buffer) {
249         }
250         public void stateChangeFailed(IFileBuffer buffer) {
251         }
252     }
253     
254     public NoStampValidationState(IFile file) {
255         super(file);
256         fContentStamp= file.getModificationStamp();
257         fFileBufferListener= new FileBufferListener();
258         FileBuffers.getTextFileBufferManager().addFileBufferListener(fFileBufferListener);
259         fDocumentListener= new DocumentChangedListener();
260         getDocument().addDocumentListener(fDocumentListener);
261     }
262
263     public RefactoringStatus isValid(boolean needsSaving, boolean resilientForDerived) throws CoreException {
264         RefactoringStatus result= super.isValid(needsSaving, resilientForDerived);
265         if (result.hasFatalError())
266             return result;
267         // If we have initialized the content stamp with the null stamp then we can't compare it with
268
// the current stamp since a change executed later could have set a concrete stamp for the
269
// current content
270
// if (fChanged || (fContentStamp != IResource.NULL_STAMP && fContentStamp != fFile.getModificationStamp())
271
if (fChanged || fContentStamp != fFile.getModificationStamp()) {
272             result.addFatalError(Messages.format(
273                 RefactoringCoreMessages.TextChanges_error_content_changed,
274                 fFile.getFullPath().toString()
275                 ));
276         }
277         return result;
278     }
279     
280     public void dispose() {
281         if (fFileBufferListener != null) {
282             FileBuffers.getTextFileBufferManager().removeFileBufferListener(fFileBufferListener);
283             // fix https://bugs.eclipse.org/bugs/show_bug.cgi?id=67821
284
fFileBufferListener= null;
285         }
286         if (fDocumentListener != null) {
287             getDocument().removeDocumentListener(fDocumentListener);
288             // fix https://bugs.eclipse.org/bugs/show_bug.cgi?id=67821
289
fDocumentListener= null;
290         }
291     }
292     
293     private void documentChanged() {
294         fChanged= true;
295         getDocument().removeDocumentListener(fDocumentListener);
296         FileBuffers.getTextFileBufferManager().removeFileBufferListener(fFileBufferListener);
297         fFileBufferListener= null;
298         fDocumentListener= null;
299     }
300 }
301
302 /**
303  * Buffer validation state based on modification stamp.
304  */

305 class ModificationStampValidationState extends BufferValidationState {
306     
307     private ModificationStamp fModificationStamp;
308     
309     public ModificationStampValidationState(IFile file) {
310         super(file);
311         fModificationStamp= getModificationStamp();
312     }
313     
314     public RefactoringStatus isValid(boolean needsSaving, boolean resilientForDerived) throws CoreException {
315         RefactoringStatus result= super.isValid(needsSaving, resilientForDerived);
316         if (result.hasFatalError())
317             return result;
318         ModificationStamp currentStamp= getModificationStamp();
319         // we don't need to check the kind here since the document stamp
320
// and file stamp are in sync for documents implementing
321
// IDocumentExtension4. If both are file stamps the file must
322
// not be dirty
323
if (fModificationStamp.getValue() != currentStamp.getValue()
324             // we know here that the stamp value are equal. However, if
325
// the stamp is a null stamp then the king must be equal as well.
326
|| (fModificationStamp.isFileStamp()
327                 && fModificationStamp.getValue() == IResource.NULL_STAMP
328                 && !currentStamp.isFileStamp())
329             || (fModificationStamp.isDocumentStamp()
330                 && fModificationStamp.getValue() == IDocumentExtension4.UNKNOWN_MODIFICATION_STAMP
331                 && !currentStamp.isDocumentStamp())
332             || (fModificationStamp.isFileStamp()
333                 && currentStamp.isFileStamp() && isDirty(fFile))) {
334             result.addFatalError(Messages.format(
335                 RefactoringCoreMessages.TextChanges_error_content_changed,
336                 fFile.getFullPath().toString()
337                 ));
338             
339         }
340         return result;
341     }
342 }
343
344 /*
345 class SavedBufferValidationState extends BufferValidationState {
346     private long fModificationStamp;
347     
348     public SavedBufferValidationState(IFile file) {
349         super(file);
350         fModificationStamp= file.getModificationStamp();
351     }
352
353     public RefactoringStatus isValid(boolean needsSaving) {
354         RefactoringStatus result= super.isValid(needsSaving);
355         if (result.hasFatalError())
356             return result;
357         ModificationStamp currentStamp= getModificationStamp();
358         if (fModificationStamp != currentStamp.value) {
359             result.addFatalError(Messages.format(
360                 RefactoringCoreMessages.TextChanges_error_content_changed, //$NON-NLS-1$
361                 fFile.getFullPath().toString()
362                 ));
363         } else if (fFile.isReadOnly()) {
364             result.addFatalError(Messages.format(
365                 RefactoringCoreMessages.TextChanges_error_read_only, //$NON-NLS-1$
366                 fFile.getFullPath().toString()
367                 ));
368         } else if (!fFile.isSynchronized(IResource.DEPTH_ZERO)) {
369             result.addFatalError(Messages.format(
370                 RefactoringCoreMessages.TextChanges_error_outOfSync, //$NON-NLS-1$
371                 fFile.getFullPath().toString()
372                 ));
373         } else if (isDirty(fFile) && currentStamp.isFileStamp()){
374             result.addFatalError(Messages.format(
375                 RefactoringCoreMessages.TextChanges_error_unsaved_changes, //$NON-NLS-1$
376                 fFile.getFullPath().toString()
377                 ));
378         }
379         return result;
380     }
381     
382 }
383 */

384
Popular Tags