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

org.testifyproject.failsafe.Functions Maven / Gradle / Ivy

There is a newer version: 1.0.6
Show newest version
/*
 * Copyright 2016 the original 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.testifyproject.failsafe;

import java.util.concurrent.Callable;
import java.util.concurrent.Semaphore;

import org.testifyproject.failsafe.function.AsyncCallable;
import org.testifyproject.failsafe.function.AsyncRunnable;
import org.testifyproject.failsafe.function.CheckedBiConsumer;
import org.testifyproject.failsafe.function.CheckedBiFunction;
import org.testifyproject.failsafe.function.CheckedConsumer;
import org.testifyproject.failsafe.function.CheckedFunction;
import org.testifyproject.failsafe.function.CheckedRunnable;
import org.testifyproject.failsafe.function.ContextualCallable;
import org.testifyproject.failsafe.function.ContextualRunnable;
import org.testifyproject.failsafe.internal.util.Assert;

/**
 * Utilities and adapters for creating functions.
 * 
 * @author Jonathan Halterman
 */
final class Functions {
  static abstract class AsyncCallableWrapper implements Callable {
    protected AsyncExecution execution;

    void inject(AsyncExecution execution) {
      this.execution = execution;
    }
  }

  static abstract class ContextualCallableWrapper implements Callable {
    protected ExecutionContext context;

    void inject(ExecutionContext context) {
      this.context = context;
    }
  }

  static  AsyncCallableWrapper asyncOf(final AsyncCallable callable) {
    Assert.notNull(callable, "callable");
    return new AsyncCallableWrapper() {
      @Override
      public synchronized T call() throws Exception {
        try {
          execution.before();
          T result = callable.call(execution);
          return result;
        } catch (Throwable e) {
          execution.completeOrRetry(null, e);
          return null;
        }
      }
    };
  }

  static  AsyncCallableWrapper asyncOf(final AsyncRunnable runnable) {
    Assert.notNull(runnable, "runnable");
    return new AsyncCallableWrapper() {
      @Override
      public synchronized T call() throws Exception {
        try {
          execution.before();
          runnable.run(execution);
        } catch (Throwable e) {
          execution.completeOrRetry(null, e);
        }

        return null;
      }
    };
  }

  static  AsyncCallableWrapper asyncOf(final Callable callable) {
    Assert.notNull(callable, "callable");
    return new AsyncCallableWrapper() {
      @Override
      public T call() throws Exception {
        try {
          execution.before();
          T result = callable.call();
          execution.completeOrRetry(result, null);
          return result;
        } catch (Throwable e) {
          execution.completeOrRetry(null, e);
          return null;
        }
      }
    };
  }

  static  AsyncCallableWrapper asyncOf(final CheckedRunnable runnable) {
    Assert.notNull(runnable, "runnable");
    return new AsyncCallableWrapper() {
      @Override
      public T call() throws Exception {
        try {
          execution.before();
          runnable.run();
          execution.completeOrRetry(null, null);
        } catch (Throwable e) {
          execution.completeOrRetry(null, e);
        }

        return null;
      }
    };
  }

  static  AsyncCallableWrapper asyncOf(final ContextualCallable callable) {
    Assert.notNull(callable, "callable");
    return new AsyncCallableWrapper() {
      @Override
      public T call() throws Exception {
        try {
          execution.before();
          T result = callable.call(execution);
          execution.completeOrRetry(result, null);
          return result;
        } catch (Throwable e) {
          execution.completeOrRetry(null, e);
          return null;
        }
      }
    };
  }

  static  AsyncCallableWrapper asyncOf(final ContextualRunnable runnable) {
    Assert.notNull(runnable, "runnable");
    return new AsyncCallableWrapper() {
      @Override
      public T call() throws Exception {
        try {
          execution.before();
          runnable.run(execution);
          execution.completeOrRetry(null, null);
        } catch (Throwable e) {
          execution.completeOrRetry(null, e);
        }

        return null;
      }
    };
  }

  static  AsyncCallableWrapper asyncOfFuture(
      final AsyncCallable> callable) {
    Assert.notNull(callable, "callable");
    return new AsyncCallableWrapper() {
      Semaphore asyncFutureLock = new Semaphore(1);

      @Override
      public T call() throws Exception {
        try {
          execution.before();
          asyncFutureLock.acquire();
          callable.call(execution).whenComplete(new java.util.function.BiConsumer() {
            @Override
            public void accept(T innerResult, Throwable failure) {
              try {
                if (failure != null)
                  execution.completeOrRetry(innerResult,
                      failure instanceof java.util.concurrent.CompletionException ? failure.getCause() : failure);
              } finally {
                asyncFutureLock.release();
              }
            }
          });
        } catch (Throwable e) {
          try {
            execution.completeOrRetry(null, e);
          } finally {
            asyncFutureLock.release();
          }
        }

        return null;
      }
    };
  }

  static  AsyncCallableWrapper asyncOfFuture(final Callable> callable) {
    Assert.notNull(callable, "callable");
    return new AsyncCallableWrapper() {
      @Override
      public T call() throws Exception {
        try {
          execution.before();
          callable.call().whenComplete(new java.util.function.BiConsumer() {
            @Override
            public void accept(T innerResult, Throwable failure) {
              // Unwrap CompletionException cause
              if (failure != null && failure instanceof java.util.concurrent.CompletionException)
                failure = failure.getCause();
              execution.completeOrRetry(innerResult, failure);
            }
          });
        } catch (Throwable e) {
          execution.completeOrRetry(null, e);
        }

        return null;
      }
    };
  }

  static  AsyncCallableWrapper asyncOfFuture(
      final ContextualCallable> callable) {
    Assert.notNull(callable, "callable");
    return new AsyncCallableWrapper() {
      @Override
      public T call() throws Exception {
        try {
          execution.before();
          callable.call(execution).whenComplete(new java.util.function.BiConsumer() {
            @Override
            public void accept(T innerResult, Throwable failure) {
              // Unwrap CompletionException cause
              if (failure != null && failure instanceof java.util.concurrent.CompletionException)
                failure = failure.getCause();
              execution.completeOrRetry(innerResult, failure);
            }
          });
        } catch (Throwable e) {
          execution.completeOrRetry(null, e);
        }

        return null;
      }
    };
  }

  static  Callable callableOf(final CheckedRunnable runnable) {
    Assert.notNull(runnable, "runnable");
    return new Callable() {
      @Override
      public T call() throws Exception {
        runnable.run();
        return null;
      }
    };
  }

  static  Callable callableOf(final ContextualCallable callable) {
    Assert.notNull(callable, "callable");
    return new ContextualCallableWrapper() {
      @Override
      public T call() throws Exception {
        T result = callable.call(context);
        return result;
      }
    };
  }

  static  Callable callableOf(final ContextualRunnable runnable) {
    Assert.notNull(runnable, "runnable");
    return new ContextualCallableWrapper() {
      @Override
      public T call() throws Exception {
        runnable.run(context);
        return null;
      }
    };
  }

  static  CheckedBiFunction fnOf(final Callable callable) {
    return new CheckedBiFunction() {
      @Override
      public R apply(T t, U u) throws Exception {
        return callable.call();
      }
    };
  }

  static  CheckedBiFunction fnOf(final CheckedBiConsumer consumer) {
    return new CheckedBiFunction() {
      @Override
      public R apply(T t, U u) throws Exception {
        consumer.accept(t, u);
        return null;
      }
    };
  }

  static  CheckedBiFunction fnOf(final CheckedConsumer consumer) {
    return new CheckedBiFunction() {
      @Override
      public R apply(T t, U u) throws Exception {
        consumer.accept(u);
        return null;
      }
    };
  }

  static  CheckedBiFunction fnOf(final CheckedFunction function) {
    return new CheckedBiFunction() {
      @Override
      public R apply(T t, U u) throws Exception {
        return function.apply(u);
      }
    };
  }

  static  CheckedBiFunction fnOf(final CheckedRunnable runnable) {
    return new CheckedBiFunction() {
      @Override
      public R apply(T t, U u) throws Exception {
        runnable.run();
        return null;
      }
    };
  }

  static  CheckedBiFunction fnOf(final R result) {
    return new CheckedBiFunction() {
      @Override
      public R apply(T t, U u) throws Exception {
        return result;
      }
    };
  }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy