All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.cp.elements.lang.CodeBlocks Maven / Gradle / Ivy

/*
 * Copyright 2011-Present Author or Authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.cp.elements.lang;

import java.util.function.Function;
import java.util.function.Predicate;

import org.cp.elements.lang.annotation.NotNull;
import org.cp.elements.lang.annotation.Nullable;

/**
 * {@link CodeBlocks} is an abstract base class used to simplify code for common code blocks, such as
 * {@literal if-then-else} statements, {@literal try-catch} and {@literal try-catch-finally} blocks,
 * {@literal while-loops}, and so on.
 *
 * @author John Blum
 * @see java.lang.Runnable
 * @see java.util.function.Function
 * @see java.util.function.Predicate
 * @since 1.0.0
 */
@SuppressWarnings({ "AbstractClassName", "unused" })
public abstract class CodeBlocks {

  public static final Runnable NO_OP_RUNNABLE = () -> { };

  /**
   * Implementation of an {@literal if-else} code block.
   *
   * @param  {@link Class type} of the {@link Object target} processed in the {@literal if} statement.
   * @param  {@link Class type} of the {@link Object result} returned from the {@literal if} statement.
   * @param target {@link Object} to evaluate in the {@literal if} statement.
   * @param ifCondition {@link Predicate} used to evaluate the {@link Object target} in the {@literal if} condition.
   * @param ifBlock {@link Function} encapsulating the logic in the {@literal if} block.
   * @param elseBlock {@link Function} encapsulating the logic in the {@literal else} block.
   * @return the {@link Object result} from the evaluation of the {@literal if} statement.
   * @throws IllegalArgumentException if the {@link Predicate if-condition}, {@link Function if-block}
   * or the {@link Function else-block} are {@literal null}.
   * @see java.util.function.Function
   * @see java.util.function.Predicate
   */
  public static  R ifElse(@Nullable T target, @NotNull Predicate ifCondition,
      @NotNull Function ifBlock, @NotNull Function elseBlock) {

    Assert.notNull(ifCondition, "The Predicate used in the condition of the if statement is required");
    Assert.notNull(ifBlock, "The Function for the if block is required");
    Assert.notNull(elseBlock, "The Function for the else block is required");

    //return ifCondition.test(target) ? ifBlock.apply(target) : elseBlock.apply(target);

    if (ifCondition.test(target)) {
      return ifBlock.apply(target);
    }
    else {
      return elseBlock.apply(target);
    }
  }

  /**
   * Implementation of the {@literal try-catch} code block, which handles the {@link Throwable} object
   * by rethrowing a {@link RuntimeException} determined by the given, required {@link Function}.
   *
   * @param  {@link Class type} of the {@link Object result} from processing the code in the {@literal try} block.
   * @param tryBlock {@link Function} encapsulating the logic invoked in the {@literal try} block. The processing logic
   * in this case is capable of throwing an {@link Error} or {@link Exception}.
   * @param catchBlock {@link Function} used to convert the {@link Throwable} into a {@link RuntimeException}.
   * @return the {@link Object result} of processing the code in the {@literal try} block.
   * @throws IllegalArgumentException if the {@literal try-block} {@link ThrowableOperation} or {@link Throwable}
   * converting {@link Function} are {@literal null}.
   * @see #tryCatchFinally(ThrowableOperation, Function, Runnable)
   * @see org.cp.elements.lang.ThrowableOperation
   * @see java.util.function.Function
   */
  public static  T tryCatch(@NotNull ThrowableOperation tryBlock,
      @NotNull Function catchBlock) {

    return tryCatchFinally(tryBlock, catchBlock, NO_OP_RUNNABLE);
  }

  /**
   * Implementation of the {@literal try-catch} code block, which handles the {@link Throwable} object
   * by rethrowing a {@link RuntimeException} determined by the given, required {@link Function}.
   *
   * @param  {@link Class type} of the {@link Object result} from processing the code in the {@literal try} block.
   * @param tryBlock {@link Function} encapsulating the logic invoked in the {@literal try} block. The processing logic
   * in this case is capable of throwing an {@link Error} or {@link Exception}.
   * @param catchBlock {@link Function} used to convert the {@link Throwable} into a {@link RuntimeException}.
   * @param finallyBlock {@link Runnable} encapsulating the logic invoked in the {@literal finally} block.
   * @return the {@link Object result} of processing the code in the {@literal try} block.
   * @throws IllegalArgumentException if the {@literal try-block} {@link ThrowableOperation}, {@link Throwable}
   * converting {@link Function} or {@literal finally-block} {@link Runnable} are {@literal null}.
   * @see org.cp.elements.lang.ThrowableOperation
   * @see java.util.function.Function
   * @see java.lang.Runnable
   */
  public static  T tryCatchFinally(@NotNull ThrowableOperation tryBlock,
      @NotNull Function catchBlock, @NotNull Runnable finallyBlock) {

    Assert.notNull(tryBlock, "The ThrowableOperation invoked in the try block is required");
    Assert.notNull(catchBlock, "The Function converter invoked in the catch block is required");
    Assert.notNull(finallyBlock, "The Runnable invoked in the finally block is required");

    try {
      return tryBlock.run(ObjectUtils.EMPTY_OBJECT_ARRAY);
    }
    catch (Throwable cause) {
      throw catchBlock.apply(cause);
    }
    finally {
      finallyBlock.run();
    }
  }

  /**
   * Implementation of the {@literal try-catch} code block, which handles the {@link Throwable} object
   * by returning a {@link Object result}, such as an alternative {@link Object value}.
   *
   * @param  {@link Class type} of the {@link Object result} from processing the code in the {@literal try} block.
   * @param tryBlock {@link Function} encapsulating the logic invoked in the {@literal try} block. The processing logic
   * in this case is capable of throwing an {@link Error} or {@link Exception}.
   * @param catchBlock {@link Function} used to handle the {@link Throwable} and return a {@link Object result}.
   * @return the {@link Object result} of processing the code in the {@literal try} block if no {@link Error}
   * or {@link Exception} is thrown, or returns the {@link Object value} computed from the {@link Throwable}
   * {@link Function} handler.
   * @throws IllegalArgumentException if the {@literal try-block} {@link ThrowableOperation} or {@link Throwable}
   * handling {@link Function} are {@literal null}.
   * @see #tryHandleFinally(ThrowableOperation, Function, Runnable)
   * @see org.cp.elements.lang.ThrowableOperation
   * @see java.util.function.Function
   */
  public static  T tryHandle(@NotNull ThrowableOperation tryBlock, @NotNull Function catchBlock) {
    return tryHandleFinally(tryBlock, catchBlock, NO_OP_RUNNABLE);
  }

  /**
   * Implementation of the {@literal try-catch} code block, which handles the {@link Throwable} object
   * by returning a {@link Object result}, such as an alternative {@link Object value}.
   *
   * @param  {@link Class type} of the {@link Object result} from processing the code in the {@literal try} block.
   * @param tryBlock {@link Function} encapsulating the logic invoked in the {@literal try} block. The processing logic
   * in this case is capable of throwing an {@link Error} or {@link Exception}.
   * @param catchBlock {@link Function} used to handle the {@link Throwable} and return a {@link Object result}.
   * @param finallyBlock {@link Runnable} encapsulating the logic invoked in the {@literal finally} block.
   * @return the {@link Object result} of processing the code in the {@literal try} block if no {@link Error}
   * or {@link Exception} is thrown, or returns the {@link Object value} computed from the {@link Throwable}
   * {@link Function} handler.
   * @throws IllegalArgumentException if the {@literal try-block} {@link ThrowableOperation} or {@link Throwable}
   * handling {@link Function} are {@literal null}.
   * @see org.cp.elements.lang.ThrowableOperation
   * @see java.util.function.Function
   * @see java.lang.Runnable
   */
  public static  T tryHandleFinally(@NotNull ThrowableOperation tryBlock,
      @NotNull Function catchBlock, @NotNull Runnable finallyBlock) {

    Assert.notNull(tryBlock, "The ThrowableOperation invoked in the try block is required");
    Assert.notNull(catchBlock, "The Function handler invoked in the catch block is required");
    Assert.notNull(finallyBlock, "The Runnable invoked in the finally block is required");

    try {
      return tryBlock.run(ObjectUtils.EMPTY_OBJECT_ARRAY);
    }
    catch (Throwable cause) {
      return catchBlock.apply(cause);
    }
    finally {
      finallyBlock.run();
    }
  }

  /**
   * Implementation of the {@literal while-loop} code block.
   *
   * @param  {@link Class type} of the {@link Object target} being processed in the {@literal while-loop}.
   * @param target {@link Object} being processed in the {@literal while-loop}
   * @param whileCondition {@link Predicate} encapsulating the condition used in the {@literal while-loop}.
   * @param whileBlock {@link Function} encapsulating the logic used to process the {@link Object target}
   * for each iteration of the {@literal while-loop}.
   * @return the {@link Object result} of processing the {@link Object target} in the {@literal while-loop}.
   * @see java.util.function.Function
   * @see java.util.function.Predicate
   */
  public static  T whileLoop(@Nullable T target,
      @NotNull Predicate whileCondition, @NotNull Function whileBlock) {

    Assert.notNull(whileCondition, "The condition for the while-loop is required");
    Assert.notNull(whileBlock, "The Function of the while-loop is required");

    T result = target;

    while (whileCondition.test(result)) {
      result = whileBlock.apply(result);
    }

    return result;
  }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy