001package org.apache.archiva.common.filelock; 002 003/* 004 * Licensed to the Apache Software Foundation (ASF) under one 005 * or more contributor license agreements. See the NOTICE file 006 * distributed with this work for additional information 007 * regarding copyright ownership. The ASF licenses this file 008 * to you under the Apache License, Version 2.0 (the 009 * "License"); you may not use this file except in compliance 010 * with the License. You may obtain a copy of the License at 011 * 012 * http://www.apache.org/licenses/LICENSE-2.0 013 * 014 * Unless required by applicable law or agreed to in writing, 015 * software distributed under the License is distributed on an 016 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 017 * KIND, either express or implied. See the License for the 018 * specific language governing permissions and limitations 019 * under the License. 020 */ 021 022import java.io.Closeable; 023import java.io.File; 024import java.io.FileNotFoundException; 025import java.io.IOException; 026import java.io.RandomAccessFile; 027import java.nio.channels.FileChannel; 028import java.nio.channels.FileLock; 029import java.util.HashMap; 030import java.util.Map; 031import java.util.concurrent.atomic.AtomicBoolean; 032import java.util.concurrent.atomic.AtomicInteger; 033 034/** 035 * @author Olivier Lamy 036 * @since 2.0.0 037 */ 038public class Lock 039{ 040 private File file; 041 042 private AtomicBoolean write; 043 044 private final Map<Thread, AtomicInteger> fileClients = new HashMap<>(); 045 046 private FileLock fileLock; 047 048 private RandomAccessFile randomAccessFile; 049 050 private FileChannel fileChannel; 051 052 public Lock( File file ) 053 { 054 this.file = file; 055 } 056 057 public Lock( File file, boolean write ) 058 throws FileNotFoundException 059 { 060 this.file = file; 061 this.write = new AtomicBoolean( write ); 062 randomAccessFile = new RandomAccessFile( file, write ? "rw" : "r" ); 063 fileChannel = randomAccessFile.getChannel(); 064 } 065 066 public File getFile() 067 { 068 return file; 069 } 070 071 public AtomicBoolean isWrite() 072 { 073 return write; 074 } 075 076 public void setFile( File file ) 077 { 078 this.file = file; 079 } 080 081 public void setWrite( boolean write ) 082 { 083 this.write.set( write ); 084 } 085 086 public boolean isShared() 087 { 088 return this.fileLock.isValid() && this.fileLock.isShared(); 089 } 090 091 public boolean isValid() 092 { 093 return this.fileLock!=null && this.fileLock.isValid(); 094 } 095 096 public Map<Thread, AtomicInteger> getFileClients() 097 { 098 return fileClients; 099 } 100 101 public void addFileClient( Thread thread ) 102 { 103 this.fileClients.put( thread, new AtomicInteger( 1 ) ); 104 } 105 106 public boolean removeFileClient( Thread thread ) 107 { 108 return this.fileClients.remove( thread ) != null; 109 } 110 111 protected void close() 112 throws IOException 113 { 114 IOException ioException = null; 115 try 116 { 117 this.fileLock.release(); 118 } 119 catch ( IOException e ) 120 { 121 ioException = e; 122 } 123 124 closeQuietly( fileChannel ); 125 closeQuietly( randomAccessFile ); 126 127 fileClients.remove( Thread.currentThread() ); 128 129 if ( ioException != null ) 130 { 131 throw ioException; 132 } 133 134 } 135 136 protected void openLock( boolean write, boolean timeout ) 137 throws IOException 138 { 139 fileClients.put( Thread.currentThread(), new AtomicInteger( 1 ) ); 140 141 this.fileLock = timeout 142 ? fileChannel.tryLock( 0L, Long.MAX_VALUE, write ? false : true ) 143 : fileChannel.lock( 0L, Long.MAX_VALUE, write ? false : true ); 144 145 } 146 147 protected RandomAccessFile getRandomAccessFile() 148 { 149 return randomAccessFile; 150 } 151 152 private void closeQuietly( Closeable closeable ) 153 { 154 try 155 { 156 closeable.close(); 157 } 158 catch ( IOException e ) 159 { 160 // ignore 161 } 162 } 163 164 165 @Override 166 public String toString() 167 { 168 final StringBuilder sb = new StringBuilder( "Lock{" ); 169 sb.append( "file=" ).append( file ); 170 sb.append( '}' ); 171 return sb.toString(); 172 } 173}