package org.multibit.mbm.core.model; import com.google.common.collect.Lists; import java.util.Collection; import java.util.List; /** *  <p>Builder to provide the following to {@link Item}:</p> *  <ul> *  <li>Provide a fluent interface to facilitate building the entity</li> *  </ul> * * @since 0.0.1 *   */ public class DeliveryBuilder { private Long id; private Supplier supplier; private List<AddDeliveryItem> addDeliveryItems = Lists.newArrayList(); private boolean isBuilt = false; /** * @return A new instance of the builder */ public static DeliveryBuilder newInstance() { return new DeliveryBuilder(); } /** * Handles the building process. No further configuration is possible after this. * * @return The item instance */ public Delivery build() { validateState(); // Delivery is a DTO so requires a default constructor Delivery delivery = new Delivery(); delivery.setId(id); delivery.setSupplier(supplier); // Add any items for (AddDeliveryItem addDeliveryItem : addDeliveryItems) { addDeliveryItem.applyTo(delivery); } isBuilt = true; return delivery; } private void validateState() { if (isBuilt) { throw new IllegalStateException("Build process is complete - no further changes can be made"); } if (supplier == null) { throw new IllegalStateException("Delivery requires a Supplier"); } } /** * Creates a DeliveryItem entry based on the parameters * * @param id The ID * * @return The builder */ public DeliveryBuilder withId(Long id) { validateState(); this.id = id; return this; } /** * Creates a DeliveryItem entry based on the parameters * * @param item The persistent Item (this should already exist in the database) * @param quantity The quantity * * @return The builder */ public DeliveryBuilder withDeliveryItem(Item item, int quantity) { validateState(); addDeliveryItems.add(new AddDeliveryItem(item, quantity)); return this; } /** * Creates a DeliveryItem entry based on the parameters * * @param deliveryItem A DeliveryItem * * @return The builder */ public DeliveryBuilder withDeliveryItem(DeliveryItem deliveryItem) { validateState(); addDeliveryItems.add(new AddDeliveryItem(deliveryItem.getItem(), deliveryItem.getQuantity())); return this; } /** * Creates multiple DeliveryItem entries based on the parameters * * @param deliveryItems A collection of DeliveryItems (Item will be re-used) * * @return The builder */ public DeliveryBuilder withDeliveryItems(Collection<DeliveryItem> deliveryItems) { validateState(); for (DeliveryItem deliveryItem: deliveryItems) { addDeliveryItems.add(new AddDeliveryItem(deliveryItem.getItem(), deliveryItem.getQuantity())); } return this; } public DeliveryBuilder withSupplier(Supplier supplier) { this.supplier = supplier; return this; } /** * Storage of parameters until ready for application */ private class AddDeliveryItem { private final Item item; private final int quantity; AddDeliveryItem(Item item, int quantity) { this.item = item; this.quantity = quantity; } /** * Applies the parameters to the given Delivery * * @param delivery The Delivery */ void applyTo(Delivery delivery) { // Bind the Item to the Delivery using the primary key DeliveryItem.DeliveryItemPk deliveryItemPk = new DeliveryItem.DeliveryItemPk(); deliveryItemPk.setDelivery(delivery); deliveryItemPk.setItem(item); DeliveryItem deliveryItem = new DeliveryItem(); deliveryItem.setPrimaryKey(deliveryItemPk); deliveryItem.setQuantity(quantity); delivery.getDeliveryItems().add(deliveryItem); } } }