package org.jfrog.wharf.ivy.lock; import org.apache.ivy.util.Message; import java.io.File; import java.io.IOException; import java.io.RandomAccessFile; import java.nio.channels.FileChannel; import java.nio.channels.FileLock; import java.nio.channels.OverlappingFileLockException; import static org.jfrog.wharf.ivy.util.WharfUtils.closeQuietly; /** * Locks a file using the {@link java.nio.channels.FileLock} mechanism. */ public class NioFileLockHolder extends BaseFileLockHolder { private FileLock lock; private RandomAccessFile raf; private FileChannel channel; public NioFileLockHolder(LockHolderFactory factory, File protectedFile) { super(factory, protectedFile); } private void initChannel() throws IOException { if (channel != null && channel.isOpen()) { return; } verifyParentDir(); if (lockFile.createNewFile()) { lockFile.deleteOnExit(); } raf = new RandomAccessFile(lockFile, "rw"); channel = raf.getChannel(); } public void close() { closeQuietly(raf); raf = null; channel = null; lock = null; } @Override public synchronized boolean acquireLock() { try { initChannel(); if (lock != null) { setLastMessage("NIO lock already taken"); if (getLogger().isDebugEnabled()) { getLogger().log(stateMessage()); } return false; } lock = channel.tryLock(); if (lock != null) { return true; } else { setLastMessage("Failed to acquire NIO file lock on " + lockFile.getAbsolutePath()); if (getLogger().isDebugEnabled()) { getLogger().log(stateMessage()); } } } catch (OverlappingFileLockException e) { setLastMessage("Trying to acquire a file lock already acquired in the same JVM: " + e.getMessage()); Message.verbose(stateMessage()); close(); } catch (IOException e) { setLastMessage("File lock failed due to an exception: " + e.getMessage()); Message.verbose(stateMessage()); close(); } return false; } @Override public synchronized void releaseLock() { if (lock == null) { setLastMessage(" file not previously locked: " + lockFile); return; } try { lock.release(); } catch (IOException e) { setLastMessage("File lock release failed due to an exception: " + e.getMessage()); Message.error(stateMessage()); close(); } finally { lock = null; } } }