/* * Copyright 2005-2010 Ignis Software Tools Ltd. All rights reserved. */ package jsystem.utils; import java.io.File; import java.io.FileOutputStream; import java.nio.channels.OverlappingFileLockException; import java.util.HashMap; import java.util.Map; /** * One of the ways to make sure the user doesn't open more then one process of a program * is to use a file as a semaphore. When a process starts it grabs a hold on the file, * When the next process starts it will identify that the file is already grabbed * and will not start. * * This utility class manages file lock mechanism. * * To work with the class the process activates the static method {@link #getFileLock(File)}. * Once the user has an instance of the class it can try to {@link #grabLock()}, true is returned * if the file could be grabbed otherwise false is returned. * When the process wants to release the lock it asks for the <code>FileLock</code> instance and * activates the {@link #releaseLock()} method. * * @author goland,dan hirsch */ public class FileLock { /** * Static map of all locks which are currently open. * The key for the lock is file's canonical path. */ private static Map<String,FileLock> fileLockMap = new HashMap<String, FileLock>(); /** * The file which serves as a semaphore for this FileLock instance. */ private File lockFile; private FileOutputStream outStream; private java.nio.channels.FileLock lock; /** * Returns a <code>FileLock</code> instance for a given <code>File</code> */ public synchronized static FileLock getFileLock(File file) throws Exception{ FileLock lock = fileLockMap.get(file.getCanonicalPath()); if (lock == null){ lock = new FileLock(file); } fileLockMap.put(file.getCanonicalPath(),lock); return lock; } /** */ private FileLock(File file){ this.lockFile = file; } /** * Tries to grab a lock (open and output stream) on the <code>File</code> with which the <code>FileLock</code> * was created. * If the file can be grabbed the method returns true, otherwise false; */ public boolean grabLock() throws Exception { outStream = new FileOutputStream(lockFile); try{ lock = outStream.getChannel().tryLock(); }catch(OverlappingFileLockException e){ return false; } //if succeed in getting lock return true if(lock != null && lock.isValid()){ return true; } return false; } /** * Releases lock (closes file output stream) */ public void releaseLock() throws Exception { if(lock != null && lock.isValid()){ lock.release(); } if (outStream != null){ outStream.close(); } } }