1 11 package org.eclipse.osgi.service.datalocation; 12 13 import java.io.*; 14 import java.util.*; 15 import org.eclipse.core.runtime.adaptor.*; 16 import org.eclipse.core.runtime.adaptor.BasicLocation; 17 import org.eclipse.core.runtime.adaptor.Locker; 18 19 39 public class FileManager { 40 private class Entry { 41 int readId; 42 int writeId; 43 44 Entry(int readId, int writeId) { 45 this.readId = readId; 46 this.writeId = writeId; 47 } 48 49 int getReadId() { 50 return readId; 51 } 52 53 int getWriteId() { 54 return writeId; 55 } 56 57 void setReadId(int value) { 58 readId = value; 59 } 60 61 void setWriteId(int value) { 62 writeId = value; 63 } 64 } 65 66 private File base; private File managerRoot; 69 private String lockMode = null; 70 private File tableFile = null; 71 private File lockFile; private Locker locker; 74 private File instanceFile = null; private Locker instanceLocker = null; 77 private long tableStamp = 0L; 79 80 private Properties table = new Properties(); 81 82 private static final String MANAGER_FOLDER = ".manager"; private static final String TABLE_FILE = ".fileTable"; private static final String LOCK_FILE = ".fileTableLock"; 86 94 public FileManager(File base, String lockMode) { 95 this.base = base; 96 this.lockMode = lockMode; 97 this.managerRoot = new File(base, MANAGER_FOLDER); 98 this.managerRoot.mkdir(); 99 this.tableFile = new File(managerRoot, TABLE_FILE); 100 this.lockFile = new File(managerRoot, LOCK_FILE); 101 } 102 103 private void initializeInstanceFile() throws IOException { 104 if (instanceFile != null) 105 return; 106 this.instanceFile = File.createTempFile(".tmp", ".instance", managerRoot); this.instanceFile.deleteOnExit(); 108 instanceLocker = BasicLocation.createLocker(instanceFile, lockMode); 109 instanceLocker.lock(); 110 } 111 112 private String getAbsolutePath(String file) { 113 return new File(base, file).getAbsolutePath(); 114 } 115 116 122 public void add(String file) throws IOException { 123 if (! lock()) 124 throw new IOException(EclipseAdaptorMsg.formatter.getString("fileManager.cannotLock")); try { 126 updateTable(); 127 Entry entry = (Entry) table.get(file); 128 if (entry == null) { 129 table.put(file, new Entry(0, 1)); 130 save(); 131 } 132 } finally { 133 release(); 134 } 135 } 136 137 147 public void update(String [] targets, String [] sources) throws IOException { 148 if (! lock()) 149 throw new IOException(EclipseAdaptorMsg.formatter.getString("fileManager.cannotLock")); try { 151 updateTable(); 152 for (int i = 0; i < targets.length; i++) { 153 String target = targets[i]; 154 update(target, sources[i]); 155 } 156 save(); 157 } finally { 158 release(); 159 } 160 } 161 162 167 public String [] getFiles() { 168 Set set = table.keySet(); 169 String [] keys = (String []) set.toArray(new String [set.size()]); 170 String [] result = new String [keys.length]; 171 for (int i = 0; i < keys.length; i++) 172 result[i] = new String (keys[i]); 173 return result; 174 } 175 176 182 public File getBase() { 183 return base; 184 } 185 186 195 public int getId(String target) { 196 Entry entry = (Entry) table.get(target); 197 if (entry == null) 198 return -1; 199 return entry.getReadId(); 200 } 201 202 214 private boolean lock() throws IOException { 215 if (locker == null) 216 locker = BasicLocation.createLocker(lockFile, lockMode); 217 if (locker == null) 218 throw new IOException(EclipseAdaptorMsg.formatter.getString("fileManager.cannotLock")); return locker.lock(); 220 } 221 222 232 public File lookup(String target, boolean add) throws IOException { 233 Entry entry = (Entry) table.get(target); 234 if (entry == null) { 235 if (add) { 236 add(target); 237 entry = (Entry) table.get(target); 238 } else { 239 return null; 240 } 241 } 242 return new File(getAbsolutePath(target + '.' + entry.getReadId())); 243 } 244 245 private void move(String source, String target) { 246 File original = new File(source); 247 if (!original.exists()) 250 return; 251 original.renameTo(new File(target)); 252 } 253 254 257 private void release() { 258 if (locker == null) 259 return; 260 locker.release(); 261 } 262 263 268 public void remove(String file) throws IOException { 269 if (! lock()) 272 throw new IOException(EclipseAdaptorMsg.formatter.getString("fileManager.cannotLock")); try { 274 updateTable(); 275 table.remove(file); 276 save(); 277 } finally { 278 release(); 279 } 280 } 281 282 private void updateTable() throws IOException { 283 if (!tableFile.exists()) 284 return; 285 long stamp = tableFile.lastModified(); 286 if (stamp == tableStamp) 287 return; 288 initializeInstanceFile(); 289 Properties diskTable = new Properties(); 290 try { 291 FileInputStream input = new FileInputStream(tableFile); 292 try { 293 diskTable.load(input); 294 } finally { 295 input.close(); 296 } 297 } catch (IOException e) { 298 throw e; } 300 tableStamp = stamp; 301 for (Enumeration e = diskTable.keys(); e.hasMoreElements();) { 302 String file = (String ) e.nextElement(); 303 String readNumber = diskTable.getProperty(file); 304 if (readNumber != null) { 305 Entry entry = (Entry) table.get(file); 306 int id = Integer.parseInt(readNumber); 307 if (entry == null) { 308 table.put(file, new Entry(id, id + 1)); 309 } else { 310 entry.setWriteId(id + 1); 311 } 312 } 313 } 314 } 315 316 319 private void save() throws IOException { 320 if (tableStamp != tableFile.lastModified()) 323 updateTable(); 324 Properties props = new Properties(); 325 for (Enumeration e = table.keys(); e.hasMoreElements();) { 326 String file = (String ) e.nextElement(); 327 Entry entry = (Entry) table.get(file); 328 String value = Integer.toString(entry.getWriteId() - 1); props.put(file, value); 330 } 331 FileOutputStream fileStream = new FileOutputStream(tableFile); 332 try { 333 try { 334 props.store(fileStream, "safe table"); } finally { 336 fileStream.close(); 337 } 338 } catch (IOException e) { 339 throw new IOException(EclipseAdaptorMsg.formatter.getString("fileManager.couldNotSave")); } 341 } 342 343 private void update(String target, String source) { 344 Entry entry = (Entry) table.get(target); 345 int newId = entry.getWriteId(); 346 move(getAbsolutePath(source), getAbsolutePath(target) + '.' + newId); 347 entry.setReadId(newId); 350 entry.setWriteId(newId + 1); 351 } 352 353 358 private void cleanup() throws IOException { 359 String [] files = managerRoot.list(); 361 for (int i = 0; i < files.length; i++) { 362 if (files[i].endsWith(".instance") && !files[i].equalsIgnoreCase(instanceFile.getName())) { if (new File(managerRoot, files[i]).delete() == false) 364 return; 365 } 366 } 367 368 if (! lock()) 371 throw new IOException(EclipseAdaptorMsg.formatter.getString("fileManager.cannotLock")); try { 373 updateTable(); 374 Collection managedFiles = table.entrySet(); 375 for (Iterator iter = managedFiles.iterator(); iter.hasNext();) { 376 Map.Entry fileEntry = (Map.Entry) iter.next(); 377 String fileName = (String ) fileEntry.getKey(); 378 Entry info = (Entry) fileEntry.getValue(); 379 String readId = Integer.toString(info.getWriteId() - 1); 381 deleteCopies(fileName, readId); 382 } 383 } catch (IOException e) { 384 throw e; 387 } finally { 388 release(); 389 } 390 } 391 392 private void deleteCopies(String fileName, String exceptionNumber) { 393 String notToDelete = fileName + '.' + exceptionNumber; 394 String [] files = base.list(); 395 for (int i = 0; i < files.length; i++) { 396 if (files[i].startsWith(fileName + '.') && !files[i].equals(notToDelete)) new File(base, files[i]).delete(); 398 } 399 } 400 401 405 public void close() { 406 try { 407 cleanup(); 408 } catch (IOException e) { 409 } 411 instanceLocker.release(); 412 instanceFile.delete(); 413 } 414 415 419 public void open(boolean wait) throws IOException { 420 boolean locked = lock(); 421 if (! locked && wait==false) 422 throw new IOException(EclipseAdaptorMsg.formatter.getString("fileManager.cannotLock")); 424 if (! locked) { 426 do { 427 try { 428 Thread.sleep(10); 429 } catch (InterruptedException e) { 430 } 432 } while(lock()); 433 } 434 435 try { 436 updateTable(); 437 } finally { 438 release(); 439 } 440 } 441 } | Popular Tags |