KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > eclipse > core > internal > localstore > HistoryStore


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.localstore;
12
13 import java.io.InputStream JavaDoc;
14 import java.util.*;
15 import org.eclipse.core.filesystem.*;
16 import org.eclipse.core.internal.indexing.*;
17 import org.eclipse.core.internal.properties.IndexedStoreWrapper;
18 import org.eclipse.core.internal.resources.*;
19 import org.eclipse.core.internal.utils.*;
20 import org.eclipse.core.internal.utils.Convert;
21 import org.eclipse.core.resources.*;
22 import org.eclipse.core.runtime.*;
23 import org.eclipse.osgi.util.NLS;
24
25 public class HistoryStore implements IHistoryStore {
26     /* package */final static String JavaDoc INDEX_FILE = ".index"; //$NON-NLS-1$
27
protected BlobStore blobStore;
28     Set blobsToRemove = new HashSet();
29     IndexedStoreWrapper store;
30
31     protected Workspace workspace;
32
33     public HistoryStore(Workspace workspace, IPath location, int limit) {
34         this.workspace = workspace;
35         this.blobStore = new BlobStore(EFS.getLocalFileSystem().getStore(location), limit);
36         this.store = new IndexedStoreWrapper(location.append(INDEX_FILE));
37     }
38
39     /**
40      * Searches indexed store for key, and invokes visitor's defined behaviour on key matches.
41      *
42      * @param key key prefix on which to perform search. This is assumed to be
43      * a path only unless the flag includeLastModTime is true.
44      * @param visitOnPartialMatch indicates whether visitor's defined behavior is to be invoked
45      * on partial or full key matches. Partial key matches are not supported on keys which
46      * contain a last modified time.
47      * @param includeLastModTime indicates if the key includes a last modified
48      * time. If set to false, the key is assumed to have only a path.
49      */

50     protected void accept(byte[] key, IHistoryStoreVisitor visitor, boolean visitOnPartialMatch, boolean includeLastModTime) {
51         try {
52             IndexCursor cursor = store.getCursor();
53             cursor.find(key);
54             // Check for a prefix match.
55
while (cursor.keyMatches(key)) {
56                 byte[] storedKey = cursor.getKey();
57
58                 int bytesToOmit = includeLastModTime ? ILocalStoreConstants.SIZE_COUNTER : ILocalStoreConstants.SIZE_KEY_SUFFIX;
59                 // visit if we have an exact match
60
if (storedKey.length - bytesToOmit == key.length) {
61                     HistoryStoreEntry storedEntry = HistoryStoreEntry.create(store, cursor);
62                     if (!visitor.visit(storedEntry))
63                         break;
64                     cursor.next();
65                     continue;
66                 }
67
68                 // return if we aren't checking partial matches
69
if (!visitOnPartialMatch) {
70                     cursor.next();
71                     continue;
72                 }
73
74                 // if the last character of the key is a path
75
// separator or if the next character in the match
76
// is a path separator then visit since it is a child
77
// based on path segment matching.
78
byte b = storedKey[key.length];
79                 if (key[key.length - 1] == 47 || b == 47) {
80                     HistoryStoreEntry storedEntry = HistoryStoreEntry.create(store, cursor);
81                     if (!visitor.visit(storedEntry))
82                         break;
83                 }
84                 cursor.next();
85             }
86             cursor.close();
87         } catch (Exception JavaDoc e) {
88             String JavaDoc message = CompatibilityMessages.history_problemsAccessing;
89             Policy.log(new ResourceStatus(IResourceStatus.FAILED_READ_LOCAL, null, message, e));
90         }
91     }
92
93     protected void accept(IPath path, IHistoryStoreVisitor visitor, boolean visitOnPartialMatch) {
94         accept(Convert.toUTF8(path.toString()), visitor, visitOnPartialMatch, false);
95     }
96
97     /**
98      * @see IHistoryStore#addState(IPath, IFileStore, IFileInfo, boolean)
99      */

100     public IFileState addState(IPath key, IFileStore localFile, IFileInfo info, boolean moveContents) {
101         long lastModified = info.getLastModified();
102         if (Policy.DEBUG_HISTORY)
103             System.out.println("History: Adding state for key: " + key + ", file: " + localFile + ", timestamp: " + lastModified + ", size: " + localFile.fetchInfo().getLength()); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
104
if (!isValid(localFile))
105             return null;
106         UniversalUniqueIdentifier uuid = null;
107         try {
108             uuid = blobStore.addBlob(localFile, moveContents);
109             addState(key, uuid, lastModified);
110             store.commit();
111         } catch (CoreException e) {
112             Policy.log(e);
113         }
114         return new FileState(this, key, lastModified, uuid);
115     }
116
117     /**
118      * Adds state into history log.
119      *
120      * @param path Full workspace path to the resource being logged.
121      * @param uuid UUID for stored file contents.
122      * @param lastModified Timestamp for resource being logged.
123      */

124     protected void addState(IPath path, UniversalUniqueIdentifier uuid, long lastModified) {
125         // Determine how many states already exist for this path and timestamp.
126
class BitVisitor implements IHistoryStoreVisitor {
127             BitSet bits = new BitSet();
128
129             public byte useNextClearBit(byte[] key) {
130                 // Don't use an empty slot as this will put this state
131
// out of order relative to the other states with the same
132
// path and last modified time. So find the first clear bit
133
// after the last set bit.
134
int nextBit = bits.length();
135                 // This value must fit in a byte. If we are running off the
136
// end of the byte, check to see if there are any empty bits
137
// in the middle. If so, reorganize the counters so we maintain
138
// the ordering of the states but use up the least number
139
// of bits (i.e., de-fragment the bit set).
140
if (nextBit > Byte.MAX_VALUE) {
141                     if (bits.cardinality() < Byte.MAX_VALUE) {
142                         // We know we have some clear bits.
143
try {
144                             IndexCursor cursor = store.getCursor();
145                             // destCount will always be the count value of the
146
// next key we want to assign a state to
147
byte destCount = (byte) bits.nextClearBit(0);
148                             if (destCount < 0)
149                                 // There are no clear bits
150
return (byte) -1;
151                             // sourceCount will always be the count value of the
152
// next key we want to move to destCount. When
153
// sourceCount is -1, there are no more source states
154
// to move so we are done.
155
byte sourceCount = (byte) bits.nextSetBit(destCount);
156                             if (sourceCount < 0)
157                                 // There are no more states to move
158
return destCount;
159                             byte[] completeKey = new byte[key.length + 1];
160                             System.arraycopy(key, 0, completeKey, 0, key.length);
161                             for (; sourceCount >= 0 && destCount >= 0; destCount++) {
162                                 completeKey[completeKey.length - 1] = sourceCount;
163                                 cursor.find(completeKey);
164                                 if (cursor.keyMatches(completeKey)) {
165                                     HistoryStoreEntry storedEntry = HistoryStoreEntry.create(store, cursor);
166                                     HistoryStoreEntry entryToInsert = new HistoryStoreEntry(storedEntry.getPath(), storedEntry.getUUID(), storedEntry.getLastModified(), destCount);
167                                     remove(storedEntry);
168                                     ObjectID valueID = store.createObject(entryToInsert.valueToBytes());
169                                     store.getIndex().insert(entryToInsert.getKey(), valueID);
170                                     sourceCount = (byte) bits.nextSetBit(sourceCount + 1);
171                                 }
172                             }
173                             cursor.close();
174                             return destCount;
175                         } catch (Exception JavaDoc e) {
176                             String JavaDoc message = CompatibilityMessages.history_problemsAccessing;
177                             Policy.log(new ResourceStatus(IResourceStatus.FAILED_READ_LOCAL, null, message, e));
178                         }
179                     } else {
180                         // Every count is being used. Too many states.
181
return (byte) -1;
182                     }
183                 }
184                 return (byte) nextBit;
185             }
186
187             public boolean visit(HistoryStoreEntry entry) {
188                 bits.set(entry.getCount());
189                 return true;
190             }
191         }
192
193         // Build partial key for which matches will be found.
194
byte[] keyPrefix = HistoryStoreEntry.keyPrefixToBytes(path, lastModified);
195         BitVisitor visitor = new BitVisitor();
196         accept(keyPrefix, visitor, false, true);
197         byte index = visitor.useNextClearBit(keyPrefix);
198         try {
199             if (index < 0) {
200                 String JavaDoc message = NLS.bind(CompatibilityMessages.history_tooManySimUpdates, path, new Date(lastModified));
201                 Policy.log(new ResourceStatus(IResourceStatus.FAILED_WRITE_LOCAL, path, message, null));
202                 return;
203             }
204             HistoryStoreEntry entryToInsert = new HistoryStoreEntry(path, uuid, lastModified, index);
205             // valueToBytes just converts the uuid to byte form
206
ObjectID valueID = store.createObject(entryToInsert.valueToBytes());
207             store.getIndex().insert(entryToInsert.getKey(), valueID);
208         } catch (Exception JavaDoc e) {
209             resetIndexedStore();
210             String JavaDoc message = NLS.bind(CompatibilityMessages.history_couldNotAdd, path);
211             Policy.log(new ResourceStatus(IResourceStatus.FAILED_WRITE_LOCAL, path, message, e));
212         }
213     }
214
215     /**
216      * @see IHistoryStore#allFiles(IPath, int, IProgressMonitor)
217      */

218     public Set allFiles(IPath path, final int depth, IProgressMonitor monitor) {
219         final Set allFiles = new HashSet();
220         final int pathLength = path.segmentCount();
221         class PathCollector implements IHistoryStoreVisitor {
222             public boolean visit(HistoryStoreEntry state) {
223                 IPath memberPath = state.getPath();
224                 boolean withinDepthRange = false;
225                 switch (depth) {
226                     case IResource.DEPTH_ZERO :
227                         withinDepthRange = memberPath.segmentCount() == pathLength;
228                         break;
229                     case IResource.DEPTH_ONE :
230                         withinDepthRange = memberPath.segmentCount() <= pathLength + 1;
231                         break;
232                     case IResource.DEPTH_INFINITE :
233                         withinDepthRange = true;
234                         break;
235                 }
236                 if (withinDepthRange) {
237                     allFiles.add(memberPath);
238                 }
239                 // traverse children as long as we're still within depth range
240
return withinDepthRange;
241             }
242         }
243         accept(path, new PathCollector(), true);
244         return allFiles;
245     }
246
247     /**
248      * @see IHistoryStore#clean(IProgressMonitor)
249      */

250     public void clean(IProgressMonitor monitor) {
251         long start = System.currentTimeMillis();
252         int entryCount = 0;
253         IWorkspaceDescription description = workspace.internalGetDescription();
254         long minimumTimestamp = System.currentTimeMillis() - description.getFileStateLongevity();
255         int max = description.getMaxFileStates();
256         IPath current = null;
257         List result = new ArrayList(Math.min(max, 1000));
258         try {
259             IndexCursor cursor = store.getCursor();
260             cursor.findFirstEntry();
261             while (cursor.isSet()) {
262                 entryCount++;
263                 HistoryStoreEntry entry = HistoryStoreEntry.create(store, cursor);
264                 // is it old?
265
if (entry.getLastModified() < minimumTimestamp) {
266                     remove(entry);
267                     continue;
268                 }
269                 if (!entry.getPath().equals(current)) {
270                     removeOldestEntries(result, max);
271                     result.clear();
272                     current = entry.getPath();
273                 }
274                 result.add(entry);
275                 cursor.next();
276             }
277             removeOldestEntries(result, max);
278             cursor.close();
279             store.commit();
280             if (Policy.DEBUG_HISTORY) {
281                 Policy.debug("Time to apply history store policies: " + (System.currentTimeMillis() - start) + "ms."); //$NON-NLS-1$ //$NON-NLS-2$
282
Policy.debug("Total number of history store entries: " + entryCount); //$NON-NLS-1$
283
}
284             start = System.currentTimeMillis();
285             // remove unreferenced blobs
286
blobStore.deleteBlobs(blobsToRemove);
287             if (Policy.DEBUG_HISTORY)
288                 Policy.debug("Time to remove " + blobsToRemove.size() + " unreferenced blobs: " + (System.currentTimeMillis() - start) + "ms."); //$NON-NLS-1$//$NON-NLS-2$ //$NON-NLS-3$
289
blobsToRemove = new HashSet();
290         } catch (Exception JavaDoc e) {
291             String JavaDoc message = CompatibilityMessages.history_problemsCleaning;
292             Policy.log(new ResourceStatus(IResourceStatus.FAILED_DELETE_LOCAL, null, message, e));
293         }
294     }
295
296     /* (non-Javadoc)
297      * @see org.eclipse.core.internal.localstore.IHistoryStore#closeHistory(org.eclipse.core.resources.IResource)
298      */

299     public void closeHistoryStore(IResource resource) {
300         //old history store does not need to be saved
301
}
302
303     /**
304      * @see IHistoryStore#copyHistory(IResource, IResource, boolean)
305      * @since 2.1
306      */

307     public void copyHistory(final IResource sourceResource, final IResource destinationResource, boolean moving) {
308         // Note that if any states in the local history for destination
309
// have the same timestamp as a state for the local history
310
// for source, the local history for destination will appear
311
// as an older state than the one for source.
312

313         // return early if either of the paths are null or if the source and
314
// destination are the same.
315
if (sourceResource == null || destinationResource == null) {
316             String JavaDoc message = CompatibilityMessages.history_copyToNull;
317             Policy.log(new ResourceStatus(IResourceStatus.INTERNAL_ERROR, null, message, null));
318             return;
319         }
320         if (sourceResource.equals(destinationResource)) {
321             String JavaDoc message = CompatibilityMessages.history_copyToSelf;
322             Policy.log(new ResourceStatus(IResourceStatus.INTERNAL_ERROR, sourceResource.getFullPath(), message, null));
323             return;
324         }
325
326         final IPath source = sourceResource.getFullPath();
327         final IPath destination = destinationResource.getFullPath();
328         // Note that if any states in the local history for destination
329
// have the same timestamp as a state for the local history
330
// for source, the local history for destination will appear
331
// as an older state than the one for source.
332

333         // matches will be a list of all the places we add local history (without
334
// any duplicates).
335
final Set matches = new HashSet();
336
337         IHistoryStoreVisitor visitor = new IHistoryStoreVisitor() {
338             public boolean visit(HistoryStoreEntry entry) {
339                 IPath path = entry.getPath();
340                 int prefixSegments = source.matchingFirstSegments(path);
341                 // if there are no matching segments then we have an internal error...something
342
// is wrong with the visitor
343
if (prefixSegments == 0) {
344                     String JavaDoc message = NLS.bind(CompatibilityMessages.history_interalPathErrors, source, path);
345                     Policy.log(new ResourceStatus(IResourceStatus.INTERNAL_ERROR, source, message, null));
346                     return false;
347                 }
348                 path = destination.append(path.removeFirstSegments(prefixSegments));
349                 if (!stateAlreadyExists(path, entry.getUUID())) {
350                     matches.add(path);
351                     addState(path, entry.getUUID(), entry.getLastModified());
352                 }
353                 return true;
354             }
355         };
356
357         // Visit all the entries. Visit partial matches too since this is a depth infinity operation
358
// and we want to copy history for children.
359
accept(source, visitor, true);
360
361         // For each match, make sure we haven't exceeded the maximum number of
362
// states allowed.
363
IWorkspaceDescription description = workspace.internalGetDescription();
364         int maxFileStates = description.getMaxFileStates();
365         try {
366             for (Iterator i = matches.iterator(); i.hasNext();) {
367                 List removeEntries = new LinkedList();
368                 IndexCursor cursor = store.getCursor();
369                 IPath path = (IPath) i.next();
370                 byte key[] = Convert.toUTF8(path.toString());
371                 cursor.find(key);
372                 // If this key is a match, grab the history store entry for it.
373
// Don't need to worry about whether or not this is a full path
374
// match as we know we used this path to add new state information
375
// to the local history.
376
while (cursor.keyMatches(key)) {
377                     removeEntries.add(HistoryStoreEntry.create(store, cursor));
378                     cursor.next();
379                 }
380                 cursor.close();
381                 removeOldestEntries(removeEntries, maxFileStates);
382             }
383         } catch (IndexedStoreException e) {
384             String JavaDoc message = NLS.bind(CompatibilityMessages.history_problemsPurging, source, destination);
385             ResourceStatus status = new ResourceStatus(IResourceStatus.FAILED_WRITE_METADATA, source, message, e);
386             Policy.log(status);
387         } catch (CoreException e) {
388             String JavaDoc message = NLS.bind(CompatibilityMessages.history_problemsPurging, source, destination);
389             ResourceStatus status = new ResourceStatus(IResourceStatus.FAILED_WRITE_METADATA, source, message, e);
390             Policy.log(status);
391         }
392
393         // We need to do a commit here. The addState method we are
394
// using won't commit store. The public ones will.
395
try {
396             store.commit();
397         } catch (CoreException e) {
398             String JavaDoc message = NLS.bind(CompatibilityMessages.history_problemCopying, source, destination);
399             ResourceStatus status = new ResourceStatus(IResourceStatus.FAILED_WRITE_METADATA, source, message, e);
400             Policy.log(status);
401         }
402     }
403
404     /**
405      * @see IHistoryStore#exists(IFileState)
406      */

407     public boolean exists(IFileState target) {
408         return blobStore.fileFor(((FileState) target).getUUID()).fetchInfo().exists();
409     }
410
411     /**
412      * @see IHistoryStore#getContents(IFileState)
413      */

414     public InputStream JavaDoc getContents(IFileState target) throws CoreException {
415         if (!target.exists()) {
416             String JavaDoc message = CompatibilityMessages.history_notValid;
417             throw new ResourceException(IResourceStatus.FAILED_READ_LOCAL, target.getFullPath(), message, null);
418         }
419         return blobStore.getBlob(((FileState) target).getUUID());
420     }
421
422     /**
423      * @see IHistoryStore#getStates(IPath, IProgressMonitor)
424      */

425     public IFileState[] getStates(final IPath key, IProgressMonitor monitor) {
426         final int max = workspace.internalGetDescription().getMaxFileStates();
427         final List result = new ArrayList(max);
428         IHistoryStoreVisitor visitor = new IHistoryStoreVisitor() {
429             public boolean visit(HistoryStoreEntry entry) {
430                 result.add(new FileState(HistoryStore.this, key, entry.getLastModified(), entry.getUUID()));
431                 return true;
432             }
433         };
434         accept(key, visitor, false);
435         if (result.isEmpty())
436             return ICoreConstants.EMPTY_FILE_STATES;
437         // put in the order of newer first
438
IFileState[] states = new IFileState[result.size()];
439         for (int i = 0; i < states.length; i++)
440             states[i] = (IFileState) result.get(result.size() - (i + 1));
441         return states;
442     }
443
444     /**
445      * Return a boolean value indicating whether or not the given file
446      * should be added to the history store based on the current history
447      * store policies.
448      *
449      * @param localFile the file to check
450      * @return <code>true</code> if this file should be added to the history
451      * store and <code>false</code> otherwise
452      */

453     private boolean isValid(IFileStore localFile) {
454         WorkspaceDescription description = workspace.internalGetDescription();
455         long length = localFile.fetchInfo().getLength();
456         boolean result = length <= description.getMaxFileStateSize();
457         if (Policy.DEBUG_HISTORY && !result)
458             System.out.println("History: Ignoring file (too large). File: " + localFile.toString() + //$NON-NLS-1$
459
", size: " + length + //$NON-NLS-1$
460
", max: " + description.getMaxFileStateSize()); //$NON-NLS-1$
461
return result;
462     }
463
464     protected void remove(HistoryStoreEntry entry) throws IndexedStoreException {
465         try {
466             Vector objectIds = store.getIndex().getObjectIdentifiersMatching(entry.getKey());
467             if (objectIds.size() == 1) {
468                 store.removeObject((ObjectID) objectIds.get(0));
469             } else if (objectIds.size() > 1) {
470                 // There is a problem with more than one entry having the same
471
// key.
472
String JavaDoc message = NLS.bind(CompatibilityMessages.history_tooManySimUpdates, entry.getPath(), new Date(entry.getLastModified()));
473                 ResourceStatus status = new ResourceStatus(IResourceStatus.FAILED_DELETE_LOCAL, entry.getPath(), message, null);
474                 Policy.log(status);
475             }
476         } catch (Exception JavaDoc e) {
477             String JavaDoc[] messageArgs = {entry.getPath().toString(), new Date(entry.getLastModified()).toString(), entry.getUUID().toString()};
478             String JavaDoc message = NLS.bind(CompatibilityMessages.history_specificProblemsCleaning, messageArgs);
479             ResourceStatus status = new ResourceStatus(IResourceStatus.FAILED_DELETE_LOCAL, null, message, e);
480             Policy.log(status);
481         }
482         // Do not remove the blob yet. It may be referenced by another
483
// history store entry.
484
blobsToRemove.add(entry.getUUID());
485         entry.remove();
486     }
487
488     /**
489      * @see IHistoryStore#remove(IPath, IProgressMonitor)
490      */

491     public void remove(IPath path, IProgressMonitor monitor) {
492         if (Path.ROOT.equals(path)) {
493             removeAll();
494             return;
495         }
496         try {
497             IndexCursor cursor = store.getCursor();
498             byte[] key = Convert.toUTF8(path.toString());
499             cursor.find(key);
500             while (cursor.keyMatches(key)) {
501                 HistoryStoreEntry entry = HistoryStoreEntry.create(store, cursor);
502                 remove(entry);
503             }
504             cursor.close();
505             store.commit();
506         } catch (Exception JavaDoc e) {
507             String JavaDoc message = NLS.bind(CompatibilityMessages.history_problemsRemoving, path);
508             ResourceStatus status = new ResourceStatus(IResourceStatus.FAILED_DELETE_LOCAL, path, message, e);
509             Policy.log(status);
510         }
511     }
512
513     /**
514      * Remove all the entries in the store.
515      */

516     private void removeAll() {
517         // TODO: should implement a method with a better performance
518
try {
519             IndexCursor cursor = store.getCursor();
520             cursor.findFirstEntry();
521             while (cursor.isSet()) {
522                 HistoryStoreEntry entry = HistoryStoreEntry.create(store, cursor);
523                 remove(entry);
524             }
525             cursor.close();
526             store.commit();
527         } catch (Exception JavaDoc e) {
528             String JavaDoc message = NLS.bind(CompatibilityMessages.history_problemsRemoving, workspace.getRoot().getFullPath());
529             ResourceStatus status = new ResourceStatus(IResourceStatus.FAILED_DELETE_LOCAL, workspace.getRoot().getFullPath(), message, e);
530             Policy.log(status);
531         }
532     }
533
534     /**
535      * Go through the history store and remove all of the unreferenced blobs.
536      * Check the instance variable which holds onto a set of UUIDs of potential
537      * candidates to be removed.
538      *
539      * @see IHistoryStore#removeGarbage()
540      */

541     public void removeGarbage() {
542         try {
543             IndexCursor cursor = store.getCursor();
544             cursor.findFirstEntry();
545             while (!blobsToRemove.isEmpty() && cursor.isSet()) {
546                 HistoryStoreEntry entry = HistoryStoreEntry.create(store, cursor);
547                 blobsToRemove.remove(entry.getUUID());
548                 cursor.next();
549             }
550             cursor.close();
551             blobStore.deleteBlobs(blobsToRemove);
552             blobsToRemove = new HashSet();
553         } catch (Exception JavaDoc e) {
554             String JavaDoc message = CompatibilityMessages.history_problemsCleaning;
555             ResourceStatus status = new ResourceStatus(IResourceStatus.FAILED_DELETE_LOCAL, null, message, e);
556             Policy.log(status);
557         }
558     }
559
560     protected void removeOldestEntries(List entries, int maxEntries) throws IndexedStoreException {
561         // do we have more states than necessary?
562
if (entries.size() <= maxEntries)
563             return;
564         int limit = entries.size() - maxEntries;
565         for (int i = 0; i < limit; i++)
566             remove((HistoryStoreEntry) entries.get(i));
567     }
568
569     protected void resetIndexedStore() {
570         store.reset();
571         java.io.File JavaDoc target = workspace.getMetaArea().getHistoryStoreLocation().toFile();
572         Workspace.clear(target);
573         target.mkdirs();
574         String JavaDoc message = CompatibilityMessages.history_corrupt;
575         ResourceStatus status = new ResourceStatus(IResourceStatus.INTERNAL_ERROR, null, message, null);
576         Policy.log(status);
577     }
578
579     /**
580      * @see IManager#shutdown(IProgressMonitor)
581      */

582     public void shutdown(IProgressMonitor monitor) {
583         if (store == null)
584             return;
585         store.close();
586     }
587
588     /**
589      * @see IManager#startup(IProgressMonitor)
590      */

591     public void startup(IProgressMonitor monitor) {
592         // do nothing
593
}
594
595     boolean stateAlreadyExists(IPath path, final UniversalUniqueIdentifier uuid) {
596         final boolean[] rc = new boolean[] {false};
597         IHistoryStoreVisitor visitor = new IHistoryStoreVisitor() {
598             public boolean visit(HistoryStoreEntry entry) {
599                 if (rc[0] || uuid.equals(entry.getUUID())) {
600                     rc[0] = true;
601                     return false;
602                 }
603                 return true;
604             }
605         };
606         accept(path, visitor, false);
607         return rc[0];
608     }
609 }
610
Popular Tags