From 33613a85afc4b1481367fbe92a17ee59c240250b Mon Sep 17 00:00:00 2001 From: Sven Eisenhauer Date: Fri, 10 Nov 2023 15:11:48 +0100 Subject: add new repo --- .../src/examples/shop/impl/entity/Customer.java | 104 +++++++ .../src/examples/shop/impl/entity/LineItem.java | 132 +++++++++ .../src/examples/shop/impl/entity/Order.java | 183 ++++++++++++ .../src/examples/shop/impl/entity/Product.java | 93 ++++++ .../examples/shop/impl/mdb/OrderProcessorBean.java | 68 +++++ .../src/examples/shop/impl/session/CartBean.java | 320 +++++++++++++++++++++ .../examples/shop/impl/session/CatalogBean.java | 41 +++ .../src/examples/shop/impl/session/PricerBean.java | 138 +++++++++ .../shop/impl/session/UserManagerBean.java | 86 ++++++ 9 files changed, 1165 insertions(+) create mode 100644 Master/Reference Architectures and Patterns/EJB 3.0 Code/Gerald Examples/src/examples/shop/impl/entity/Customer.java create mode 100644 Master/Reference Architectures and Patterns/EJB 3.0 Code/Gerald Examples/src/examples/shop/impl/entity/LineItem.java create mode 100644 Master/Reference Architectures and Patterns/EJB 3.0 Code/Gerald Examples/src/examples/shop/impl/entity/Order.java create mode 100644 Master/Reference Architectures and Patterns/EJB 3.0 Code/Gerald Examples/src/examples/shop/impl/entity/Product.java create mode 100644 Master/Reference Architectures and Patterns/EJB 3.0 Code/Gerald Examples/src/examples/shop/impl/mdb/OrderProcessorBean.java create mode 100644 Master/Reference Architectures and Patterns/EJB 3.0 Code/Gerald Examples/src/examples/shop/impl/session/CartBean.java create mode 100644 Master/Reference Architectures and Patterns/EJB 3.0 Code/Gerald Examples/src/examples/shop/impl/session/CatalogBean.java create mode 100644 Master/Reference Architectures and Patterns/EJB 3.0 Code/Gerald Examples/src/examples/shop/impl/session/PricerBean.java create mode 100644 Master/Reference Architectures and Patterns/EJB 3.0 Code/Gerald Examples/src/examples/shop/impl/session/UserManagerBean.java (limited to 'Master/Reference Architectures and Patterns/EJB 3.0 Code/Gerald Examples/src/examples/shop/impl') diff --git a/Master/Reference Architectures and Patterns/EJB 3.0 Code/Gerald Examples/src/examples/shop/impl/entity/Customer.java b/Master/Reference Architectures and Patterns/EJB 3.0 Code/Gerald Examples/src/examples/shop/impl/entity/Customer.java new file mode 100644 index 0000000..c986436 --- /dev/null +++ b/Master/Reference Architectures and Patterns/EJB 3.0 Code/Gerald Examples/src/examples/shop/impl/entity/Customer.java @@ -0,0 +1,104 @@ +package examples.shop.impl.entity; + +import javax.persistence.Entity; +import javax.persistence.Id; + +/** + * This entity represents customer details. + */ +@Entity +public class Customer implements java.io.Serializable { + + private String customerID; + + private String name; + + private String password; + + private String address; + + private double discount; + + /** + * Returns the Id of the customer + */ + @Id + public String getCustomerID() { + return customerID; + } + + /** + * Sets the id of the customer + */ + public void setCustomerID(String customerId) { + this.customerID = customerId; + } + /** + * Returns the name of the customer + */ + public String getName() { + return name; + } + + /** + * Sets the name of the customer + */ + public void setName(String name) { + this.name = name; + } + + /** + * Returns the password of the customer + */ + public String getPassword() { + return password; + } + + /** + * Sets the password of the customer + */ + public void setPassword(String password) { + this.password = password; + } + + /** + * Returns the address of the customer + */ + public String getAddress() { + return address; + } + + /** + * Sets the address of the customer + */ + public void setAddress(String address) { + this.address = address; + } + + public double getDiscount() { + return discount; + } + + public void setDiscount(double discount) { + this.discount = discount; + } + + public Customer() { + } + + /** + * Called when new data is created. + * + * We need to initialize our Bean's state with the parameters + * passed from the client by calling our own abstract set + * methods. The Container can then inspect our Bean and + * INSERT the corresponding database entries. + */ + public void init(String id, String name, String password, String address) { + setCustomerID(id); + setName(name); + setAddress(address); + setPassword(password); + } + +} diff --git a/Master/Reference Architectures and Patterns/EJB 3.0 Code/Gerald Examples/src/examples/shop/impl/entity/LineItem.java b/Master/Reference Architectures and Patterns/EJB 3.0 Code/Gerald Examples/src/examples/shop/impl/entity/LineItem.java new file mode 100644 index 0000000..447cc75 --- /dev/null +++ b/Master/Reference Architectures and Patterns/EJB 3.0 Code/Gerald Examples/src/examples/shop/impl/entity/LineItem.java @@ -0,0 +1,132 @@ +package examples.shop.impl.entity; + +import javax.persistence.Entity; +import javax.persistence.Id; +import javax.persistence.OneToOne; + + +/** + * A line item entity is a quantity of a single product. + * + * Instances of this class are used for both in-memory represenation + * of carts and the persistent representation of orders in + * the database + */ +@Entity +public class LineItem implements java.io.Serializable { + + private String id; + + /** the product */ + private Product product; + + /** Number of items */ + private int quantity; + + /** Amount of the discount for each item */ + private double discount; + + /** + * Constructor + * @param productitem + * @param number of items + * @Param discount for each item + */ + public LineItem(Product productItem, int quantity, double discount) { + System.out.println("LineItem(...) called"); + this.product = productItem; + this.quantity = quantity; + this.discount = discount; + } + + public LineItem() { + System.out.println("New LineItem created."); + } + + /** + * The id number of this line item. This is our primary key as well. + * + * @return the id + */ + @Id + public String getId() { + return id; + } + + /** + * Sets the id + */ + public void setId(String id) { + this.id = id; + } + + + /** + * @return the productitem. + * productitem has product id, name of the product and description + */ + @OneToOne + public Product getProduct() { + System.out.println("LineItem.getProduct() called."); + return product; + } + + /** + * @param productItem. + */ + public void setProduct(Product product) { + System.out.println("LineItem.setProduct() called."); + this.product = product; + } + + /** + * @return the number of items. + */ + public int getQuantity() { + System.out.println("LineItem.getQuantity() called."); + return quantity; + } + + /** + * @param the number of items. + */ + public void setQuantity(int quantity) { + System.out.println("LineItem.setQuantity() called."); + this.quantity = quantity; + } + + /** + * @return the base price. The base price is the + * product's price times the quantity ordered. This + * figure does not take discounts into consideration. + */ + public double basePrice() { + System.out.println("LineItem.getBasePrice() called."); + return quantity * product.getBasePrice(); + } + + /** + * @return the discount that the customer gets on + * this order. + * + * Note: The discount is a whole number, not + * a percentage discount. + */ + public double getDiscount() { + System.out.println("LineItem.getDiscount() called."); + return discount; + } + + /** + * @param the discount that the customer gets on + * this order. + * + * Note: The discount is a whole number, not + * a percentage discount. + */ + public void setDiscount(double discount) { + System.out.println("LineItem.setDiscount(" + discount + ") called."); + this.discount = discount; + } + +} diff --git a/Master/Reference Architectures and Patterns/EJB 3.0 Code/Gerald Examples/src/examples/shop/impl/entity/Order.java b/Master/Reference Architectures and Patterns/EJB 3.0 Code/Gerald Examples/src/examples/shop/impl/entity/Order.java new file mode 100644 index 0000000..8986495 --- /dev/null +++ b/Master/Reference Architectures and Patterns/EJB 3.0 Code/Gerald Examples/src/examples/shop/impl/entity/Order.java @@ -0,0 +1,183 @@ +package examples.shop.impl.entity; + +import java.sql.Timestamp; +import java.util.Iterator; +import java.util.List; + +import javax.persistence.CascadeType; +import javax.persistence.Entity; +import javax.persistence.Id; +import javax.persistence.OneToMany; +import javax.persistence.Table; + +/** + * This entity represents an order placed for goods. + * + * Note: This entity could easily be extended to include other things, such as: + * + */ + +@Entity +@Table(name = "ORDERS") +public class Order { + + public enum Status { + Submitted, Unverified, Approved, Shipping, Delivered, Returned + }; + + private String orderId; + + private List lineItems; + + private Customer customer; + + private Timestamp orderDate; + + private Status status; + + private double taxes; + + private double subTotal; + + /** + * This order's identification number. It's also our Primary Key. + * + * @return order id + */ + @Id + public String getOrderID() { + return orderId; + } + + /** + * Sets the order id of an order + */ + public void setOrderID(String id) { + orderId = id; + } + + /** + * This represents a one-to-many relationship to the + * line items in the order. Persisting the order cascades + * to the line items. + * + * @return the set of order line items + */ + @OneToMany(cascade = CascadeType.PERSIST) + public List getLineItems() { + return lineItems; + } + + /** + * Sets set of the order line items + */ + public void setLineItems(List lineItems) { + this.lineItems = lineItems; + } + + /** + * @returns the Customer who placed this Order. + */ + public Customer getCustomer() { + return customer; + } + + /** + * set customer who placed this order. + */ + public void setCustomer(Customer customer) { + this.customer = customer; + } + + /** + * Returns the date this order was placed. + */ + public Timestamp getOrderDate() { + return orderDate; + } + + /** + * Sets the date this order + */ + public void setOrderDate(Timestamp orderDate) { + this.orderDate = orderDate; + } + + /** + * @return status information about the order. + */ + public Status getStatus() { + return status; + } + + /** + * Sets status information about the order. + */ + public void setStatus(Status status) { + this.status = status; + } + + /** + * Sets the subtotal of this order + */ + + public double getSubTotal() { + return subTotal; + } + + /** + * Returns the subtotal of this order + */ + public void setSubTotal(double subTotal) { + this.subTotal = subTotal; + } + + /** + * Returns taxes of this order + */ + public double getTaxes() { + return taxes; + } + + /** + * Sets the taxes of this order + */ + public void setTaxes(double taxes) { + this.taxes = taxes; + } + + /** + * Returns the subtotal rice of the entire order, ie. the sum of + * the base prices of all line items in this order. + */ + public double totalPrice() { + double totalPrice = 0; + for (Iterator iter = getLineItems().iterator(); iter + .hasNext();) { + LineItem item = iter.next(); + totalPrice += item.getProduct().basePrice; + } + return totalPrice; + } + + /** + * Called to initialize a new order entity + * + * We need to initialize our entity's state with the parameters passed from + * the client. + */ + public void init(String orderID, Customer customer, Status status, + double subTotal, double taxes) { + System.out.println("Order.init(" + orderID + ") called"); + setOrderID(orderID); + setOrderDate(new java.sql.Timestamp(System.currentTimeMillis())); + setStatus(status); + setSubTotal(subTotal); + setTaxes(taxes); + } + +} diff --git a/Master/Reference Architectures and Patterns/EJB 3.0 Code/Gerald Examples/src/examples/shop/impl/entity/Product.java b/Master/Reference Architectures and Patterns/EJB 3.0 Code/Gerald Examples/src/examples/shop/impl/entity/Product.java new file mode 100644 index 0000000..99fb29a --- /dev/null +++ b/Master/Reference Architectures and Patterns/EJB 3.0 Code/Gerald Examples/src/examples/shop/impl/entity/Product.java @@ -0,0 +1,93 @@ +package examples.shop.impl.entity; + +import javax.persistence.Entity; +import javax.persistence.Id; + +/** + * Entity + * + * This is a product that's persistent. It has an ID #, a name, + * a description, and a base price. + */ +@Entity +public class Product implements java.io.Serializable { + + public String name; + public String description; + public double basePrice; + public String productID; + + public Product() { + } + + /** + * @return the product id. + */ + @Id + public String getProductID() { + return productID; + } + + /** + * Sets the product id. + */ + public void setProductID(String productID) { + this.productID = productID; + } + + /** + * @return the name of the product. + */ + public String getName() { + return name; + } + + /** + * Sets the name of the product. + */ + public void setName(String name) { + this.name = name; + } + + /** + * @return the description of the product. + */ + public String getDescription() { + return description; + } + + /** + * Sets the description of the product. + */ + public void setDescription(String description) { + this.description = description; + } + + /** + * @return the base price of the product. + */ + public double getBasePrice() { + return basePrice; + } + + /** + * Sets the base price of the product. + */ + public void setBasePrice(double price) { + this.basePrice = price; + } + + + /** + * This is the initialization method + */ + public Product init(String productID, String name, String description, + double basePrice) { + this.productID = productID; + this.name = name; + this.description = description; + this.basePrice = basePrice; + return this; + } + +} diff --git a/Master/Reference Architectures and Patterns/EJB 3.0 Code/Gerald Examples/src/examples/shop/impl/mdb/OrderProcessorBean.java b/Master/Reference Architectures and Patterns/EJB 3.0 Code/Gerald Examples/src/examples/shop/impl/mdb/OrderProcessorBean.java new file mode 100644 index 0000000..a1056d1 --- /dev/null +++ b/Master/Reference Architectures and Patterns/EJB 3.0 Code/Gerald Examples/src/examples/shop/impl/mdb/OrderProcessorBean.java @@ -0,0 +1,68 @@ +package examples.shop.impl.mdb; + +import javax.ejb.ActivationConfigProperty; +import javax.ejb.EJBException; +import javax.ejb.MessageDriven; +import javax.jms.Message; +import javax.jms.MessageListener; +import javax.jms.TextMessage; +import javax.persistence.EntityManager; +import javax.persistence.PersistenceContext; + +import examples.shop.impl.entity.Order; + + +/** + * This message-driven bean receives JMS messages + * to process orders. It then performs the order + * processing. + */ +@MessageDriven(activationConfig = { + @ActivationConfigProperty( + propertyName = "destinationType", + propertyValue = "javax.jms.Queue") + }) +public class OrderProcessorBean implements MessageListener { + + @PersistenceContext + EntityManager manager; + + public OrderProcessorBean() { + } + + /** + * The one business method that message-driven beans have + * Here we perform the actual order processing + */ + public void onMessage(Message msg) { + TextMessage tm = (TextMessage) msg; + try { + String orderID = tm.getText(); + System.out.println("Processing order " + orderID); + + Order order = manager.find(Order.class, orderID); + + /* + * At this point, we could perform lots of tasks: + * + * - A call-out to a credit card company (perhaps through + * web services) to check the user's credit + * card rating and perform a debit. + * + * - Check the product inventory to ensure availability + * + * - Check the current backlog for shipping orders + * + * - Send an email confirmation + * + * In this example, we'll merely set the order status to + * "approved". + */ + order.setStatus(Order.Status.Approved); + } catch (Exception e) { + e.printStackTrace(); + throw new EJBException(e); + } + } + +} diff --git a/Master/Reference Architectures and Patterns/EJB 3.0 Code/Gerald Examples/src/examples/shop/impl/session/CartBean.java b/Master/Reference Architectures and Patterns/EJB 3.0 Code/Gerald Examples/src/examples/shop/impl/session/CartBean.java new file mode 100644 index 0000000..d5e2b1b --- /dev/null +++ b/Master/Reference Architectures and Patterns/EJB 3.0 Code/Gerald Examples/src/examples/shop/impl/session/CartBean.java @@ -0,0 +1,320 @@ +package examples.shop.impl.session; + +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; + +import javax.ejb.Remote; +import javax.ejb.Remove; +import javax.ejb.Stateful; +import javax.jms.Connection; +import javax.jms.ConnectionFactory; +import javax.jms.Destination; +import javax.jms.JMSException; +import javax.jms.MessageProducer; +import javax.jms.Session; +import javax.jms.TextMessage; +import javax.naming.Context; +import javax.naming.InitialContext; +import javax.persistence.EntityManager; +import javax.persistence.PersistenceContext; + +import examples.shop.impl.entity.Customer; +import examples.shop.impl.entity.LineItem; +import examples.shop.impl.entity.Order; +import examples.shop.impl.entity.Product; +import examples.shop.logic.Cart; + +/** + * This stateful session bean represents a cart which a customer is + * working on. A cart is a set of products that the customer is + * interested in, but has not committed to buying yet. + * + * A cart consists of a series of line items. Each line item + * represents one particular product the customer wants, as well as a + * quantity and discount for that product. + * + * The distinction between a cart and an order is that a quote is only + * temporary and in-memory (hence a stateful session bean), whereas an + * order is a persistent record (hence an entity). The cart bean + * knows how to transform itself into an order (via the purchase() + * method). + */ + +@Stateful +@Remote(Cart.class) +public class CartBean implements Cart { + + /** + * The shopping cart owner + */ + private String owner; + + /** + * The shopping cart contents - a vector of LineItems + */ + private List contents = new ArrayList(); + + /** + * The subtotal (price before taxes) of the goods + */ + private double subTotal; + + /** + * The taxes on the goods + */ + private double taxes; + + @PersistenceContext + private EntityManager manager; + + public CartBean() { + } + + /** + * Get method for the shopping cart owner's name + * + * @return shopping cart owner + */ + public String getOwner() { + return owner; + } + + /** + * Set method for the shopping cart owner's name + * + * @param shopping + * cart owner + */ + public void setOwner(String owner) { + this.owner = owner; + } + + /** + * Adds an item to the shopping cart + * + * @param shopping + * cart lineitem + */ + public void add(LineItem lineItem) { + /* + * Search for an exiting line item in the cart that match + * the productID passed in. + */ + for (Iterator iter = contents.iterator(); iter.hasNext();) { + LineItem item = iter.next(); + Product product = item.getProduct(); + + if (product != null + && product.getProductID().equals( + lineItem.getProduct().getProductID())) { + // found one, modify that line item's quantity and return + item.setQuantity(item.getQuantity() + lineItem.getQuantity()); + return; + } + } + + /* + * Did not find a match, so add the line item as new. + */ + contents.add(lineItem); + } + + /** + * Changes the quantities of contents in the shopping cart + * + * @param product + * Id + * @param number + * of items. + */ + public void modify(String productID, int quantity) throws Exception { + System.out.println("CartBean.modify()"); + + /* + * Search for a lineitem in the cart that match the productID passed in. + * If found, modify that lineitem. + */ + for (Iterator iter = contents.iterator(); iter.hasNext();) { + LineItem item = iter.next(); + Product product = item.getProduct(); + if (product != null && product.getProductID().equals(productID)) { + item.setQuantity(quantity); + if (quantity == 0) { + iter.remove(); + } + return; + } + } + throw new Exception("CartBean.modify() error: Could not find product " + + productID); + } + + /** + * Returns all the shopping cart line items + * + * @return A collection of Cart LineItems + */ + public List getAll() { + return contents; + } + + /** + * @return the subtotal price which has been previously set by + * setSubtotal(). + */ + public double getSubtotal() { + return subTotal; + } + + /** + * Sets the subtotal price. + * @param subTotal the subtotal price + */ + public void setSubtotal(double subTotal) { + this.subTotal = subTotal; + } + + /** + * @return the taxes computed for this Cart. + */ + public double getTaxes() { + return taxes; + } + + /** + * Sets the taxes for this Cart. + */ + public void setTaxes(double taxes) { + System.out.println("CartBean.setTaxes(): " + taxes); + this.taxes = taxes; + } + + /** + * Get the total price. The total Price is computed from: + *
    + *
  1. Subtotal price + *
  2. Tax + *
+ * @return the total price. + */ + public double getTotalPrice() { + return subTotal + taxes; + } + + /** + * Empties the shopping cart + */ + public void clear() { + contents.clear(); + } + + /** + * Purchases this cart. The cart will create an order in the database + * and return the order ID as a confirmation number. + * + * @return The Order confirmation number + */ + public String purchase() { + System.out.println("CartBean.purchase()"); + Customer customer = manager.find(Customer.class, owner); + + /* + * Create the order entity + */ + Order order = new Order(); + String orderID = makeUniqueID(); + order.init(orderID, customer, Order.Status.Unverified, subTotal, taxes); + order.setLineItems(prepareContents()); + manager.persist(order); + + /* + * Sends the JMS message to the topic + */ + try { + sendMessage(orderID); + } catch (Exception e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + + /* + * Return the order ID + */ + return orderID; + } + + /** + * Sends a JMS message to a destination (Queue or Topic) + * + * @param a + * message string, in this case orderId + */ + private void sendMessage(String text) throws Exception { + Connection connection = null; + MessageProducer producer = null; + Session session = null; + + try { + Context jndiContext = new InitialContext(); + ConnectionFactory connectionFactory = (ConnectionFactory) jndiContext + .lookup("jms/QueueConnectionFactory"); + Destination destination = (Destination) jndiContext + .lookup("jms/OrderQueue"); + connection = connectionFactory.createConnection(); + session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE); + producer = session.createProducer(destination); + + connection.start(); + TextMessage msg = session.createTextMessage(); + msg.setText(text); + producer.send(msg); + } catch (Exception ex) { + throw ex; + } finally { + if (connection != null) { + try { + producer.close(); + connection.close(); + session.close(); + } catch (JMSException e) { + // ignore + } + } + } + } + + /** + * Generates primary keys for line items and loads the products + * into the persistence context. + */ + + private List prepareContents() { + for (Iterator iter = contents.iterator(); iter.hasNext();) { + LineItem lineItem = iter.next(); + Product p = manager.find(Product.class, lineItem.getProduct() + .getProductID()); + lineItem.setProduct(p); + lineItem.setId(makeUniqueID()); + } + return contents; + } + + /** + * Returns a unique Id based on current time. Can be removed + * when AUTO key generation works in Glassfish * + */ + private String makeUniqueID() { + String id = new Long(System.nanoTime()).toString(); + System.out.println("makeUniqueID: " + id); + return id; + } + + /** + * Removes this quote, and hence all client- + * specific state. + */ + @Remove + public void remove() { + } +} diff --git a/Master/Reference Architectures and Patterns/EJB 3.0 Code/Gerald Examples/src/examples/shop/impl/session/CatalogBean.java b/Master/Reference Architectures and Patterns/EJB 3.0 Code/Gerald Examples/src/examples/shop/impl/session/CatalogBean.java new file mode 100644 index 0000000..658b675 --- /dev/null +++ b/Master/Reference Architectures and Patterns/EJB 3.0 Code/Gerald Examples/src/examples/shop/impl/session/CatalogBean.java @@ -0,0 +1,41 @@ +package examples.shop.impl.session; + +import java.util.List; + +import javax.ejb.Remote; +import javax.ejb.Stateless; +import javax.persistence.EntityManager; +import javax.persistence.PersistenceContext; + +import examples.shop.impl.entity.Product; +import examples.shop.logic.Catalog; + +/** + * This catalog Stateless Session Bean retrieves a list of productitems. + * ProductItem has product Id, name of the product and description + */ +@Stateless +@Remote(Catalog.class) +public class CatalogBean implements Catalog { + + @PersistenceContext + private EntityManager manager; + + public CatalogBean() { + } + + public Product getProduct(String productId) { + return manager.find(Product.class, productId); + } + + public List getProductList() { + /* find all products */ + return manager.createQuery("SELECT p FROM Product p") + .getResultList(); + } + + public void addProduct(Product product) { + manager.persist(product); + } + +} diff --git a/Master/Reference Architectures and Patterns/EJB 3.0 Code/Gerald Examples/src/examples/shop/impl/session/PricerBean.java b/Master/Reference Architectures and Patterns/EJB 3.0 Code/Gerald Examples/src/examples/shop/impl/session/PricerBean.java new file mode 100644 index 0000000..cbcb73f --- /dev/null +++ b/Master/Reference Architectures and Patterns/EJB 3.0 Code/Gerald Examples/src/examples/shop/impl/session/PricerBean.java @@ -0,0 +1,138 @@ +package examples.shop.impl.session; + +import java.util.Iterator; +import java.util.List; + +import javax.annotation.Resource; +import javax.ejb.EJB; +import javax.ejb.Remote; +import javax.ejb.Stateless; +import javax.jws.WebService; + +import examples.shop.impl.entity.Customer; +import examples.shop.impl.entity.LineItem; +import examples.shop.logic.Pricer; +import examples.shop.logic.UserManager; + +/** + * Stateless Session Bean which computes prices based + * upon a set of pricing rules. The pricing rules are + * deployed with the bean as environment properties. + */ +@Stateless +@Remote(Pricer.class) +@WebService(serviceName="PricerService", portName="PricerPort") +public class PricerBean implements Pricer { + + @Resource(name="taxRate") + public int taxRate = 0; + + @Resource(name="bulkDiscountRate") + public int bulkDiscountRate = 0; + + @EJB + UserManager userManager; + + public PricerBean() { + } + + /** + * bulk discounts apply to quantities of BULK or more items + */ + private static final int BULK = 5; + + /** + * This method computes the applicable discount in absolute + * figure, based on bulk and personal discounts that may apply. + * + * @param quantity the number of items that a user intends to buy + * @param basePrice the overall, non-discounted volume of the + * purchase (individual price times quantity) + * @param the user name + * @return the subTotal for the line item after applying any + * applicable discounts, excluding taxes + */ + public double getDiscount(int quantity, double basePrice, String user) { + double discountRate = getPersonalDiscountRate(user); + if (quantity >= BULK) { + discountRate += getBulkDiscountRate(); + System.out.println("Using getBulkDiscountRate " + getBulkDiscountRate()); + } + + /* + * Calculate the discount in absolute figures + */ + return basePrice * (discountRate / 100); + } + + /** + * A bulk discount applies to quantities of more than 5 pieces. + * @return the bulk discount rate int percent + */ + public double getBulkDiscountRate() { + return this.bulkDiscountRate; + } + + /** + * Customers with certain names get discounts. The discount rules + * are stored in the environment properties that the bean is + * deployed with. + */ + public double getPersonalDiscountRate(String userName) { + /* + * Get the name of this customer. + */ + Customer user = userManager.getUser(userName); + if( user != null) + return user.getDiscount(); + else + return 0; + } + + /** + * Computes the subtotal price for a set of products the customer + * is interested in. The subtotal takes into account the price of + * each product the customer wants, the quantity of each product, + * and any personal discounts the customer gets. However, the + * subtotal ignores taxes. + * + * @param quote All the data needed to compute the + * subtotal is in this parameter. + */ + public double priceSubtotal(String user, List items) { + System.out.println("PricerBean.priceSubtotal() called"); + + /* + * Compute the subtotal + */ + double subTotal = 0; + + for(Iterator iter = items.iterator(); iter.hasNext(); ) { + LineItem item = iter.next(); + item.setDiscount( + getDiscount(item.getQuantity(), item.basePrice(),user)); + + /* + * Add the price to the subtotal. + */ + subTotal += (item.basePrice() - item.getDiscount()); + } + + return subTotal; + } + + /** + * Computes the taxes on a quote. + */ + public double priceTaxes(double subtotal) { + System.out.println("PricerBean.priceTaxes() called, taxes: " + getTaxRate()); + return (getTaxRate() / 100) * subtotal; + } + + /** + * @return the applicable tax rate + */ + public double getTaxRate() { + return taxRate; + } +} diff --git a/Master/Reference Architectures and Patterns/EJB 3.0 Code/Gerald Examples/src/examples/shop/impl/session/UserManagerBean.java b/Master/Reference Architectures and Patterns/EJB 3.0 Code/Gerald Examples/src/examples/shop/impl/session/UserManagerBean.java new file mode 100644 index 0000000..babb67e --- /dev/null +++ b/Master/Reference Architectures and Patterns/EJB 3.0 Code/Gerald Examples/src/examples/shop/impl/session/UserManagerBean.java @@ -0,0 +1,86 @@ +package examples.shop.impl.session; + +import java.util.Iterator; +import java.util.List; + +import javax.ejb.Remote; +import javax.ejb.Stateless; +import javax.persistence.EntityManager; +import javax.persistence.PersistenceContext; + +import examples.shop.impl.entity.Customer; +import examples.shop.logic.InvalidPasswordException; +import examples.shop.logic.UserManager; + +/** + * UserManager is Stateless session bean resposible for creating and + * retrieving a customer record. It also authenticates the user. + */ + +@Stateless +@Remote(UserManager.class) +public class UserManagerBean implements UserManager { + + @PersistenceContext + EntityManager manager; + + public UserManagerBean() { + } + + /** + * Returns an customer object for the given customer id. + */ + public Customer getUser(String customerId) { + return manager.find(Customer.class, customerId); + } + + /** + * It uses the customer entity bean to create a record in the databse + * @param customerId + * @param name + * @param password + * @param address + */ + + public Customer createUser(String customerId, String name, String password, String address) { + Customer customer = new Customer(); + customer.init(customerId, name, password, address); + manager.persist(customer); + return customer; + } + + /** + * This method authenticates the user + * + * @return true, if the password is correct + * @throws an InvalidPasswordException if password is incorrect. + */ + + public boolean validateUser(String customerID, String password) + throws InvalidPasswordException { + if(customerID== null || password == null) + throw new IllegalArgumentException("id " + customerID + " pw " + password); + Customer user = getUser(customerID); + if (user != null && password.equals(user.getPassword())) { + return true; + } else { + System.out.println("Failure to validate user ID " + customerID + + " with password " + password + " against password " + + user.getPassword()); + + throw new InvalidPasswordException("Invalid Password:" + + password); + } + } + + public List findAllCustomers() { + return manager.createQuery("SELECT c FROM Customer c").getResultList(); + } + + public void removeAllCustomers() { + List l = manager.createQuery("SELECT c FROM Customer c ").getResultList(); + for(Iterator iter = l.iterator(); iter.hasNext();) { + manager.remove(iter.next()); + } + } +} -- cgit v1.2.3