001/* 002 * ============================================================================ 003 * Copyright © 2002-2020 by Thomas Thrien. 004 * All Rights Reserved. 005 * ============================================================================ 006 * 007 * Licensed to the public under the agreements of the GNU Lesser General Public 008 * License, version 3.0 (the "License"). You may obtain a copy of the License at 009 * 010 * http://www.gnu.org/licenses/lgpl.html 011 * 012 * Unless required by applicable law or agreed to in writing, software 013 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 014 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 015 * License for the specific language governing permissions and limitations 016 * under the License. 017 */ 018 019package org.tquadrat.foundation.lang.internal; 020 021import static org.apiguardian.api.API.Status.INTERNAL; 022import static org.tquadrat.foundation.lang.Objects.requireNonNullArgument; 023 024import java.util.Optional; 025import java.util.concurrent.locks.Condition; 026import java.util.concurrent.locks.Lock; 027import java.util.concurrent.locks.ReentrantLock; 028 029import org.apiguardian.api.API; 030import org.tquadrat.foundation.annotation.ClassVersion; 031import org.tquadrat.foundation.annotation.NotRecord; 032import org.tquadrat.foundation.lang.Action; 033import org.tquadrat.foundation.lang.AutoLock; 034import org.tquadrat.foundation.lang.Constraint; 035import org.tquadrat.foundation.lang.Operation; 036 037/** 038 * The implementation of 039 * {@link AutoLock}. 040 * 041 * @extauthor Thomas Thrien - thomas.thrien@tquadrat.org 042 * @version $Id: AutoLockImpl.java 1185 2026-04-06 10:26:47Z tquadrat $ 043 * @since 0.1.0 044 * 045 * @see java.util.concurrent.locks.Lock 046 * 047 * @UMLGraph.link 048 */ 049@ClassVersion( sourceVersion = "$Id: AutoLockImpl.java 1185 2026-04-06 10:26:47Z tquadrat $" ) 050@API( status = INTERNAL, since = "0.1.0" ) 051@NotRecord 052public final class AutoLockImpl implements AutoLock 053{ 054 /*------------*\ 055 ====** Attributes **======================================================= 056 \*------------*/ 057 /** 058 * The wrapped lock. 059 */ 060 private final Lock m_Lock; 061 062 /*--------------*\ 063 ====** Constructors **===================================================== 064 \*--------------*/ 065 /** 066 * Creates a new {@code AutoLockImpl} instance. 067 * 068 * @param lock The wrapped lock. 069 */ 070 public AutoLockImpl( final Lock lock ) 071 { 072 super(); 073 m_Lock = requireNonNullArgument( lock, "lock" ); 074 } // AutoLockImpl() 075 076 /** 077 * Creates a new {@code AutoLockImpl} instance with an internal lock 078 * object. 079 */ 080 public AutoLockImpl() { this( new ReentrantLock() ); } 081 082 /*---------*\ 083 ====** Methods **========================================================== 084 \*---------*/ 085 /** 086 * {@inheritDoc} 087 */ 088 @SuppressWarnings( "ProhibitedExceptionCaught" ) 089 @Override 090 public final void close() 091 { 092 try 093 { 094 m_Lock.unlock(); 095 } 096 catch( final IllegalMonitorStateException ignored ) { /* Deliberately ignored */ } 097 } // close() 098 099 /** 100 * {@inheritDoc} 101 */ 102 @SuppressWarnings( "OverlyBroadCatchBlock" ) 103 @Override 104 public final boolean evaluate( final Constraint constraint ) throws ExecutionFailedException 105 { 106 requireNonNullArgument( constraint, "condition" ); 107 final boolean retValue; 108 try( final var _ = lock() ) 109 { 110 retValue = constraint.evaluate(); 111 } 112 /* 113 * Catching java.lang.Throwable is required here to wrap really all 114 * thrown exceptions into an ExecutionFailedException. 115 */ 116 catch( final Throwable t ) 117 { 118 throw new ExecutionFailedException( t ); 119 } 120 121 //---* Done *---------------------------------------------------------- 122 return retValue; 123 } // evaluate() 124 125 /** 126 * {@inheritDoc} 127 */ 128 @SuppressWarnings( "OverlyBroadCatchBlock" ) 129 @Override 130 public <R> Optional<R> execute( final Operation<? extends R> verification ) throws ExecutionFailedException 131 { 132 requireNonNullArgument( verification, "operation" ); 133 final Optional<R> retValue; 134 try( final var _ = lock() ) 135 { 136 retValue = Optional.ofNullable( verification.get() ); 137 } 138 /* 139 * Catching java.lang.Throwable is required here to wrap really all 140 * thrown exceptions into an ExecutionFailedException. 141 */ 142 catch( final Throwable t ) 143 { 144 throw new ExecutionFailedException( t ); 145 } 146 147 //---* Done *---------------------------------------------------------- 148 return retValue; 149 } // execute() 150 151 /** 152 * {@inheritDoc} 153 */ 154 @Override 155 public final Lock getWrappedLockInstance() { return m_Lock; } 156 157 /** 158 * {@inheritDoc} 159 */ 160 @SuppressWarnings( "LockAcquiredButNotSafelyReleased" ) 161 @Override 162 public final AutoLock lock() 163 { 164 m_Lock.lock(); 165 166 //---* Done *---------------------------------------------------------- 167 return this; 168 } // lock() 169 170 /** 171 * {@inheritDoc} 172 */ 173 @SuppressWarnings( "LockAcquiredButNotSafelyReleased" ) 174 @Override 175 public final AutoLock lockInterruptibly() throws InterruptedException 176 { 177 m_Lock.lockInterruptibly(); 178 179 //---* Done *---------------------------------------------------------- 180 return this; 181 } // lockInterruptibly() 182 183 /** 184 * {@inheritDoc} 185 */ 186 @Override 187 public final Condition newCondition() { return m_Lock.newCondition(); } 188 189 /** 190 * {@inheritDoc} 191 */ 192 @SuppressWarnings( "OverlyBroadCatchBlock" ) 193 @Override 194 public void perform( final Action action ) throws ExecutionFailedException 195 { 196 requireNonNullArgument( action, "action" ); 197 try( final var _ = lock() ) 198 { 199 action.run(); 200 } 201 /* 202 * Catching java.lang.Throwable is required here to wrap really all 203 * thrown exceptions into an ExecutionFailedException. 204 */ 205 catch( final Throwable t ) 206 { 207 throw new ExecutionFailedException( t ); 208 } 209 } // perform() 210} 211// class AutoLock 212 213/* 214 * End of File 215 */