package org.vamsas.client.simpleclient; import java.io.BufferedOutputStream; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import java.io.RandomAccessFile; public class FileLock extends Lock { File _lock = null; protected static String _LockSuffix="lck"; /** * call to clear up a filelock file after its been made * */ private void tidy() { if (_lock!=null) { _lock.delete(); _lock=null; } } /** * @param lockfile */ public FileLock(File lockfile) { super(lockfile); // try and get a lock. try { _lock = new File(lockfile.getParentFile(), lockfile.getName()+"."+_LockSuffix); if (_lock.exists() || !_lock.createNewFile()) { log.debug("Failed to get lock for "+lockfile+" using lockfile "+_lock); _lock=null; return; } _lock.deleteOnExit(); // safe - all locks should be removed on finalization. // create target file ready to be written to if necessary. if (!lockfile.exists()) if (!lockfile.createNewFile()) { log.warn("Failed to create locked file "+lockfile); return; } openRaFile(); } catch (FileNotFoundException e) { // log.debug("FileLock failed with target="+lockfile+" and lockfile suffix of "+_LockSuffix); //log.error("Error! Couldn't create a lockfile at " // + lockfile.getAbsolutePath(), e); } catch (IOException e) { log.error("Error! Problems with IO when creating a lock on " + lockfile.getAbsolutePath(),e); } } private boolean openRaFile() throws IOException { if (target==null) return false; if (_lock==null || !_lock.exists()) return false; if (rafile==null) rafile=new RandomAccessFile(target,"rw"); return (rafile.getChannel()!=null) && rafile.getChannel().isOpen(); } public boolean isLocked() { if (_lock != null) { if (_lock.exists()) return true; _lock=null; if (log.isDebugEnabled()) log.debug("Lockfile "+_lock+" unexpectedly deleted ?"); } return false; } public void release() { release(true); } public void release(boolean closeChannel) { if (_lock==null) return; if (closeChannel) { if (rafile!=null) try { rafile.close(); } catch (Exception e) { log.debug("Unexpected exception whilst closing RandomAccessFile on "+target, e); } rafile=null; } tidy(); } public FileInputStream getFileInputStream(boolean atStart) throws IOException { if (!isLocked()) return null; openRaFile(); if (atStart) rafile.seek(0); return new FileInputStream(rafile.getFD()); } public FileOutputStream getFileOutputStream(boolean clear) throws IOException { if (!isLocked()) return null; openRaFile(); if (clear) rafile.setLength(0); else rafile.seek(rafile.length()); return new LockedFileOutputStream(rafile.getFD()); } public BufferedOutputStream getBufferedOutputStream(boolean clear) throws IOException { FileOutputStream fos = getFileOutputStream(clear); if (fos!=null) return new BufferedOutputStream(fos); return null; } protected void finalize() throws Throwable { release(true); // we explicitly lose the lock here. super.finalize(); } }