KickJava   Java API By Example, From Geeks To Geeks.

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


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 java.net.URI JavaDoc;
15 import org.eclipse.core.filesystem.URIUtil;
16 import org.eclipse.core.internal.localstore.SafeChunkyInputStream;
17 import org.eclipse.core.internal.localstore.SafeChunkyOutputStream;
18 import org.eclipse.core.internal.utils.Messages;
19 import org.eclipse.core.internal.utils.Policy;
20 import org.eclipse.core.resources.*;
21 import org.eclipse.core.runtime.*;
22 import org.eclipse.osgi.util.NLS;
23
24 public class LocalMetaArea implements ICoreConstants {
25     /* package */static final String JavaDoc F_BACKUP_FILE_EXTENSION = ".bak"; //$NON-NLS-1$
26
/* package */static final String JavaDoc F_DESCRIPTION = ".workspace"; //$NON-NLS-1$
27

28     /* package */static final String JavaDoc F_HISTORY_STORE = ".history"; //$NON-NLS-1$
29
/* package */static final String JavaDoc F_MARKERS = ".markers"; //$NON-NLS-1$
30
/* package */static final String JavaDoc F_OLD_PROJECT = ".prj"; //$NON-NLS-1$
31
/* package */static final String JavaDoc F_PROJECT_LOCATION = ".location"; //$NON-NLS-1$
32
/* package */static final String JavaDoc F_PROJECTS = ".projects"; //$NON-NLS-1$
33
/* package */static final String JavaDoc F_PROPERTIES = ".properties"; //$NON-NLS-1$
34
/* package */static final String JavaDoc F_ROOT = ".root"; //$NON-NLS-1$
35
/* package */static final String JavaDoc F_SAFE_TABLE = ".safetable"; //$NON-NLS-1$
36
/* package */static final String JavaDoc F_SNAP = ".snap"; //$NON-NLS-1$
37
/* package */static final String JavaDoc F_SNAP_EXTENSION = "snap"; //$NON-NLS-1$
38
/* package */static final String JavaDoc F_SYNCINFO = ".syncinfo"; //$NON-NLS-1$
39
/* package */static final String JavaDoc F_TREE = ".tree"; //$NON-NLS-1$
40
/* package */static final String JavaDoc URI_PREFIX = "URI//"; //$NON-NLS-1$
41

42
43     protected final IPath metaAreaLocation;
44
45     /**
46      * The project location is just stored as an optimization, to avoid recomputing it.
47      */

48     protected final IPath projectMetaLocation;
49
50     public LocalMetaArea() {
51         super();
52         metaAreaLocation = ResourcesPlugin.getPlugin().getStateLocation();
53         projectMetaLocation = metaAreaLocation.append(F_PROJECTS);
54     }
55
56     /**
57      * For backwards compatibility, if there is a project at the old project
58      * description location, delete it.
59      */

60     public void clearOldDescription(IProject target) {
61         Workspace.clear(getOldDescriptionLocationFor(target).toFile());
62     }
63
64     public void create(IProject target) {
65         java.io.File JavaDoc file = locationFor(target).toFile();
66         //make sure area is empty
67
Workspace.clear(file);
68         file.mkdirs();
69     }
70
71     /**
72      * Creates the meta area root directory.
73      */

74     public synchronized void createMetaArea() throws CoreException {
75         java.io.File JavaDoc workspaceLocation = metaAreaLocation.toFile();
76         Workspace.clear(workspaceLocation);
77         if (!workspaceLocation.mkdirs()) {
78             String JavaDoc message = NLS.bind(Messages.resources_writeWorkspaceMeta, workspaceLocation);
79             throw new ResourceException(IResourceStatus.FAILED_WRITE_METADATA, null, message, null);
80         }
81     }
82
83     /**
84      * The project is being deleted. Delete all meta-data associated with the
85      * project.
86      */

87     public void delete(IProject target) throws CoreException {
88         IPath path = locationFor(target);
89         if (!Workspace.clear(path.toFile()) && path.toFile().exists()) {
90             String JavaDoc message = NLS.bind(Messages.resources_deleteMeta, target.getFullPath());
91             throw new ResourceException(IResourceStatus.FAILED_DELETE_METADATA, target.getFullPath(), message, null);
92         }
93     }
94
95     public IPath getBackupLocationFor(IPath file) {
96         return file.removeLastSegments(1).append(file.lastSegment() + F_BACKUP_FILE_EXTENSION);
97     }
98
99     public IPath getHistoryStoreLocation() {
100         return metaAreaLocation.append(F_HISTORY_STORE);
101     }
102
103     /**
104      * Returns the local file system location which contains the META data for
105      * the resources plugin (i.e., the entire workspace).
106      */

107     public IPath getLocation() {
108         return metaAreaLocation;
109     }
110
111     /**
112      * Returns the path of the file in which to save markers for the given
113      * resource. Should only be called for the workspace root and projects.
114      */

115     public IPath getMarkersLocationFor(IResource resource) {
116         Assert.isNotNull(resource);
117         Assert.isLegal(resource.getType() == IResource.ROOT || resource.getType() == IResource.PROJECT);
118         return locationFor(resource).append(F_MARKERS);
119     }
120
121     /**
122      * Returns the path of the file in which to snapshot markers for the given
123      * resource. Should only be called for the workspace root and projects.
124      */

125     public IPath getMarkersSnapshotLocationFor(IResource resource) {
126         return getMarkersLocationFor(resource).addFileExtension(F_SNAP_EXTENSION);
127     }
128
129     /**
130      * The project description file is the only metadata file stored outside
131      * the metadata area. It is stored as a file directly under the project
132      * location. For backwards compatibility, we also have to check for a
133      * project file at the old location in the metadata area.
134      */

135     public IPath getOldDescriptionLocationFor(IProject target) {
136         return locationFor(target).append(F_OLD_PROJECT);
137     }
138
139     public IPath getOldWorkspaceDescriptionLocation() {
140         return metaAreaLocation.append(F_DESCRIPTION);
141     }
142
143     public IPath getPropertyStoreLocation(IResource resource) {
144         int type = resource.getType();
145         Assert.isTrue(type != IResource.FILE && type != IResource.FOLDER);
146         return locationFor(resource).append(F_PROPERTIES);
147     }
148
149     public IPath getSafeTableLocationFor(String JavaDoc pluginId) {
150         IPath prefix = metaAreaLocation.append(F_SAFE_TABLE);
151         // if the plugin is the resources plugin, we return the master table
152
// location
153
if (pluginId.equals(ResourcesPlugin.PI_RESOURCES))
154             return prefix.append(pluginId); // master table
155
int saveNumber = getWorkspace().getSaveManager().getSaveNumber(pluginId);
156         return prefix.append(pluginId + "." + saveNumber); //$NON-NLS-1$
157
}
158
159     public IPath getSnapshotLocationFor(IResource resource) {
160         return metaAreaLocation.append(F_SNAP);
161     }
162
163     /**
164      * Returns the path of the file in which to save the sync information for
165      * the given resource. Should only be called for the workspace root and
166      * projects.
167      */

168     public IPath getSyncInfoLocationFor(IResource resource) {
169         Assert.isNotNull(resource);
170         Assert.isLegal(resource.getType() == IResource.ROOT || resource.getType() == IResource.PROJECT);
171         return locationFor(resource).append(F_SYNCINFO);
172     }
173
174     /**
175      * Returns the path of the file in which to snapshot the sync information
176      * for the given resource. Should only be called for the workspace root and
177      * projects.
178      */

179     public IPath getSyncInfoSnapshotLocationFor(IResource resource) {
180         return getSyncInfoLocationFor(resource).addFileExtension(F_SNAP_EXTENSION);
181     }
182
183     /**
184      * Returns the local file system location of the tree file for the given
185      * resource. This file does not follow the same save number as its plug-in.
186      * So, the number here is called "sequence number" and not "save number" to
187      * avoid confusion.
188      */

189     public IPath getTreeLocationFor(IResource target, boolean updateSequenceNumber) {
190         IPath key = target.getFullPath().append(F_TREE);
191         String JavaDoc sequenceNumber = getWorkspace().getSaveManager().getMasterTable().getProperty(key.toString());
192         if (sequenceNumber == null)
193             sequenceNumber = "0"; //$NON-NLS-1$
194
if (updateSequenceNumber) {
195             int n = new Integer JavaDoc(sequenceNumber).intValue() + 1;
196             n = n < 0 ? 1 : n;
197             sequenceNumber = new Integer JavaDoc(n).toString();
198             getWorkspace().getSaveManager().getMasterTable().setProperty(key.toString(), new Integer JavaDoc(sequenceNumber).toString());
199         }
200         return locationFor(target).append(sequenceNumber + F_TREE);
201     }
202
203     public IPath getWorkingLocation(IResource resource, String JavaDoc id) {
204         return locationFor(resource).append(id);
205     }
206
207     protected Workspace getWorkspace() {
208         return (Workspace) ResourcesPlugin.getWorkspace();
209     }
210
211     public boolean hasSavedProject(IProject project) {
212         //if there is a location file, then the project exists
213
return getOldDescriptionLocationFor(project).toFile().exists() || locationFor(project).append(F_PROJECT_LOCATION).toFile().exists();
214     }
215
216     public boolean hasSavedWorkspace() {
217         return metaAreaLocation.toFile().exists() || getBackupLocationFor(metaAreaLocation).toFile().exists();
218     }
219
220     /**
221      * Returns the local file system location in which the meta data for the
222      * resource with the given path is stored.
223      */

224     public IPath locationFor(IPath resourcePath) {
225         if (Path.ROOT.equals(resourcePath))
226             return metaAreaLocation.append(F_ROOT);
227         return projectMetaLocation.append(resourcePath.segment(0));
228     }
229
230     /**
231      * Returns the local file system location in which the meta data for the
232      * given resource is stored.
233      */

234     public IPath locationFor(IResource resource) {
235         if (resource.getType() == IResource.ROOT)
236             return metaAreaLocation.append(F_ROOT);
237         return projectMetaLocation.append(resource.getProject().getName());
238     }
239
240     /**
241      * Reads and returns the project description for the given project. Returns
242      * null if there was no project description file on disk. Throws an
243      * exception if there was any failure to read the project.
244      */

245     public ProjectDescription readOldDescription(IProject project) throws CoreException {
246         IPath path = getOldDescriptionLocationFor(project);
247         if (!path.toFile().exists())
248             return null;
249         IPath tempPath = getBackupLocationFor(path);
250         ProjectDescription description = null;
251         try {
252             description = new ProjectDescriptionReader(project).read(path, tempPath);
253         } catch (IOException e) {
254             String JavaDoc msg = NLS.bind(Messages.resources_readMeta, project.getName());
255             throw new ResourceException(IResourceStatus.FAILED_READ_METADATA, project.getFullPath(), msg, e);
256         }
257         if (description == null) {
258             String JavaDoc msg = NLS.bind(Messages.resources_readMeta, project.getName());
259             throw new ResourceException(IResourceStatus.FAILED_READ_METADATA, project.getFullPath(), msg, null);
260         }
261         return description;
262     }
263
264     /**
265      * Provides backward compatibility with existing workspaces based on
266      * descriptions.
267      */

268     public WorkspaceDescription readOldWorkspace() {
269         IPath path = getOldWorkspaceDescriptionLocation();
270         IPath tempPath = getBackupLocationFor(path);
271         try {
272             WorkspaceDescription oldDescription = (WorkspaceDescription) new WorkspaceDescriptionReader().read(path, tempPath);
273             // if one of those files exist, get rid of them
274
Workspace.clear(path.toFile());
275             Workspace.clear(tempPath.toFile());
276             return oldDescription;
277         } catch (IOException e) {
278             return null;
279         }
280     }
281
282     /**
283      * Returns the portions of the project description that are private, and
284      * adds them to the supplied project description. In particular, the
285      * project location and the project's dynamic references are stored here.
286      * The project location will be set to <code>null</code> if the default
287      * location should be used. In the case of failure, log the exception and
288      * return silently, thus reverting to using the default location and no
289      * dynamic references. The current format of the location file is:
290      * UTF - project location
291      * int - number of dynamic project references
292      * UTF - project reference 1
293      * ... repeat for remaining references
294      */

295     public void readPrivateDescription(IProject target, IProjectDescription description) {
296         IPath locationFile = locationFor(target).append(F_PROJECT_LOCATION);
297         java.io.File JavaDoc file = locationFile.toFile();
298         if (!file.exists()) {
299             locationFile = getBackupLocationFor(locationFile);
300             file = locationFile.toFile();
301             if (!file.exists())
302                 return;
303         }
304         try {
305             SafeChunkyInputStream input = new SafeChunkyInputStream(file, 500);
306             DataInputStream dataIn = new DataInputStream(input);
307             try {
308                 try {
309                     String JavaDoc location = dataIn.readUTF();
310                     if (location.length() > 0) {
311                         //location format < 3.2 was a local file system OS path
312
//location format >= 3.2 is: URI_PREFIX + uri.toString()
313
if (location.startsWith(URI_PREFIX))
314                             description.setLocationURI(URI.create(location.substring(URI_PREFIX.length())));
315                         else
316                             description.setLocationURI(URIUtil.toURI(Path.fromOSString(location)));
317                     }
318                 } catch (Exception JavaDoc e) {
319                     //don't allow failure to read the location to propagate
320
String JavaDoc msg = NLS.bind(Messages.resources_exReadProjectLocation, target.getName());
321                     Policy.log(new ResourceStatus(IStatus.ERROR, IResourceStatus.FAILED_READ_METADATA, target.getFullPath(), msg, e));
322                 }
323                 //try to read the dynamic references - will fail for old location files
324
int numRefs = dataIn.readInt();
325                 IProject[] references = new IProject[numRefs];
326                 IWorkspaceRoot root = getWorkspace().getRoot();
327                 for (int i = 0; i < numRefs; i++)
328                     references[i] = root.getProject(dataIn.readUTF());
329                 description.setDynamicReferences(references);
330             } finally {
331                 dataIn.close();
332             }
333         } catch (IOException e) {
334             //ignore - this is an old location file or an exception occurred
335
// closing the stream
336
}
337     }
338
339     /**
340      * Writes the workspace description to the local meta area. This method is
341      * synchronized to prevent multiple current write attempts.
342      *
343      * @deprecated should not be called any more - workspace preferences are
344      * now maintained in the plug-in's preferences
345      */

346     public synchronized void write(WorkspaceDescription description) throws CoreException {
347         IPath path = getOldWorkspaceDescriptionLocation();
348         path.toFile().getParentFile().mkdirs();
349         IPath tempPath = getBackupLocationFor(path);
350         try {
351             new ModelObjectWriter().write(description, path, tempPath);
352         } catch (IOException e) {
353             String JavaDoc message = NLS.bind(Messages.resources_writeWorkspaceMeta, path);
354             throw new ResourceException(IResourceStatus.FAILED_WRITE_METADATA, null, message, e);
355         }
356     }
357
358     /**
359      * Write the private project description information, including the location
360      * and the dynamic project references. See <tt>readPrivateDescription</tt>
361      * for details on the file format.
362      */

363     public void writePrivateDescription(IProject target) throws CoreException {
364         IPath location = locationFor(target).append(F_PROJECT_LOCATION);
365         java.io.File JavaDoc file = location.toFile();
366         //delete any old location file
367
Workspace.clear(file);
368         //don't write anything if there is no interesting private metadata
369
ProjectDescription desc = ((Project) target).internalGetDescription();
370         if (desc == null)
371             return;
372         final URI JavaDoc projectLocation = desc.getLocationURI();
373         final IProject[] references = desc.getDynamicReferences(false);
374         final int numRefs = references.length;
375         if (projectLocation == null && numRefs == 0)
376             return;
377         //write the private metadata file
378
try {
379             SafeChunkyOutputStream output = new SafeChunkyOutputStream(file);
380             DataOutputStream dataOut = new DataOutputStream(output);
381             try {
382                 if (projectLocation == null)
383                     dataOut.writeUTF(""); //$NON-NLS-1$
384
else
385                     dataOut.writeUTF(URI_PREFIX + projectLocation.toString());
386                 dataOut.writeInt(numRefs);
387                 for (int i = 0; i < numRefs; i++)
388                     dataOut.writeUTF(references[i].getName());
389                 output.succeed();
390             } finally {
391                 dataOut.close();
392             }
393         } catch (IOException e) {
394             String JavaDoc message = NLS.bind(Messages.resources_exSaveProjectLocation, target.getName());
395             throw new ResourceException(IResourceStatus.INTERNAL_ERROR, null, message, e);
396         }
397     }
398 }
399
Popular Tags