Class RecipeExtractor

java.lang.Object
com.tccc.kos.ext.dispense.pipeline.beverage.RecipeExtractor

public class RecipeExtractor extends Object
Given a GraphNode (typically a BeverageNode), search for all ingredients under the node, and for each found ingredient, select the available pump with the highest rank.

If a pump is found for every ingredient below the root node, then the recipe is considered valid and therefore isValid() returns true.

If any pumps are missing, then getMissingIngredients() identifies the ingredients that did not have an available pump (assuming that the ingredients were found). If valid, the list of pumps from getPumps() indicates the pumps to use to pour the desired beverage.

This search expects that ingredients are children of the specified node, and any child node that is not an ingredient implies an invalid recipe. This matches a typical pattern of dependencies:

    pump -> ingredient -> beverage
 
This implies that even beverages with a single ingredient (such as water) should still follow this pattern.

This can be used with simple BiB configurations, where each BiB is combined with water/carb to form a beverage, but can also be used with BiB plus flavor shots. While there are any number of approaches to handling flavors, two approaches that work with this search are:

  • Create a beverage node for each variation of the base beverage and flavor. If there is one beverage (Coke) and one flavor (cherry), then this approach results in two beverages: Coke and Coke+cherry. This search will work on either beverage.
  • Create a set of base beverages and then create a group with flavor beverages (pump -> ingredient -> flavorBev). When a user selects a flavor with a beverage, send both IDs back and in the model lookup both beverages and combine the list of pumps.

When holding a value to represent a selected beverage, use the beverageId, not the corresponding holder. If there is a graph rebuild, the nodes from the previous graph will be invalid but the ID can be used to look up the node in the current graph.

While this class is designed specifically for the common pump -> ingredient -> beverage pattern, graphs can be constructed in many different ways. The logic in this class is quite simple to replicate, so graphs should be designed based on need and then the ability to extract recipes can be added afterward.

Since:
1.0
Version:
2023-02-11
  • Constructor Details

    • RecipeExtractor

      public RecipeExtractor(BeveragePourEngine<?> engine)
      Create a recipe extractor for the engine.
    • RecipeExtractor

      public RecipeExtractor(BeveragePourEngine<?> engine, String bevId)
      Create a recipe extractor for the engine and add the ingredients for the specified beverageId. This is a shortcut which avoids a separate call to addIngredients(bevId) .
      Parameters:
      engine - the engine to use
      bevId - id of the beverage to add ingredients for
  • Method Details

    • addIngredients

      public RecipeExtractor addIngredients(String nodeId)
      Find the specified node in the beverage graph, if it's valid, traverse all the child nodes looking for ingredient nodes. Add all ingredients to the recipe extractor. If any nodes are unavailable or missing, the extractor will be marked invalid. This is typically called with a beverageId.
      Parameters:
      nodeId - id of the beverage graph node to start with
    • addIngredients

      public RecipeExtractor addIngredients(Collection<String> nodeIds)
      Convenience method for calling addIngredients() with a list of nodeIds. This is typically used when working with recipes that have a list of modifiers like flavors.
      Parameters:
      nodeIds - id of the beverage graph node to start with
    • addIngredients

      public RecipeExtractor addIngredients(GraphNode node)
      Add a graph node to the extractor. This will find all the underlying ingredient nodes and them to the recipe.
    • isValid

      public boolean isValid()
      Returns true if the resulting recipe is valid (can be poured).
    • getMissingIngredients

      public Collection<String> getMissingIngredients()
      Returns the set of missing ingredients.
    • getPumps

      public Collection<Pump<?>> getPumps()
      Returns the pumps associated with the recipe ingredients.