Explorar el Código

Make it so Products (and thus, Recipes) do not track objects by preparation when composing their ingredients list.

Sam Jaffe hace 5 años
padre
commit
dfa4c7fc8d

+ 3 - 9
src/main/lombok/org/leumasjaffe/recipe/model/CompoundRecipeComponent.java

@@ -1,10 +1,10 @@
 package org.leumasjaffe.recipe.model;
 
 import java.util.Collection;
-import java.util.HashMap;
-import java.util.Map;
 import java.util.stream.Stream;
 
+import org.leumasjaffe.recipe.util.Collator;
+
 import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
 
 @JsonIgnoreProperties({"duration", "ingredients", "components", "ingredientsAsStream"})
@@ -20,12 +20,6 @@ interface CompoundRecipeComponent extends RecipeComponent {
 	
 	@Override
 	default Collection<Ingredient> getIngredients() {
-		final Map<String, Ingredient> map = new HashMap<>();
-        getIngredientsAsStream().forEach(i -> {
-        	final String key = i.key();
-            map.computeIfPresent(key, (k, v) -> v.plus(i));
-            map.computeIfAbsent(key, k -> i);
-        });
-        return map.values();
+		return Collator.collateBy(getIngredientsAsStream(), Ingredient::key, Ingredient::plus);
 	}
 }

+ 7 - 1
src/main/lombok/org/leumasjaffe/recipe/model/Product.java

@@ -4,6 +4,7 @@ import java.util.List;
 import java.util.stream.Stream;
 
 import org.leumasjaffe.observer.Observable;
+import org.leumasjaffe.recipe.util.Collator;
 
 import lombok.Data;
 import lombok.EqualsAndHashCode;
@@ -15,11 +16,16 @@ public class Product extends Observable.Instance implements CompoundRecipeCompon
 
 	@Override
 	public Stream<Ingredient> getIngredientsAsStream() {
-		return cards.stream().flatMap(Card::getIngredientsAsStream);
+		return Collator.collateBy(cards.stream().flatMap(Card::getIngredientsAsStream),
+				Product::key, Ingredient::plus).stream();
 	}
 
 	@Override
 	public Stream<? extends RecipeComponent> getComponents() {
 		return cards.stream();
 	}
+	
+	private static String key(Ingredient ingredient) {
+		return ingredient.getName() + ingredient.getAmount().getUnit();
+	}
 }

+ 24 - 0
src/main/lombok/org/leumasjaffe/recipe/util/Collator.java

@@ -0,0 +1,24 @@
+package org.leumasjaffe.recipe.util;
+
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.function.BiFunction;
+import java.util.function.Function;
+import java.util.stream.Stream;
+
+import lombok.experimental.UtilityClass;
+
+@UtilityClass
+public class Collator {
+	public <T> Collection<T> collateBy(final Stream<T> stream, final Function<T, String> getKey,
+			final BiFunction<T, T, T> folder) {
+		final Map<String, T> map = new HashMap<>();
+        stream.forEach(value -> {
+        	final String key = getKey.apply(value);
+            map.computeIfPresent(key, (k, v) -> folder.apply(v, value));
+            map.computeIfAbsent(key, k -> value);
+        });
+        return map.values();
+	}
+}

+ 2 - 1
src/main/lombok/org/leumasjaffe/recipe/view/ProductSummaryPanel.java

@@ -6,6 +6,7 @@ import org.jdesktop.swingx.VerticalLayout;
 import org.leumasjaffe.observer.ObservableListener;
 import org.leumasjaffe.observer.ObserverDispatch;
 import org.leumasjaffe.recipe.model.Product;
+
 import java.awt.GridBagLayout;
 import java.awt.Insets;
 
@@ -43,7 +44,7 @@ public class ProductSummaryPanel extends JPanel {
 		
 		listener = new ObservableListener<>(panel, (c, t) -> {
 			c.removeAll();
-			product.getIngredients().stream().map(SummaryIngredientPanel::new).forEach(c::add);
+			product.getIngredientsAsStream().map(SummaryIngredientPanel::new).forEach(c::add);
 		});
 		listener.setObserved(product);
 	}