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 CartBuilder { private Long id; private Customer customer; private List<AddCartItem> addCartItems = Lists.newArrayList(); private boolean isBuilt = false; /** * @return A new instance of the builder */ public static CartBuilder newInstance() { return new CartBuilder(); } /** * Handles the building process. No further configuration is possible after this. * * @return The item instance */ public Cart build() { validateState(); // Cart is a DTO so requires a default constructor Cart cart = new Cart(); cart.setId(id); cart.setCustomer(customer); // Add any items for (AddCartItem addCartItem : addCartItems) { addCartItem.applyTo(cart); } isBuilt = true; return cart; } private void validateState() { if (isBuilt) { throw new IllegalStateException("Build process is complete - no further changes can be made"); } if (customer == null) { throw new IllegalStateException("Cart requires a Customer"); } } /** * Creates a CartItem entry based on the parameters * * @param id The ID * * @return The builder */ public CartBuilder withId(Long id) { validateState(); this.id = id; return this; } /** * Creates a CartItem 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 CartBuilder withCartItem(Item item, int quantity) { validateState(); addCartItems.add(new AddCartItem(item, quantity)); return this; } /** * Creates a CartItem entry based on the parameters * * @param cartItem A CartItem * * @return The builder */ public CartBuilder withCartItem(CartItem cartItem) { validateState(); addCartItems.add(new AddCartItem(cartItem.getItem(), cartItem.getQuantity())); return this; } /** * Creates multiple CartItem entries based on the parameters * * @param cartItems A collection of CartItems (Item will be re-used) * * @return The builder */ public CartBuilder withCartItems(Collection<CartItem> cartItems) { validateState(); for (CartItem cartItem: cartItems) { addCartItems.add(new AddCartItem(cartItem.getItem(), cartItem.getQuantity())); } return this; } public CartBuilder withCustomer(Customer customer) { this.customer = customer; return this; } /** * Storage of parameters until ready for application */ private class AddCartItem { private final Item item; private final int quantity; AddCartItem(Item item, int quantity) { this.item = item; this.quantity = quantity; } /** * Applies the parameters to the given Cart * * @param cart The Cart */ void applyTo(Cart cart) { // Bind the Item to the Cart using the primary key CartItem.CartItemPk cartItemPk = new CartItem.CartItemPk(); cartItemPk.setCart(cart); cartItemPk.setItem(item); CartItem cartItem = new CartItem(); cartItem.setPrimaryKey(cartItemPk); cartItem.setQuantity(quantity); cart.getCartItems().add(cartItem); } } }