001/* 002 * ============================================================================ 003 * Copyright © 2002-2026 by Thomas Thrien. 004 * All Rights Reserved. 005 * ============================================================================ 006 * Licensed to the public under the agreements of the GNU Lesser General Public 007 * License, version 3.0 (the "License"). You may obtain a copy of the License at 008 * 009 * http://www.gnu.org/licenses/lgpl.html 010 * 011 * Unless required by applicable law or agreed to in writing, software 012 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 013 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 014 * License for the specific language governing permissions and limitations 015 * under the License. 016 */ 017 018package org.tquadrat.foundation.lang; 019 020import static org.apiguardian.api.API.Status.STABLE; 021 022import java.util.Optional; 023import java.util.concurrent.locks.Lock; 024 025import org.apiguardian.api.API; 026import org.tquadrat.foundation.annotation.ClassVersion; 027import org.tquadrat.foundation.lang.AutoLock.ExecutionFailedException; 028import org.tquadrat.foundation.lang.internal.LockExecutorImpl; 029 030/** 031 * <p>{@summary Allows to execute an operation with an obtained lock.}</p> 032 * <p>Use this class like below:</p> 033 * <div class="source-container"><pre>… 034 * final var lock = new ReentrantLock(); 035 * final var executor = LockExecutor.of( lock ); 036 * … 037 * executor.execute( () -> doSomething() ); 038 * …</pre></div> 039 * 040 * @note If your program is using {@code AutoLock}, you should use the 041 * corresponding methods from there. 042 * 043 * @version $Id: LockExecutor.java 1185 2026-04-06 10:26:47Z tquadrat $ 044 * @extauthor Thomas Thrien - thomas.thrien@tquadrat.org 045 * @UMLGraph.link 046 * @since 0.1.0 047 */ 048@ClassVersion( sourceVersion = "$Id: LockExecutor.java 1185 2026-04-06 10:26:47Z tquadrat $" ) 049@API( status = STABLE, since = "0.1.0" ) 050public sealed interface LockExecutor 051 permits LockExecutorImpl 052{ 053 /*---------*\ 054 ====** Methods **========================================================== 055 \*---------*/ 056 /** 057 * Evaluates the given condition. 058 * 059 * @param constraint The constraint. 060 * @return The result of the evaluation of the condition. 061 * @throws ExecutionFailedException The evaluation failed for some 062 * reason. 063 */ 064 @SuppressWarnings( "BooleanMethodNameMustStartWithQuestion" ) 065 public boolean evaluate( final Constraint constraint ) throws ExecutionFailedException; 066 067 /** 068 * Executes the given action. 069 * 070 * @param action The action. 071 * @throws ExecutionFailedException The action failed for some 072 * reason. 073 * @deprecated Use 074 * {@link #perform(Action)} 075 * instead; basically this method was renamed to avoid the unintended 076 * use of 077 * {@link #execute(Operation)} 078 * when an 079 * {@link Action} 080 * should be used instead. 081 */ 082 @Deprecated( since = "0.25.3", forRemoval = true ) 083 public default void execute( final Action action ) throws ExecutionFailedException 084 { 085 perform( action ); 086 } // execute() 087 088 /** 089 * Executes the given operation. 090 * 091 * @param <R> The type of the operation's result. 092 * @param operation The operation. 093 * @return An instance of 094 * {@link Optional} 095 * that holds the result of the operation. 096 * @throws ExecutionFailedException The operation failed for some 097 * reason. 098 */ 099 public <R> Optional<R> execute( final Operation<R> operation ) throws ExecutionFailedException; 100 101 /** 102 * Creates a new {@code LockExecutor} from the given 103 * {@link Lock} 104 * instance. 105 * 106 * @param lock The lock. 107 * @return The new {@code LockExecutor}. 108 */ 109 @API( status = STABLE, since = "0.1.0" ) 110 public static LockExecutor of( final Lock lock ) 111 { 112 final var retValue = LockExecutorImpl.of( lock ); 113 114 //---* Done *---------------------------------------------------------- 115 return retValue; 116 } // of() 117 118 /** 119 * Creates a new {@code LockExecutor} from the given 120 * {@link AutoLock} 121 * instance. 122 * 123 * @param lock The lock. 124 * @return The new {@code LockExecutor}. 125 */ 126 @API( status = STABLE, since = "0.1.0" ) 127 public static LockExecutor of( final AutoLock lock ) 128 { 129 final var retValue = LockExecutorImpl.of( lock ); 130 131 //---* Done *---------------------------------------------------------- 132 return retValue; 133 } // of() 134 135 /** 136 * <p>{@summary Performs the given action after obtaining the lock.}</p> 137 * <p>This differs from 138 * {@link #execute(Operation)} 139 * as 140 * {@link Action} 141 * does not return something, and a warning regarding "Result of 142 * assignment expression used" can be avoided in case the 143 * {@code action} is used to set an attribute.</p> 144 * 145 * @param action The action. 146 * @throws ExecutionFailedException The action failed for some reason. 147 */ 148 public void perform( final Action action ) throws ExecutionFailedException; 149} 150// interface LockExecutor 151 152/* 153 * End of File 154 */