KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > eclipse > core > internal > resources > File


1 /*******************************************************************************
2  * Copyright (c) 2000, 2006 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.core.internal.resources;
12
13 import java.io.*;
14 import org.eclipse.core.filesystem.*;
15 import org.eclipse.core.internal.preferences.EclipsePreferences;
16 import org.eclipse.core.internal.utils.*;
17 import org.eclipse.core.resources.*;
18 import org.eclipse.core.runtime.*;
19 import org.eclipse.core.runtime.content.IContentDescription;
20 import org.eclipse.core.runtime.content.IContentTypeManager;
21 import org.eclipse.core.runtime.jobs.ISchedulingRule;
22 import org.eclipse.osgi.util.NLS;
23
24 public class File extends Resource implements IFile {
25
26     protected File(IPath path, Workspace container) {
27         super(path, container);
28     }
29
30     /* (non-Javadoc)
31      * @see IFile#appendContents(InputStream, int, IProgressMonitor)
32      */

33     public void appendContents(InputStream content, int updateFlags, IProgressMonitor monitor) throws CoreException {
34         monitor = Policy.monitorFor(monitor);
35         try {
36             String JavaDoc message = NLS.bind(Messages.resources_settingContents, getFullPath());
37             monitor.beginTask(message, Policy.totalWork);
38             Assert.isNotNull(content, "Content cannot be null."); //$NON-NLS-1$
39
if (workspace.shouldValidate)
40                 workspace.validateSave(this);
41             final ISchedulingRule rule = workspace.getRuleFactory().modifyRule(this);
42             try {
43                 workspace.prepareOperation(rule, monitor);
44                 ResourceInfo info = getResourceInfo(false, false);
45                 checkAccessible(getFlags(info));
46                 workspace.beginOperation(true);
47                 IFileInfo fileInfo = getStore().fetchInfo();
48                 internalSetContents(content, fileInfo, updateFlags, true, Policy.subMonitorFor(monitor, Policy.opWork));
49             } catch (OperationCanceledException e) {
50                 workspace.getWorkManager().operationCanceled();
51                 throw e;
52             } finally {
53                 workspace.endOperation(rule, true, Policy.subMonitorFor(monitor, Policy.endOpWork));
54             }
55         } finally {
56             monitor.done();
57         }
58     }
59
60     /* (non-Javadoc)
61      * @see IFile#appendContents(InputStream, boolean, boolean, IProgressMonitor)
62      */

63     public void appendContents(InputStream content, boolean force, boolean keepHistory, IProgressMonitor monitor) throws CoreException {
64         // funnel all operations to central method
65
int updateFlags = force ? IResource.FORCE : IResource.NONE;
66         updateFlags |= keepHistory ? IResource.KEEP_HISTORY : IResource.NONE;
67         appendContents(content, updateFlags, monitor);
68     }
69
70     /**
71      * Changes this file to be a folder in the resource tree and returns
72      * the newly created folder. All related
73      * properties are deleted. It is assumed that on disk the resource is
74      * already a folder/directory so no action is taken to delete the disk
75      * contents.
76      * <p>
77      * <b>This method is for the exclusive use of the local resource manager</b>
78      */

79     public IFolder changeToFolder() throws CoreException {
80         getPropertyManager().deleteProperties(this, IResource.DEPTH_ZERO);
81         IFolder result = workspace.getRoot().getFolder(path);
82         if (isLinked()) {
83             IPath location = getRawLocation();
84             delete(IResource.NONE, null);
85             result.createLink(location, IResource.ALLOW_MISSING_LOCAL, null);
86         } else {
87             workspace.deleteResource(this);
88             workspace.createResource(result, false);
89         }
90         return result;
91     }
92
93     /* (non-Javadoc)
94      * @see IFile#create(InputStream, int, IProgressMonitor)
95      */

96     public void create(InputStream content, int updateFlags, IProgressMonitor monitor) throws CoreException {
97         final boolean monitorNull = monitor == null;
98         monitor = Policy.monitorFor(monitor);
99         try {
100             String JavaDoc message = monitorNull ? "" : NLS.bind(Messages.resources_creating, getFullPath()); //$NON-NLS-1$
101
monitor.beginTask(message, Policy.totalWork);
102             checkValidPath(path, FILE, true);
103             final ISchedulingRule rule = workspace.getRuleFactory().createRule(this);
104             try {
105                 workspace.prepareOperation(rule, monitor);
106                 checkDoesNotExist();
107                 Container parent = (Container) getParent();
108                 ResourceInfo info = parent.getResourceInfo(false, false);
109                 parent.checkAccessible(getFlags(info));
110
111                 workspace.beginOperation(true);
112                 IFileStore store = getStore();
113                 IFileInfo localInfo = store.fetchInfo();
114                 if (BitMask.isSet(updateFlags, IResource.FORCE)) {
115                     if (!Workspace.caseSensitive) {
116                         if (localInfo.exists()) {
117                             String JavaDoc name = getLocalManager().getLocalName(store);
118                             if (name == null || localInfo.getName().equals(name)) {
119                                 delete(true, null);
120                             } else {
121                                 // The file system is not case sensitive and there is already a file
122
// under this location.
123
message = NLS.bind(Messages.resources_existsLocalDifferentCase, new Path(store.toString()).removeLastSegments(1).append(name).toOSString());
124                                 throw new ResourceException(IResourceStatus.CASE_VARIANT_EXISTS, getFullPath(), message, null);
125                             }
126                         }
127                     }
128                 } else {
129                     if (localInfo.exists()) {
130                         //return an appropriate error message for case variant collisions
131
if (!Workspace.caseSensitive) {
132                             String JavaDoc name = getLocalManager().getLocalName(store);
133                             if (name != null && !localInfo.getName().equals(name)) {
134                                 message = NLS.bind(Messages.resources_existsLocalDifferentCase, new Path(store.toString()).removeLastSegments(1).append(name).toOSString());
135                                 throw new ResourceException(IResourceStatus.CASE_VARIANT_EXISTS, getFullPath(), message, null);
136                             }
137                         }
138                         message = NLS.bind(Messages.resources_fileExists, store.toString());
139                         throw new ResourceException(IResourceStatus.FAILED_WRITE_LOCAL, getFullPath(), message, null);
140                     }
141                 }
142                 monitor.worked(Policy.opWork * 40 / 100);
143
144                 info = workspace.createResource(this, updateFlags);
145                 boolean local = content != null;
146                 if (local) {
147                     try {
148                         internalSetContents(content, localInfo, updateFlags, false, Policy.subMonitorFor(monitor, Policy.opWork * 60 / 100));
149                     } catch (CoreException e) {
150                         // a problem happened creating the file on disk, so delete from the workspace and disk
151
workspace.deleteResource(this);
152                         store.delete(EFS.NONE, null);
153                         throw e; // rethrow
154
}
155                 }
156                 internalSetLocal(local, DEPTH_ZERO);
157                 if (!local)
158                     getResourceInfo(true, true).clearModificationStamp();
159             } catch (OperationCanceledException e) {
160                 workspace.getWorkManager().operationCanceled();
161                 throw e;
162             } finally {
163                 workspace.endOperation(rule, true, Policy.subMonitorFor(monitor, Policy.endOpWork));
164             }
165         } finally {
166             monitor.done();
167             ensureClosed(content);
168         }
169     }
170
171     /* (non-Javadoc)
172      * @see IFile#create(InputStream, boolean, IProgressMonitor)
173      */

174     public void create(InputStream content, boolean force, IProgressMonitor monitor) throws CoreException {
175         // funnel all operations to central method
176
create(content, (force ? IResource.FORCE : IResource.NONE), monitor);
177     }
178
179     /**
180      * IFile API methods require that the stream be closed regardless
181      * of the success of the method. This method makes a best effort
182      * at closing the stream, and ignores any resulting IOException.
183      */

184     protected void ensureClosed(InputStream stream) {
185         if (stream != null) {
186             try {
187                 stream.close();
188             } catch (IOException e) {
189                 // ignore
190
}
191         }
192     }
193
194     /* (non-Javadoc)
195      * @see IFile#getCharset()
196      */

197     public String JavaDoc getCharset() throws CoreException {
198         return getCharset(true);
199     }
200
201     /* (non-Javadoc)
202      * @see IFile#getCharset(boolean)
203      */

204     public String JavaDoc getCharset(boolean checkImplicit) throws CoreException {
205         // non-existing resources default to parent's charset
206
ResourceInfo info = getResourceInfo(false, false);
207         int flags = getFlags(info);
208         if (!exists(flags, false))
209             return checkImplicit ? workspace.getCharsetManager().getCharsetFor(getFullPath().removeLastSegments(1), true) : null;
210         checkLocal(flags, DEPTH_ZERO);
211         return internalGetCharset(checkImplicit, info);
212     }
213
214     /* (non-Javadoc)
215      * @see IFile#getCharsetFor(Reader)
216      */

217     public String JavaDoc getCharsetFor(Reader contents) throws CoreException {
218         String JavaDoc charset;
219         ResourceInfo info = getResourceInfo(false, false);
220         int flags = getFlags(info);
221         if (exists(flags, true))
222             // the file exists, look for user setting
223
if ((charset = workspace.getCharsetManager().getCharsetFor(getFullPath(), false)) != null)
224                 // if there is a file-specific user setting, use it
225
return charset;
226         // tries to obtain a description from the contents provided
227
IContentDescription description;
228         try {
229             // TODO need to take project specific settings into account
230
IContentTypeManager contentTypeManager = Platform.getContentTypeManager();
231             description = contentTypeManager.getDescriptionFor(contents, getName(), new QualifiedName[] {IContentDescription.CHARSET});
232         } catch (IOException e) {
233             String JavaDoc message = NLS.bind(Messages.resources_errorContentDescription, getFullPath());
234             throw new ResourceException(IResourceStatus.FAILED_DESCRIBING_CONTENTS, getFullPath(), message, e);
235         }
236         if (description != null)
237             if ((charset = description.getCharset()) != null)
238                 // the description contained charset info, we are done
239
return charset;
240         // could not find out the encoding based on the contents... default to parent's
241
return workspace.getCharsetManager().getCharsetFor(getFullPath().removeLastSegments(1), true);
242     }
243
244     private String JavaDoc internalGetCharset(boolean checkImplicit, ResourceInfo info) throws CoreException {
245         // if there is a file-specific user setting, use it
246
String JavaDoc charset = workspace.getCharsetManager().getCharsetFor(getFullPath(), false);
247         if (charset != null || !checkImplicit)
248             return charset;
249         // tries to obtain a description for the file contents
250
IContentDescription description = workspace.getContentDescriptionManager().getDescriptionFor(this, info);
251         if (description != null) {
252             String JavaDoc contentCharset = description.getCharset();
253             if (contentCharset != null)
254                 return contentCharset;
255         }
256         // could not find out the encoding based on the contents... default to parent's
257
return workspace.getCharsetManager().getCharsetFor(getFullPath().removeLastSegments(1), true);
258     }
259
260     /*
261      * (non-Javadoc)
262      * @see org.eclipse.core.resources.IFile#getContentDescription()
263      */

264     public IContentDescription getContentDescription() throws CoreException {
265         ResourceInfo info = getResourceInfo(false, false);
266         int flags = getFlags(info);
267         checkAccessible(flags);
268         checkLocal(flags, DEPTH_ZERO);
269         return workspace.getContentDescriptionManager().getDescriptionFor(this, info);
270     }
271
272     /* (non-Javadoc)
273      * @see IFile#getContents()
274      */

275     public InputStream getContents() throws CoreException {
276         return getContents(false);
277     }
278
279     /* (non-Javadoc)
280      * @see IFile#getContents(boolean)
281      */

282     public InputStream getContents(boolean force) throws CoreException {
283         ResourceInfo info = getResourceInfo(false, false);
284         int flags = getFlags(info);
285         checkAccessible(flags);
286         checkLocal(flags, DEPTH_ZERO);
287         return getLocalManager().read(this, force, null);
288     }
289
290     /**
291      * @see IFile#getEncoding()
292      * @deprecated
293      */

294     public int getEncoding() throws CoreException {
295         ResourceInfo info = getResourceInfo(false, false);
296         int flags = getFlags(info);
297         checkAccessible(flags);
298         checkLocal(flags, DEPTH_ZERO);
299         return getLocalManager().getEncoding(this);
300     }
301
302     /* (non-Javadoc)
303      * @see IFile#getHistory(IProgressMonitor)
304      */

305     public IFileState[] getHistory(IProgressMonitor monitor) {
306         return getLocalManager().getHistoryStore().getStates(getFullPath(), monitor);
307     }
308
309     /* (non-Javadoc)
310      * @see IResource#getType()
311      */

312     public int getType() {
313         return FILE;
314     }
315
316     protected void internalSetContents(InputStream content, IFileInfo fileInfo, int updateFlags, boolean append, IProgressMonitor monitor) throws CoreException {
317         if (content == null)
318             content = new ByteArrayInputStream(new byte[0]);
319         getLocalManager().write(this, content, fileInfo, updateFlags, append, monitor);
320         updateMetadataFiles();
321         workspace.getAliasManager().updateAliases(this, getStore(), IResource.DEPTH_ZERO, monitor);
322     }
323
324     /**
325      * Optimized refreshLocal for files. This implementation does not block the workspace
326      * for the common case where the file exists both locally and on the file system, and
327      * is in sync. For all other cases, it defers to the super implementation.
328      */

329     public void refreshLocal(int depth, IProgressMonitor monitor) throws CoreException {
330         if (!getLocalManager().fastIsSynchronized(this))
331             super.refreshLocal(IResource.DEPTH_ZERO, monitor);
332     }
333
334     /* (non-Javadoc)
335      * @see IFile#setContents(IFileState, int, IProgressMonitor)
336      */

337     public void setContents(IFileState content, int updateFlags, IProgressMonitor monitor) throws CoreException {
338         setContents(content.getContents(), updateFlags, monitor);
339     }
340
341     /* (non-Javadoc)
342      * @see IFile#setContents(InputStream, int, IProgressMonitor)
343      */

344     public void setContents(InputStream content, int updateFlags, IProgressMonitor monitor) throws CoreException {
345         monitor = Policy.monitorFor(monitor);
346         try {
347             String JavaDoc message = NLS.bind(Messages.resources_settingContents, getFullPath());
348             monitor.beginTask(message, Policy.totalWork);
349             if (workspace.shouldValidate)
350                 workspace.validateSave(this);
351             final ISchedulingRule rule = workspace.getRuleFactory().modifyRule(this);
352             try {
353                 workspace.prepareOperation(rule, monitor);
354                 ResourceInfo info = getResourceInfo(false, false);
355                 checkAccessible(getFlags(info));
356                 workspace.beginOperation(true);
357                 IFileInfo fileInfo = getStore().fetchInfo();
358                 internalSetContents(content, fileInfo, updateFlags, false, Policy.subMonitorFor(monitor, Policy.opWork));
359             } catch (OperationCanceledException e) {
360                 workspace.getWorkManager().operationCanceled();
361                 throw e;
362             } finally {
363                 workspace.endOperation(rule, true, Policy.subMonitorFor(monitor, Policy.endOpWork));
364             }
365         } finally {
366             monitor.done();
367             ensureClosed(content);
368         }
369     }
370
371     /* (non-Javadoc)
372      * @see IResource#setLocalTimeStamp(long)
373      */

374     public long setLocalTimeStamp(long value) throws CoreException {
375         //override to handle changing timestamp on project description file
376
long result = super.setLocalTimeStamp(value);
377         if (path.segmentCount() == 2 && path.segment(1).equals(IProjectDescription.DESCRIPTION_FILE_NAME)) {
378             //handle concurrent project deletion
379
ResourceInfo projectInfo = ((Project) getProject()).getResourceInfo(false, false);
380             if (projectInfo != null)
381                 getLocalManager().updateLocalSync(projectInfo, result);
382         }
383         return result;
384     }
385
386     /**
387      * Treat the file specially if it represents a metadata file, which includes:
388      * - project description file (.project)
389      * - project preferences files (*.prefs)
390      *
391      * This method is called whenever it is discovered that a file has
392      * been modified (added, removed, or changed).
393      */

394     public void updateMetadataFiles() throws CoreException {
395         int count = path.segmentCount();
396         String JavaDoc name = path.segment(1);
397         // is this a project description file?
398
if (count == 2 && name.equals(IProjectDescription.DESCRIPTION_FILE_NAME)) {
399             ((Project) getProject()).updateDescription();
400             return;
401         }
402         // check to see if we are in the .settings directory
403
if (count == 3 && EclipsePreferences.DEFAULT_PREFERENCES_DIRNAME.equals(name)) {
404             ProjectPreferences.updatePreferences(this);
405             return;
406         }
407     }
408
409     /** (non-Javadoc)
410      * @see IFile#setCharset(String)
411      * @deprecated Replaced by {@link #setCharset(String, IProgressMonitor)} which
412      * is a workspace operation and reports changes in resource deltas.
413      */

414     public void setCharset(String JavaDoc newCharset) throws CoreException {
415         ResourceInfo info = getResourceInfo(false, false);
416         checkAccessible(getFlags(info));
417         workspace.getCharsetManager().setCharsetFor(getFullPath(), newCharset);
418     }
419
420     /* (non-Javadoc)
421      * @see IFile#setCharset(String, IProgressMonitor)
422      */

423     public void setCharset(String JavaDoc newCharset, IProgressMonitor monitor) throws CoreException {
424         monitor = Policy.monitorFor(monitor);
425         try {
426             String JavaDoc message = NLS.bind(Messages.resources_settingCharset, getFullPath());
427             monitor.beginTask(message, Policy.totalWork);
428             // need to get the project as a scheduling rule because we might be creating a new folder/file to
429
// hold the project settings
430
final ISchedulingRule rule = workspace.getRuleFactory().charsetRule(this);
431             try {
432                 workspace.prepareOperation(rule, monitor);
433                 ResourceInfo info = getResourceInfo(false, false);
434                 checkAccessible(getFlags(info));
435                 workspace.beginOperation(true);
436                 workspace.getCharsetManager().setCharsetFor(getFullPath(), newCharset);
437                 info = getResourceInfo(false, true);
438                 info.incrementCharsetGenerationCount();
439                 monitor.worked(Policy.opWork);
440             } catch (OperationCanceledException e) {
441                 workspace.getWorkManager().operationCanceled();
442                 throw e;
443             } finally {
444                 workspace.endOperation(rule, true, Policy.subMonitorFor(monitor, Policy.endOpWork));
445             }
446         } finally {
447             monitor.done();
448         }
449     }
450
451     /* (non-Javadoc)
452      * @see IFile#setContents(InputStream, boolean, boolean, IProgressMonitor)
453      */

454     public void setContents(InputStream content, boolean force, boolean keepHistory, IProgressMonitor monitor) throws CoreException {
455         // funnel all operations to central method
456
int updateFlags = force ? IResource.FORCE : IResource.NONE;
457         updateFlags |= keepHistory ? IResource.KEEP_HISTORY : IResource.NONE;
458         setContents(content, updateFlags, monitor);
459     }
460
461     /* (non-Javadoc)
462      * @see IFile#setContents(IFileState, boolean, boolean, IProgressMonitor)
463      */

464     public void setContents(IFileState source, boolean force, boolean keepHistory, IProgressMonitor monitor) throws CoreException {
465         // funnel all operations to central method
466
int updateFlags = force ? IResource.FORCE : IResource.NONE;
467         updateFlags |= keepHistory ? IResource.KEEP_HISTORY : IResource.NONE;
468         setContents(source.getContents(), updateFlags, monitor);
469     }
470 }
471
Popular Tags