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

com.codepoetics.fluvius.execution.KeyCheckingFlowExecution Maven / Gradle / Ivy

There is a newer version: 1.10
Show newest version
package com.codepoetics.fluvius.execution;

import com.codepoetics.fluvius.api.*;
import com.codepoetics.fluvius.api.scratchpad.Key;
import com.codepoetics.fluvius.api.scratchpad.KeyValue;
import com.codepoetics.fluvius.api.scratchpad.Scratchpad;
import com.codepoetics.fluvius.exceptions.MissingKeysException;
import com.codepoetics.fluvius.scratchpad.Scratchpads;

import java.util.HashSet;
import java.util.Set;
import java.util.UUID;

/**
 * Flow execution that checks that all required keys are provided before executing the flow.
 * @param  The type of value returned by executing the flow.
 */
public final class KeyCheckingFlowExecution extends AbstractFlowExecution {

  /**
   * Create a key-checking flow execution using the supplied flow and visitor.
   * @param flow The flow to build flow execution for.
   * @param visitor The visitor to use to compile the flow.
   * @param  The type of value returned by executing the flow.
   * @return The constructed flow execution.
   */
  public static  FlowExecution forFlow(Flow flow, FlowVisitor visitor) {
    return forAction(flow.visit(visitor), flow.getRequiredKeys(), flow.getProvidedKey());
  }

  static  FlowExecution forAction(Action action, Set> requiredKeys, Key providedKey) {
    return new KeyCheckingFlowExecution<>(action, requiredKeys, providedKey);
  }

  private final Action action;
  private final Set> requiredKeys;
  private final Key providedKey;

  KeyCheckingFlowExecution(Action action, Set> requiredKeys, Key providedKey) {
    this.action = action;
    this.requiredKeys = requiredKeys;
    this.providedKey = providedKey;
  }

  private Set> getMissingKeys(Scratchpad initialScratchpad) {
    Set> missingKeys = new HashSet<>();
    for (Key requiredKey : requiredKeys) {
      if (!initialScratchpad.containsKey(requiredKey)) {
        missingKeys.add(requiredKey);
      }
    }
    return missingKeys;
  }

  @Override
  public T run(UUID flowId, Scratchpad initialScratchpad) throws Exception {
    Set> missingKeys = getMissingKeys(initialScratchpad);

    if (!missingKeys.isEmpty()) {
      throw MissingKeysException.create(missingKeys);
    }

    Scratchpad finalScratchpad = action.run(flowId, initialScratchpad.locked());

    if (finalScratchpad.isSuccessful(providedKey)) {
      return finalScratchpad.get(providedKey);
    } else {
      throw (finalScratchpad.getFailureReason(providedKey));
    }
  }

  @Override
  public T run(UUID flowId, KeyValue... initialKeyValues) throws Exception {
    return run(flowId, Scratchpads.create(initialKeyValues));
  }

  @Override
  public Runnable asAsync(UUID flowId, FlowResultCallback callback, Scratchpad initialScratchpad) {
    return new RunWithCallback<>(flowId, initialScratchpad, callback, this);
  }

  private static final class RunWithCallback implements Runnable {
    private final UUID flowId;
    private final Scratchpad initialScratchpad;
    private final FlowResultCallback callback;
    private final KeyCheckingFlowExecution execution;

    private RunWithCallback(UUID flowId, Scratchpad initialScratchpad, FlowResultCallback callback, KeyCheckingFlowExecution execution) {
      this.flowId = flowId;
      this.initialScratchpad = initialScratchpad;
      this.callback = callback;
      this.execution = execution;
    }

    @Override
    public void run() {
      T result = null;
      try {
        result = execution.run(flowId, initialScratchpad);
      } catch (Exception e) {
        callback.onFailure(flowId, e);
      }
      if (result != null) {
        callback.onSuccess(flowId, result);
      }
    }
  }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy