001package org.eclipse.aether.named.hazelcast; 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.util.concurrent.ConcurrentHashMap; 023import java.util.concurrent.ConcurrentMap; 024import java.util.concurrent.TimeUnit; 025 026import com.hazelcast.core.HazelcastInstance; 027import com.hazelcast.cp.ISemaphore; 028import org.eclipse.aether.named.support.AdaptedSemaphoreNamedLock; 029import org.eclipse.aether.named.support.AdaptedSemaphoreNamedLock.AdaptedSemaphore; 030import org.eclipse.aether.named.support.NamedLockFactorySupport; 031 032import static java.util.Objects.requireNonNull; 033 034/** 035 * Factory of {@link AdaptedSemaphoreNamedLock} instances, using adapted Hazelcast {@link ISemaphore}. It delegates 036 * most the work to {@link HazelcastSemaphoreProvider} and this class just adapts the returned semaphore to named lock 037 * and caches {@link ISemaphore} instances, as recommended by Hazelcast. 038 */ 039public class HazelcastSemaphoreNamedLockFactory 040 extends NamedLockFactorySupport 041{ 042 protected final HazelcastInstance hazelcastInstance; 043 044 protected final boolean manageHazelcast; 045 046 private final HazelcastSemaphoreProvider hazelcastSemaphoreProvider; 047 048 private final ConcurrentMap<String, ISemaphore> semaphores; 049 050 public HazelcastSemaphoreNamedLockFactory( 051 final HazelcastInstance hazelcastInstance, 052 final boolean manageHazelcast, 053 final HazelcastSemaphoreProvider hazelcastSemaphoreProvider 054 ) 055 { 056 this.hazelcastInstance = requireNonNull( hazelcastInstance ); 057 this.manageHazelcast = manageHazelcast; 058 this.hazelcastSemaphoreProvider = requireNonNull( hazelcastSemaphoreProvider ); 059 this.semaphores = new ConcurrentHashMap<>(); 060 } 061 062 @Override 063 protected AdaptedSemaphoreNamedLock createLock( final String name ) 064 { 065 ISemaphore semaphore = semaphores.computeIfAbsent( name, 066 k -> hazelcastSemaphoreProvider.acquireSemaphore( hazelcastInstance, name ) ); 067 return new AdaptedSemaphoreNamedLock( name, this, new HazelcastSemaphore( semaphore ) ); 068 } 069 070 @Override 071 protected void destroyLock( final String name ) 072 { 073 hazelcastSemaphoreProvider.releaseSemaphore( hazelcastInstance, name, semaphores.remove( name ) ); 074 } 075 076 @Override 077 public void shutdown() 078 { 079 if ( manageHazelcast ) 080 { 081 hazelcastInstance.shutdown(); 082 } 083 } 084 085 private static final class HazelcastSemaphore implements AdaptedSemaphore 086 { 087 private final ISemaphore semaphore; 088 089 private HazelcastSemaphore( final ISemaphore semaphore ) 090 { 091 this.semaphore = semaphore; 092 } 093 094 @Override 095 public boolean tryAcquire( final int perms, final long time, final TimeUnit unit ) 096 throws InterruptedException 097 { 098 return semaphore.tryAcquire( perms, time, unit ); 099 } 100 101 @Override 102 public void release( final int perms ) 103 { 104 semaphore.release( perms ); 105 } 106 } 107}