001/*
002 * ============================================================================
003 *  Copyright © 2002-2021 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 *  <pre><code>  …
034 *  final var lock = new ReentrantLock();
035 *  final var executor = LockExecutor.of( lock );
036 *  …
037 *  executor.execute( () -> doSomething() );
038 *  …</code></pre>
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 1097 2024-02-06 20:10:12Z tquadrat $
044 *  @extauthor Thomas Thrien - thomas.thrien@tquadrat.org
045 *  @UMLGraph.link
046 *  @since 0.1.0
047 */
048@ClassVersion( sourceVersion = "$Id: LockExecutor.java 1097 2024-02-06 20:10:12Z 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     */
074    public void execute( final Action action ) throws ExecutionFailedException;
075
076    /**
077     *  Executes the given operation.
078     *
079     *  @param  <R> The type of the operation's result.
080     *  @param  operation   The operation.
081     *  @return An instance of
082     *      {@link Optional}
083     *      that holds the result of the operation.
084     *  @throws ExecutionFailedException    The operation failed for some
085     *      reason.
086     */
087    public <R> Optional<R> execute( final Operation<R> operation ) throws ExecutionFailedException;
088
089    /**
090     *  Creates a new {@code LockExecutor} from the given
091     *  {@link Lock}
092     *  instance.
093     *
094     *  @param  lock    The lock.
095     *  @return The new {@code LockExecutor}.
096     */
097    @API( status = STABLE, since = "0.1.0" )
098    public static LockExecutor of( final Lock lock )
099    {
100        final var retValue = LockExecutorImpl.of( lock );
101
102        //---* Done *----------------------------------------------------------
103        return retValue;
104    }   //  of()
105
106    /**
107     *  Creates a new {@code LockExecutor} from the given
108     *  {@link AutoLock}
109     *  instance.
110     *
111     *  @param  lock    The lock.
112     *  @return The new {@code LockExecutor}.
113     */
114    @API( status = STABLE, since = "0.1.0" )
115    public static LockExecutor of( final AutoLock lock )
116    {
117        final var retValue = LockExecutorImpl.of( lock );
118
119        //---* Done *----------------------------------------------------------
120        return retValue;
121    }   //  of()
122}
123//  interface LockExecutor
124
125/*
126 *  End of File
127 */