]> git.mxchange.org Git - pizzaservice-ejb.git/commitdiff
Continued and discontinued:
authorRoland Häder <roland@mxchange.org>
Sat, 15 Apr 2017 21:57:41 +0000 (23:57 +0200)
committerRoland Häder <roland@mxchange.org>
Sat, 15 Apr 2017 21:57:41 +0000 (23:57 +0200)
- jshop-ejb and jshop-receipt-ejb had persistence unit files which would make
  it impossible to have two shops at the same system. Well, mostly not what you
  want because you want performance, but who knows?

Signed-off-by: Roland Häder <roland@mxchange.org>
17 files changed:
lib/gnu-jpdf/gnujpdf-1.7.0.jar [new file with mode: 0644]
lib/jproduct-core.jar [new file with mode: 0644]
lib/jshop-receipt-lib.jar [new file with mode: 0644]
lib/nblibraries.properties
nbproject/build-impl.xml
nbproject/project.properties
nbproject/project.xml
src/java/org/mxchange/pizzaservice/beans/checkout/CheckoutMessageBean.java [new file with mode: 0644]
src/java/org/mxchange/pizzaservice/model/basket/BasketSessionBean.java [new file with mode: 0644]
src/java/org/mxchange/pizzaservice/model/category/AdminCategorySessionBean.java [new file with mode: 0644]
src/java/org/mxchange/pizzaservice/model/category/CategorySessionBean.java [new file with mode: 0644]
src/java/org/mxchange/pizzaservice/model/customer/ShopCustomerSessionBean.java [new file with mode: 0644]
src/java/org/mxchange/pizzaservice/model/product/AdminProductSessionBean.java [new file with mode: 0644]
src/java/org/mxchange/pizzaservice/model/product/ProductSessionBean.java [new file with mode: 0644]
src/java/org/mxchange/pizzaservice/model/receipt/PdfReceiptSessionBean.java [new file with mode: 0644]
src/java/org/mxchange/pizzaservice/receipt/PdfReceiptBean.java [new file with mode: 0644]
src/java/org/mxchange/pizzaservice/receipt/ReceiptFactory.java [new file with mode: 0644]

diff --git a/lib/gnu-jpdf/gnujpdf-1.7.0.jar b/lib/gnu-jpdf/gnujpdf-1.7.0.jar
new file mode 100644 (file)
index 0000000..8b325ea
Binary files /dev/null and b/lib/gnu-jpdf/gnujpdf-1.7.0.jar differ
diff --git a/lib/jproduct-core.jar b/lib/jproduct-core.jar
new file mode 100644 (file)
index 0000000..af98d89
Binary files /dev/null and b/lib/jproduct-core.jar differ
diff --git a/lib/jshop-receipt-lib.jar b/lib/jshop-receipt-lib.jar
new file mode 100644 (file)
index 0000000..eb2f505
Binary files /dev/null and b/lib/jshop-receipt-lib.jar differ
index 1aac91b5ad352c0ac9d8ed75040aeb0ba50fc6d4..3eaecf1e266b83484e1cf6cb09d8d329ef586282 100644 (file)
@@ -13,3 +13,8 @@ libs.eclipselinkmodelgen.classpath=\
     ${base}/eclipselinkmodelgen/org.eclipse.persistence.jpa.modelgen_2.5.2.v20140319-9ad6abd.jar
 libs.eclipselinkmodelgen.displayName=EclipseLink-ModelGen (JPA 2.1)
 libs.eclipselinkmodelgen.prop-maven-dependencies=org.eclipse.persistence:org.eclipse.persistence.jpa.modelgen.processor:2.5.2:jar
+libs.GNU_JPDF_1.7.0.classpath=\
+    ${base}/gnu-jpdf/gnujpdf-1.7.0.jar
+libs.GNU_JPDF_1.7.0.displayName=GNU JPDF 1.7.0
+libs.GNU_JPDF_1.7.0.javadoc=\
+    http://www.aip.de/~granzer/javadoc/jpdf/
index 4c1f7558854472df4e8d197f3c9f51964540310d..2a4528f566071cb5c3ec7e52cd17f05a9207e742 100644 (file)
@@ -858,9 +858,12 @@ exists or setup the property manually. For example like this:
         <copyfiles files="${file.reference.jcustomer-lib.jar}" todir="${build.classes.dir}"/>
         <copyfiles files="${file.reference.jphone-core.jar}" todir="${build.classes.dir}"/>
         <copyfiles files="${file.reference.jphone-lib.jar}" todir="${build.classes.dir}"/>
+        <copyfiles files="${file.reference.jproduct-core.jar}" todir="${build.classes.dir}"/>
         <copyfiles files="${file.reference.jshop-core.jar}" todir="${build.classes.dir}"/>
         <copyfiles files="${file.reference.jshop-ee-lib.jar}" todir="${build.classes.dir}"/>
+        <copyfiles files="${file.reference.jshop-receipt-lib.jar}" todir="${build.classes.dir}"/>
         <copyfiles files="${file.reference.jmailer-ee.jar}" todir="${build.classes.dir}"/>
+        <copyfiles files="${libs.GNU_JPDF_1.7.0.classpath}" todir="${build.classes.dir}"/>
         <copyfiles files="${reference.pizzaservice-core.jar}" todir="${build.classes.dir}"/>
         <copyfiles files="${reference.pizzaservice-lib.jar}" todir="${build.classes.dir}"/>
         <copyfiles files="${reference.pizzaservice-mailer.jar}" todir="${build.classes.dir}"/>
@@ -881,15 +884,18 @@ exists or setup the property manually. For example like this:
         <basename file="${file.reference.jcustomer-lib.jar}" property="manifest.file.reference.jcustomer-lib.jar"/>
         <basename file="${file.reference.jphone-core.jar}" property="manifest.file.reference.jphone-core.jar"/>
         <basename file="${file.reference.jphone-lib.jar}" property="manifest.file.reference.jphone-lib.jar"/>
+        <basename file="${file.reference.jproduct-core.jar}" property="manifest.file.reference.jproduct-core.jar"/>
         <basename file="${file.reference.jshop-core.jar}" property="manifest.file.reference.jshop-core.jar"/>
         <basename file="${file.reference.jshop-ee-lib.jar}" property="manifest.file.reference.jshop-ee-lib.jar"/>
+        <basename file="${file.reference.jshop-receipt-lib.jar}" property="manifest.file.reference.jshop-receipt-lib.jar"/>
         <basename file="${file.reference.jmailer-ee.jar}" property="manifest.file.reference.jmailer-ee.jar"/>
+        <basename file="${libs.GNU_JPDF_1.7.0.classpath}" property="manifest.libs.GNU_JPDF_1.7.0.classpath"/>
         <basename file="${reference.pizzaservice-core.jar}" property="manifest.reference.pizzaservice-core.jar"/>
         <basename file="${reference.pizzaservice-lib.jar}" property="manifest.reference.pizzaservice-lib.jar"/>
         <basename file="${reference.pizzaservice-mailer.jar}" property="manifest.reference.pizzaservice-mailer.jar"/>
         <basename file="${file.reference.cdi-api.jar}" property="manifest.file.reference.cdi-api.jar"/>
         <manifest file="${build.ear.classes.dir}/META-INF/MANIFEST.MF" mode="update">
-            <attribute name="Extension-List" value="jar-1 jar-2 jar-3 jar-4 jar-5 jar-6 jar-7 jar-8 jar-9 jar-10 jar-11 jar-12 jar-13 jar-14 jar-15 jar-16 jar-17 jar-18 jar-19 jar-20 jar-21 "/>
+            <attribute name="Extension-List" value="jar-1 jar-2 jar-3 jar-4 jar-5 jar-6 jar-7 jar-8 jar-9 jar-10 jar-11 jar-12 jar-13 jar-14 jar-15 jar-16 jar-17 jar-18 jar-19 jar-20 jar-21 jar-22 jar-23 jar-24 "/>
             <attribute name="jar-1-Extension-Name" value="${manifest.file.reference.jcoreee.jar}"/>
             <attribute name="jar-2-Extension-Name" value="${manifest.file.reference.jcore-logger-lib.jar}"/>
             <attribute name="jar-3-Extension-Name" value="${manifest.file.reference.jcountry-core.jar}"/>
@@ -904,13 +910,16 @@ exists or setup the property manually. For example like this:
             <attribute name="jar-12-Extension-Name" value="${manifest.file.reference.jcustomer-lib.jar}"/>
             <attribute name="jar-13-Extension-Name" value="${manifest.file.reference.jphone-core.jar}"/>
             <attribute name="jar-14-Extension-Name" value="${manifest.file.reference.jphone-lib.jar}"/>
-            <attribute name="jar-15-Extension-Name" value="${manifest.file.reference.jshop-core.jar}"/>
-            <attribute name="jar-16-Extension-Name" value="${manifest.file.reference.jshop-ee-lib.jar}"/>
-            <attribute name="jar-17-Extension-Name" value="${manifest.file.reference.jmailer-ee.jar}"/>
-            <attribute name="jar-18-Extension-Name" value="${manifest.reference.pizzaservice-core.jar}"/>
-            <attribute name="jar-19-Extension-Name" value="${manifest.reference.pizzaservice-lib.jar}"/>
-            <attribute name="jar-20-Extension-Name" value="${manifest.reference.pizzaservice-mailer.jar}"/>
-            <attribute name="jar-21-Extension-Name" value="${manifest.file.reference.cdi-api.jar}"/>
+            <attribute name="jar-15-Extension-Name" value="${manifest.file.reference.jproduct-core.jar}"/>
+            <attribute name="jar-16-Extension-Name" value="${manifest.file.reference.jshop-core.jar}"/>
+            <attribute name="jar-17-Extension-Name" value="${manifest.file.reference.jshop-ee-lib.jar}"/>
+            <attribute name="jar-18-Extension-Name" value="${manifest.file.reference.jshop-receipt-lib.jar}"/>
+            <attribute name="jar-19-Extension-Name" value="${manifest.file.reference.jmailer-ee.jar}"/>
+            <attribute name="jar-20-Extension-Name" value="${manifest.libs.GNU_JPDF_1.7.0.classpath}"/>
+            <attribute name="jar-21-Extension-Name" value="${manifest.reference.pizzaservice-core.jar}"/>
+            <attribute name="jar-22-Extension-Name" value="${manifest.reference.pizzaservice-lib.jar}"/>
+            <attribute name="jar-23-Extension-Name" value="${manifest.reference.pizzaservice-mailer.jar}"/>
+            <attribute name="jar-24-Extension-Name" value="${manifest.file.reference.cdi-api.jar}"/>
         </manifest>
     </target>
     <target depends="compile" name="library-inclusion-in-manifest">
@@ -928,9 +937,12 @@ exists or setup the property manually. For example like this:
         <copyfiles files="${file.reference.jcustomer-lib.jar}" todir="${dist.ear.dir}/lib"/>
         <copyfiles files="${file.reference.jphone-core.jar}" todir="${dist.ear.dir}/lib"/>
         <copyfiles files="${file.reference.jphone-lib.jar}" todir="${dist.ear.dir}/lib"/>
+        <copyfiles files="${file.reference.jproduct-core.jar}" todir="${dist.ear.dir}/lib"/>
         <copyfiles files="${file.reference.jshop-core.jar}" todir="${dist.ear.dir}/lib"/>
         <copyfiles files="${file.reference.jshop-ee-lib.jar}" todir="${dist.ear.dir}/lib"/>
+        <copyfiles files="${file.reference.jshop-receipt-lib.jar}" todir="${dist.ear.dir}/lib"/>
         <copyfiles files="${file.reference.jmailer-ee.jar}" todir="${dist.ear.dir}/lib"/>
+        <copyfiles files="${libs.GNU_JPDF_1.7.0.classpath}" todir="${dist.ear.dir}/lib"/>
         <copyfiles files="${reference.pizzaservice-core.jar}" todir="${dist.ear.dir}/lib"/>
         <copyfiles files="${reference.pizzaservice-lib.jar}" todir="${dist.ear.dir}/lib"/>
         <copyfiles files="${reference.pizzaservice-mailer.jar}" todir="${dist.ear.dir}/lib"/>
index 9cdbf0b476cca8123cf588fec685f9d9eff9c57c..5f9b6b8f6a2d8c11f9fe986cc5f9f419c8859b6b 100644 (file)
@@ -33,8 +33,10 @@ file.reference.jcustomer-lib.jar=lib/jcustomer-lib.jar
 file.reference.jmailer-ee.jar=lib/jmailer-ee.jar
 file.reference.jphone-core.jar=lib/jphone-core.jar
 file.reference.jphone-lib.jar=lib/jphone-lib.jar
+file.reference.jproduct-core.jar=lib/jproduct-core.jar
 file.reference.jshop-core.jar=lib/jshop-core.jar
 file.reference.jshop-ee-lib.jar=lib/jshop-ee-lib.jar
+file.reference.jshop-receipt-lib.jar=lib/jshop-receipt-lib.jar
 file.reference.juser-core.jar=lib/juser-core.jar
 file.reference.juser-lib.jar=lib/juser-lib.jar
 file.reference.juser-activity-core.jar=lib/juser-activity-core.jar
@@ -69,9 +71,12 @@ javac.classpath=\
     ${file.reference.jcustomer-lib.jar}:\
     ${file.reference.jphone-core.jar}:\
     ${file.reference.jphone-lib.jar}:\
+    ${file.reference.jproduct-core.jar}:\
     ${file.reference.jshop-core.jar}:\
     ${file.reference.jshop-ee-lib.jar}:\
+    ${file.reference.jshop-receipt-lib.jar}:\
     ${file.reference.jmailer-ee.jar}:\
+    ${libs.GNU_JPDF_1.7.0.classpath}:\
     ${reference.pizzaservice-core.jar}:\
     ${reference.pizzaservice-lib.jar}:\
     ${reference.pizzaservice-mailer.jar}:\
@@ -131,8 +136,10 @@ source.reference.jcustomer-lib.jar=../jcustomer-lib/src/
 source.reference.jmailer-ee.jar=../jmailer-ee/src/
 source.reference.jphone-core.jar=../jphone-core/src/
 source.reference.jphone-lib.jar=../jphone-lib/src/
+source.reference.jproduct-core.jar=../jproduct-core/src/
 source.reference.jshop-core.jar=../../jshop-core/src/
 source.reference.jshop-ee-lib.jar=../../jshop-ee-lib/src/
+source.reference.jshop-receipt-lib.jar=../jshop-receipt-lib/src/
 source.reference.juser-core.jar=../juser-core/src/
 source.reference.juser-lib.jar=../juser-lib/src/
 source.reference.juser-activity-core.jar=../juser-activity-core/src/
index 3282b4238c83278b6f637d05b3e15d8ed4e7a704..06b9cc46f0d7dcba9ae31ab93fe975b555cbd3a7 100644 (file)
             <included-library dirs="200">file.reference.jcustomer-lib.jar</included-library>
             <included-library dirs="200">file.reference.jphone-core.jar</included-library>
             <included-library dirs="200">file.reference.jphone-lib.jar</included-library>
+            <included-library dirs="200">file.reference.jproduct-core.jar</included-library>
             <included-library dirs="200">file.reference.jshop-core.jar</included-library>
             <included-library dirs="200">file.reference.jshop-ee-lib.jar</included-library>
+            <included-library dirs="200">file.reference.jshop-receipt-lib.jar</included-library>
             <included-library dirs="200">file.reference.jmailer-ee.jar</included-library>
+            <included-library dirs="200">libs.GNU_JPDF_1.7.0.classpath</included-library>
             <included-library dirs="200">reference.pizzaservice-core.jar</included-library>
             <included-library dirs="200">reference.pizzaservice-lib.jar</included-library>
             <included-library dirs="200">reference.pizzaservice-mailer.jar</included-library>
diff --git a/src/java/org/mxchange/pizzaservice/beans/checkout/CheckoutMessageBean.java b/src/java/org/mxchange/pizzaservice/beans/checkout/CheckoutMessageBean.java
new file mode 100644 (file)
index 0000000..7d2b021
--- /dev/null
@@ -0,0 +1,206 @@
+/*
+ * Copyright (C) 2016 Roland Häder
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+package org.mxchange.pizzaservice.beans.checkout;
+
+import java.io.Serializable;
+import java.text.MessageFormat;
+import java.util.List;
+import javax.ejb.ActivationConfigProperty;
+import javax.ejb.EJB;
+import javax.ejb.MessageDriven;
+import javax.jms.JMSException;
+import javax.jms.Message;
+import javax.jms.MessageListener;
+import javax.jms.ObjectMessage;
+import javax.naming.Context;
+import javax.naming.InitialContext;
+import javax.naming.NamingException;
+import org.mxchange.jcoreeelogger.beans.local.logger.Log;
+import org.mxchange.jcoreeelogger.beans.local.logger.LoggerBeanLocal;
+import org.mxchange.jcustomercore.exceptions.CustomerAlreadyRegisteredException;
+import org.mxchange.jcustomercore.model.customer.Customer;
+import org.mxchange.jcustomercore.model.customer.CustomerSessionBeanRemote;
+import org.mxchange.jshopcore.model.basket.AddableBasketItem;
+import org.mxchange.jshopcore.model.basket.BasketSessionBeanRemote;
+import org.mxchange.jshopcore.model.receipt.ReceiptBeanRemote;
+import org.mxchange.jshopcore.wrapper.WrapableCheckout;
+
+/**
+ * A message-driven bean for checkouts
+ * <p>
+ * @author Roland Häder<roland@mxchange.org>
+ */
+@MessageDriven (
+               name = "checkout",
+               description = "A message bean for shop checkouts",
+               activationConfig = {
+                       @ActivationConfigProperty (propertyName = "destinationType", propertyValue = "javax.jms.Queue"),
+                       @ActivationConfigProperty (propertyName = "destinationLookup", propertyValue = "jms/shopCheckoutQueue")
+               }
+)
+public class CheckoutMessageBean implements MessageListener {
+
+       /**
+        * Basket bean
+        */
+       @EJB
+       private BasketSessionBeanRemote basketBean;
+
+       /**
+        * Customer instance
+        */
+       @EJB
+       private CustomerSessionBeanRemote customerBean;
+
+       /**
+        * Logger bean
+        */
+       @Log
+       private LoggerBeanLocal loggerBeanLocal;
+
+       /**
+        * Receipt bean
+        */
+       @EJB
+       private ReceiptBeanRemote receiptBean;
+
+       /**
+        * Default constructor
+        */
+       public CheckoutMessageBean () {
+               try {
+                       // Get initial context
+                       Context context = new InitialContext();
+
+                       // Lookup logger
+                       this.loggerBeanLocal = (LoggerBeanLocal) context.lookup("java:global/jcore-logger-ejb/logger!org.mxchange.jcoreeelogger.beans.local.logger.LoggerBeanLocal"); //NOI18N
+               } catch (final NamingException ex) {
+                       // Continue to throw
+                       throw new RuntimeException(MessageFormat.format("context.lookup() failed: {0}", ex.getMessage()), ex); //NOI18N
+               }
+       }
+
+       @Override
+       public void onMessage (final Message message) {
+               // Trace message
+               this.loggerBeanLocal.logTrace(MessageFormat.format("onMessage: message={0} - CALLED!", message)); //NOI18N
+
+               // Is the message castable to ObjectMessage?
+               if (null == message) {
+                       // message is null
+                       throw new NullPointerException("message is null"); //NOI18N
+               } else if (!(message instanceof ObjectMessage)) {
+                       // Not castable
+                       throw new ClassCastException(MessageFormat.format("message cannot be casted to ObjectMessage: {0}", message)); //NOI18N
+               }
+
+               // Securely cast it
+               ObjectMessage objectMessage = (ObjectMessage) message;
+
+               // Init instance
+               Serializable object;
+
+               try {
+                       // Get object from it
+                       object = objectMessage.getObject();
+               } catch (final JMSException ex) {
+                       // Log exception ...
+                       this.loggerBeanLocal.logException(ex);
+
+                       // ... and don't continue
+                       return;
+               }
+
+               // Debug message
+               this.loggerBeanLocal.logDebug(MessageFormat.format("onMessage: object={0}", object)); //NOI18N
+
+               // Does this object implement WrapableCheckout ?
+               if (null == object) {
+                       // object cannot be null
+                       throw new NullPointerException("object is null"); //NOI18N
+               } else if (!(object instanceof WrapableCheckout)) {
+                       // Not proper interface used
+                       throw new ClassCastException(MessageFormat.format("object does not implement WrapableCheckout: {0}", object)); //NOI18N
+               }
+
+               // Securely cast it
+               WrapableCheckout checkout = (WrapableCheckout) object;
+
+               // Get customer and list from it
+               Customer customer = checkout.getCustomer();
+               List<AddableBasketItem> orderedItems = checkout.getList();
+
+               // Debug message
+               this.loggerBeanLocal.logDebug(MessageFormat.format("onMessage: customerInstance={0},itemList={1}", customer, orderedItems)); //NOI18N
+
+               // Check both on null
+               if (null == customer) {
+                       // customer is null
+                       throw new NullPointerException("customer is null"); //NOI18N
+               } else if (null == orderedItems) {
+                       // list is null
+                       throw new NullPointerException("list is null"); //NOI18N
+               }
+
+               try {
+                       // Is the customer already registered?
+                       if (this.customerBean.isRegistered(customer)) {
+                               // Already registered, so get all data
+                               customer = this.customerBean.fillCustomerData(customer);
+                       } else {
+                               // Register customer first, this generates a customer number
+                               customer = this.customerBean.registerCustomer(customer);
+                       }
+               } catch (final CustomerAlreadyRegisteredException ex) {
+                       // Log exception and abort
+                       this.loggerBeanLocal.logException(ex);
+                       return;
+               }
+
+               // Is the instance set?
+               if (null == customer) {
+                       // Customer is null
+                       throw new NullPointerException("customer is null"); //NOI18N
+               }
+
+               // Make sure the number has been regenerated
+               if (customer.getCustomerNumber() == null) {
+                       // Not assigned
+                       throw new NullPointerException(MessageFormat.format("registerCustomer() did not create a custome number: customerInstance={0}", customer)); //NOI18N
+               }
+
+               // Now add the ordered item list
+               String accessKey = this.basketBean.registerItems(customer, orderedItems);
+
+               // Debug message
+               this.loggerBeanLocal.logDebug(MessageFormat.format("onMessage: accessKey={0}", accessKey)); //NOI18N
+
+               // Should not be null
+               if (null == accessKey) {
+                       // Abort here
+                       throw new NullPointerException("accessKey is null"); //NOI18N
+               }
+
+               // Set access key and customer
+               this.receiptBean.setAccessKey(accessKey);
+               this.receiptBean.setCustomer(customer);
+
+               // Trace message
+               this.loggerBeanLocal.logTrace("onMessage: EXIT!"); //NOI18N
+       }
+
+}
diff --git a/src/java/org/mxchange/pizzaservice/model/basket/BasketSessionBean.java b/src/java/org/mxchange/pizzaservice/model/basket/BasketSessionBean.java
new file mode 100644 (file)
index 0000000..07f7148
--- /dev/null
@@ -0,0 +1,117 @@
+/*
+ * Copyright (C) 2016 Roland Häder
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+package org.mxchange.pizzaservice.model.basket;
+
+import java.text.MessageFormat;
+import java.util.GregorianCalendar;
+import java.util.List;
+import javax.ejb.Stateless;
+import javax.persistence.EntityExistsException;
+import org.mxchange.jcoreee.database.BaseDatabaseBean;
+import org.mxchange.jcustomercore.model.customer.Customer;
+import org.mxchange.jshopcore.model.basket.AddableBasketItem;
+import org.mxchange.jshopcore.model.basket.BasketSessionBeanRemote;
+import org.mxchange.jshopcore.model.customer.CustomerUtils;
+import org.mxchange.jshopcore.model.order.Orderable;
+import org.mxchange.jshopcore.model.order.ShopOrder;
+
+/**
+ * A basket for orderable items
+ * <p>
+ * @author Roland Häder<roland@mxchange.org>
+ */
+@Stateless (name = "basket", description = "A bean handling persisting baskets of logged-in customers")
+public class BasketSessionBean extends BaseDatabaseBean implements BasketSessionBeanRemote {
+
+       /**
+        * Serial number
+        */
+       private static final long serialVersionUID = 4_384_123_923_163_957L;
+
+       /**
+        * Default constructor
+        */
+       public BasketSessionBean () {
+       }
+
+       @Override
+       public void clear () {
+               // @TODO Nothing done so far
+       }
+
+       @Override
+       public String registerItems (final Customer customer, final List<AddableBasketItem> orderedItems) {
+               // Trace message
+               this.getLoggerBeanLocal().logTrace(MessageFormat.format("registerItems: customer={0},itemList={1} - CALLED!", customer, orderedItems)); //NOI18N
+
+               // Init variable for access key
+               String accessKey;
+
+               // customer/itemList should not be null
+               if (null == customer) {
+                       // Abort here
+                       throw new NullPointerException("customer is null"); //NOI18N
+               } else if (null == orderedItems) {
+                       // Abort here
+                       throw new NullPointerException("itemList is null"); //NOI18N
+               } else if (customer.getCustomerId() == null) {
+                       // null pointer found
+                       throw new NullPointerException(MessageFormat.format("customer {0} id is null", customer)); //NOI18N
+               } else if (customer.getCustomerId() == 0) {
+                       // id not set
+                       throw new IllegalArgumentException(MessageFormat.format("customer {0} has no id set", customer)); //NOI18N
+               } else if (orderedItems.isEmpty()) {
+                       // Empty list
+                       throw new IllegalArgumentException("item list is empty"); //NOI18N
+               }
+
+               // First try to register the order (to get an id number from it)
+               try {
+                       // Generate access key
+                       accessKey = CustomerUtils.generateAccessKey(this.getEntityManager(), customer);
+
+                       // Debug message
+                       this.getLoggerBeanLocal().logDebug(MessageFormat.format("registerItems: accessKey={0}", accessKey)); //NOI18N
+
+                       // Create order object
+                       Orderable order = new ShopOrder();
+                       order.setCustomer(customer);
+                       order.setAccessKey(accessKey);
+                       order.setOrderedItems(orderedItems);
+                       order.setOrderCreated(new GregorianCalendar());
+
+                       // Persist it
+                       this.getEntityManager().persist(order);
+               } catch (final EntityExistsException ex) {
+                       // Log exception
+                       this.getLoggerBeanLocal().logException(ex);
+
+                       /*
+                        * Don't return an access key as the exception should never be
+                        * thrown.
+                        */
+                       accessKey = null;
+               }
+
+               // Trace message
+               this.getLoggerBeanLocal().logTrace(MessageFormat.format("registerItems: accessKey={0} - EXIT!", accessKey)); //NOI18N
+
+               // Return it
+               return accessKey;
+       }
+
+}
diff --git a/src/java/org/mxchange/pizzaservice/model/category/AdminCategorySessionBean.java b/src/java/org/mxchange/pizzaservice/model/category/AdminCategorySessionBean.java
new file mode 100644 (file)
index 0000000..afce2c3
--- /dev/null
@@ -0,0 +1,130 @@
+/*
+ * Copyright (C) 2016 Roland Häder
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+package org.mxchange.pizzaservice.model.category;
+
+import java.text.MessageFormat;
+import javax.ejb.Stateless;
+import javax.persistence.EntityNotFoundException;
+import javax.persistence.NoResultException;
+import javax.persistence.Query;
+import org.mxchange.jcoreee.database.BaseDatabaseBean;
+import org.mxchange.jproduct.exceptions.CannotAddCategoryException;
+import org.mxchange.jproduct.exceptions.CategoryTitleAlreadyUsedException;
+import org.mxchange.jproduct.model.category.Category;
+import org.mxchange.jproduct.model.category.ProductCategory;
+import org.mxchange.jshopcore.model.category.AdminCategorySessionBeanRemote;
+
+/**
+ * An EJB for administrative access on categories
+ * <p>
+ * @author Roland Häder<roland@mxchange.org>
+ */
+@Stateless (name = "admin_category", description = "An administrative bean handling product categories")
+public class AdminCategorySessionBean extends BaseDatabaseBean implements AdminCategorySessionBeanRemote {
+
+       /**
+        * Serial number
+        */
+       private static final long serialVersionUID = 26_143_895_789_581L;
+
+       @Override
+       public Category doAdminAddCategory (final Category category) throws CategoryTitleAlreadyUsedException, CannotAddCategoryException {
+               // Trace message
+               this.getLoggerBeanLocal().logTrace(MessageFormat.format("doAdminAddCategory: category={0} - CALLED!", category)); //NOI18N
+
+               if (null == category) {
+                       // category is null
+                       throw new NullPointerException("category is null"); //NOI18N
+               } else if (this.getEntityManager() == null) {
+                       // Connection is not there
+                       throw new NullPointerException("connection is null"); //NOI18N
+               }
+
+               // The connection must be there
+               if (this.isCategoryTitleUsed(category)) {
+                       // Then abort here
+                       throw new CategoryTitleAlreadyUsedException(category);
+               }
+
+               // Perist the category
+               this.getEntityManager().persist(category);
+
+               // Flush it
+               this.getEntityManager().flush();
+
+               // Trace message
+               this.getLoggerBeanLocal().logTrace(MessageFormat.format("doAdminAddCategory: category={0} - EXIT!", category)); //NOI18N
+
+               // Return it
+               return category;
+       }
+
+       /**
+        * Checks if the category's title has already been used as they need to be
+        * unique. This method works case-insensitive. Any spaces, new-line,
+        * carriage-return or tabulator characters are trimmed away. If the title
+        * has been used already, for performance reasons, the id and parent id are
+        * set in the category object.
+        * <p>
+        * @param category Category instance
+        * <p>
+        * @return Whether the category's title has been used
+        */
+       private boolean isCategoryTitleUsed (final Category category) {
+               // Trace message
+               this.getLoggerBeanLocal().logTrace(MessageFormat.format("isCategoryTitleUsed: category={0} - CALLED!", category)); //NOI18N
+
+               // The connection must be there
+               if (null == category) {
+                       // category is null
+                       throw new NullPointerException("category is null"); //NOI18N
+               } else if (this.getEntityManager() == null) {
+                       // Connection is not there
+                       throw new NullPointerException("connection is null"); //NOI18N
+               }
+
+               // Default is not found
+               boolean isUsed = false;
+
+               // Debug message
+               this.getLoggerBeanLocal().logDebug(MessageFormat.format("isCategoryTitleUsed: category.id={0},category.title={1},category.parentId={2}", category.getCategoryId(), category.getCategoryTitle(), category.getParentCategory())); //NOI18N
+
+               // Try to locate it
+               try {
+                       // Get query instance
+                       Query query = this.getEntityManager().createQuery("SELECT c FROM category AS c WHERE LOWER(c.categoryTitle) = LOWER(:param)", ProductCategory.class); //NOI18N
+                       query.setParameter("param", category.getCategoryTitle()); //NOI18N
+                       Category cat = (Category) query.getSingleResult();
+
+                       // Is found, so copy the object
+                       category.copyAll(cat);
+
+                       // Mark as found
+                       isUsed = true;
+               } catch (final EntityNotFoundException | NoResultException e) {
+                       // Not found
+                       this.getLoggerBeanLocal().logWarning(e.getMessage());
+               }
+
+               // Trace message
+               this.getLoggerBeanLocal().logTrace(MessageFormat.format("isCategoryTitleUsed: isUsed={0} - EXIT!", isUsed)); //NOI18N
+
+               // Return it
+               return isUsed;
+       }
+
+}
diff --git a/src/java/org/mxchange/pizzaservice/model/category/CategorySessionBean.java b/src/java/org/mxchange/pizzaservice/model/category/CategorySessionBean.java
new file mode 100644 (file)
index 0000000..9f95f44
--- /dev/null
@@ -0,0 +1,72 @@
+/*
+ * Copyright (C) 2016 Roland Häder
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+package org.mxchange.pizzaservice.model.category;
+
+import java.text.MessageFormat;
+import java.util.List;
+import javax.ejb.Stateless;
+import javax.persistence.Query;
+import org.mxchange.jcoreee.database.BaseDatabaseBean;
+import org.mxchange.jproduct.model.category.Category;
+import org.mxchange.jproduct.model.category.ProductCategory;
+import org.mxchange.jshopcore.model.category.CategorySessionBeanRemote;
+
+/**
+ * Main shop class
+ * <p>
+ * @author Roland Häder<roland@mxchange.org>
+ */
+@Stateless (name = "category", description = "A bean handling categories for all others (non-admin)")
+public class CategorySessionBean extends BaseDatabaseBean implements CategorySessionBeanRemote {
+
+       /**
+        * Serial number
+        */
+       private static final long serialVersionUID = 58_137_539_530_279L;
+
+       /**
+        * Default constructor
+        */
+       public CategorySessionBean () {
+       }
+
+       @Override
+       @SuppressWarnings ("unchecked")
+       public List<Category> getAllCategories () {
+               // Trace message
+               this.getLoggerBeanLocal().logTrace("getAllCategories: CALLED!"); //NOI18N
+
+               // The connection must be there
+               if (this.getEntityManager() == null) {
+                       // Connection is not there
+                       throw new NullPointerException("connection is null"); //NOI18N
+               }
+
+               // Create statement
+               Query query = this.getEntityManager().createQuery("SELECT c FROM category AS c ORDER BY c.categoryId ASC", ProductCategory.class);
+
+               // Get result
+               List<Category> list = query.getResultList();
+
+               // Trace message
+               this.getLoggerBeanLocal().logTrace(MessageFormat.format("getAllCategories: list({0})={1} - EXIT!", list.size(), list)); //NOI18N
+
+               // Return it
+               return list;
+       }
+
+}
diff --git a/src/java/org/mxchange/pizzaservice/model/customer/ShopCustomerSessionBean.java b/src/java/org/mxchange/pizzaservice/model/customer/ShopCustomerSessionBean.java
new file mode 100644 (file)
index 0000000..d0274fd
--- /dev/null
@@ -0,0 +1,151 @@
+/*
+ * Copyright (C) 2016 Roland Häder
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+package org.mxchange.pizzaservice.model.customer;
+
+import java.text.MessageFormat;
+import java.util.GregorianCalendar;
+import javax.ejb.Stateless;
+import javax.persistence.EntityNotFoundException;
+import org.mxchange.jcoreee.database.BaseDatabaseBean;
+import org.mxchange.jcustomercore.exceptions.CustomerAlreadyRegisteredException;
+import org.mxchange.jcustomercore.exceptions.CustomerNotFoundException;
+import org.mxchange.jcustomercore.model.customer.Customer;
+import org.mxchange.jcustomercore.model.customer.CustomerSessionBeanRemote;
+
+/**
+ * A customer bean which hides the customer instance
+ * <p>
+ * @author Roland Häder<roland@mxchange.org>
+ */
+@Stateless (name = "shop_customer", description = "A bean handling the customer data")
+public class ShopCustomerSessionBean extends BaseDatabaseBean implements CustomerSessionBeanRemote {
+
+       /**
+        * Serial number
+        */
+       private static final long serialVersionUID = 542_145_347_916L;
+
+       /**
+        * Default constructor
+        */
+       public ShopCustomerSessionBean () {
+       }
+
+       @Override
+       public Customer fillCustomerData (final Customer customer) {
+               // Trace message
+               this.getLoggerBeanLocal().logTrace(MessageFormat.format("fillCustomerData: customer={0} - CALLED!", customer)); //NOI18N
+
+               // customer should not be null
+               if (null == customer) {
+                       // Abort here
+                       throw new NullPointerException("customer is null"); //NOI18N
+               }
+
+               // Try it
+               try {
+                       // Try to locate it
+                       Customer cat = this.getEntityManager().getReference(Customer.class, customer);
+
+                       // Copy all data
+                       customer.copyAll(cat);
+               } catch (final EntityNotFoundException ex) {
+                       // Log it
+                       this.getLoggerBeanLocal().logException(ex);
+
+                       // Return null
+                       return null;
+               }
+
+               // Trace message
+               this.getLoggerBeanLocal().logTrace(MessageFormat.format("fillCustomerData: customer={0} - EXIT!", customer)); //NOI18N
+
+               // Return prepared instance
+               return customer;
+       }
+
+       @Override
+       public Customer findCustomerById (final Long customerId) throws CustomerNotFoundException {
+               throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
+       }
+
+       @Override
+       public boolean isRegistered (final Customer customer) {
+               // Trace message
+               this.getLoggerBeanLocal().logTrace(MessageFormat.format("isRegistered: customer={0} - CALLED!", customer)); //NOI18N
+
+               // customer should not be null
+               if (null == customer) {
+                       // Abort here
+                       throw new NullPointerException("customer is null"); //NOI18N
+               }
+
+               // Try this
+               try {
+                       Customer c = this.getEntityManager().getReference(Customer.class, customer);
+               } catch (final EntityNotFoundException ex) {
+                       // Log it
+                       this.getLoggerBeanLocal().logException(ex);
+
+                       // Did not finish
+                       return false;
+               }
+
+               // Found it
+               return true;
+       }
+
+       @Override
+       public Customer registerCustomer (final Customer customer) throws CustomerAlreadyRegisteredException {
+               // Trace message
+               this.getLoggerBeanLocal().logTrace(MessageFormat.format("registerCustomer: customer={0} - CALLED!", customer)); //NOI18N
+
+               // customer should not be null
+               if (null == customer) {
+                       // Abort here
+                       throw new NullPointerException("customer is null"); //NOI18N
+               }
+
+               // Is the customer registered?
+               if (this.isRegistered(customer)) {
+                       // Already registered
+                       throw new CustomerAlreadyRegisteredException(customer);
+               }
+
+               // Debug message
+               this.getLoggerBeanLocal().logDebug(MessageFormat.format("registerCustomer: Preparing statement for customer={0}", customer)); //NOI18N
+
+               // Set creation timestamp
+               customer.setCustomerCreated(new GregorianCalendar());
+
+               // Try to persist it
+               this.getEntityManager().persist(customer);
+
+               // Flush it as the id might be needed
+               this.getEntityManager().flush();
+
+               // Debug message
+               this.getLoggerBeanLocal().logDebug(MessageFormat.format("registerCustomer: customer.id={0}", customer.getCustomerId())); //NOI18N
+
+               // Trace message
+               this.getLoggerBeanLocal().logTrace(MessageFormat.format("registerCustomer: customer={0} - CALLED!", customer)); //NOI18N
+
+               // Return prepared instance
+               return customer;
+       }
+
+}
diff --git a/src/java/org/mxchange/pizzaservice/model/product/AdminProductSessionBean.java b/src/java/org/mxchange/pizzaservice/model/product/AdminProductSessionBean.java
new file mode 100644 (file)
index 0000000..ae0f909
--- /dev/null
@@ -0,0 +1,163 @@
+/*
+ * Copyright (C) 2016 Roland Häder
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+package org.mxchange.pizzaservice.model.product;
+
+import java.text.MessageFormat;
+import java.util.List;
+import javax.ejb.Stateless;
+import javax.persistence.EntityExistsException;
+import javax.persistence.EntityNotFoundException;
+import javax.persistence.NoResultException;
+import javax.persistence.Query;
+import org.mxchange.jcoreee.database.BaseDatabaseBean;
+import org.mxchange.jproduct.exceptions.CannotAddProductException;
+import org.mxchange.jproduct.exceptions.ProductTitleAlreadyUsedException;
+import org.mxchange.jproduct.model.product.GenericProduct;
+import org.mxchange.jproduct.model.product.Product;
+import org.mxchange.jshopcore.model.product.AdminProductSessionBeanRemote;
+
+/**
+ * A session bean for non-administrative roles for products
+ * <p>
+ * @author Roland Häder<roland@mxchange.org>
+ */
+@Stateless (name = "admin_product", description = "An administrative bean handling products")
+public class AdminProductSessionBean extends BaseDatabaseBean implements AdminProductSessionBeanRemote {
+
+       /**
+        * Serial number
+        */
+       private static final long serialVersionUID = 65_173_487_394_812L;
+
+       /**
+        * Default constructor
+        */
+       public AdminProductSessionBean () {
+       }
+
+       @Override
+       public Product doAdminAddProduct (final Product product) throws ProductTitleAlreadyUsedException, CannotAddProductException {
+               // Trace message
+               this.getLoggerBeanLocal().logTrace(MessageFormat.format("doAdminAddProduct: product={0} - CALLED!", product)); //NOI18N
+
+               // Check if product's title is used
+               if (null == product) {
+                       // product is null
+                       throw new NullPointerException("product is null"); //NOI18N
+               } else if (this.getEntityManager() == null) {
+                       // Connection is not there
+                       throw new NullPointerException("connection is null"); //NOI18N
+               } else if (this.isProductTitleUsed(product)) {
+                       // Throw exception
+                       throw new ProductTitleAlreadyUsedException(product);
+               }
+
+               try {
+                       // Persist it
+                       this.getEntityManager().persist(product);
+
+                       // Flush it as the id might be needed immediately
+                       this.getEntityManager().flush();
+               } catch (final EntityExistsException ex) {
+                       // Continue to throw
+                       throw new CannotAddProductException(ex);
+               }
+
+               // Trace message
+               this.getLoggerBeanLocal().logTrace(MessageFormat.format("doAdminAddProduct: product={0} - EXIT!", product)); //NOI18N
+
+               // Return it
+               return product;
+       }
+
+       @Override
+       @SuppressWarnings ("unchecked")
+       public List<Product> getAllProducts () {
+               // Trace message
+               this.getLoggerBeanLocal().logTrace("getAllProducts: CALLED!"); //NOI18N
+
+               // The connection must be there
+               if (this.getEntityManager() == null) {
+                       // Connection is not there
+                       throw new NullPointerException("connection is null"); //NOI18N
+               }
+
+               // Create statement
+               Query query = this.getEntityManager().createQuery("SELECT p FROM products AS p ORDER BY p.productId ASC", GenericProduct.class); //NOI18N
+
+               // Get list
+               List<Product> list = query.getResultList();
+
+               // Trace message
+               this.getLoggerBeanLocal().logTrace(MessageFormat.format("getAllProducts: list({0})={1} - EXIT!", list.size(), list)); //NOI18N
+
+               // Return it
+               return list;
+       }
+
+       /**
+        * Checks if the product's title has already been used as they need to be
+        * unique. This method works case-insensitive. Any spaces, new-line,
+        * carriage-return or tabulator characters are trimmed away. If the title
+        * has been used already, for performance reasons, the whole data is set in
+        * the product object.
+        * <p>
+        * @param product Product instance
+        * <p>
+        * @return Whether the product's title has been used
+        */
+       private boolean isProductTitleUsed (final Product product) {
+               // Trace message
+               this.getLoggerBeanLocal().logTrace(MessageFormat.format("isProductTitleUsed: Product={0} - CALLED!", product)); //NOI18N
+
+               // The connection must be there
+               if (null == product) {
+                       // product is null
+                       throw new NullPointerException("product is null"); //NOI18N
+               } else if (this.getEntityManager() == null) {
+                       // Connection is not there
+                       throw new NullPointerException("connection is null"); //NOI18N
+               }
+
+               // Default is not found
+               boolean isUsed = false;
+
+               // Try to locate it
+               try {
+                       // Get query instance
+                       Query query = this.getEntityManager().createQuery("SELECT p FROM products AS p WHERE LOWER(p.productTitle) = LOWER(:param)", GenericProduct.class); //NOI18N
+                       query.setParameter("param", product.getProductTitle()); //NOI18N
+                       Product pro = (Product) query.getSingleResult();
+
+                       // Is found, so copy the object
+                       product.copyAll(pro);
+
+                       // Mark as found
+                       isUsed = true;
+               } catch (final EntityNotFoundException | NoResultException e) {
+                       // Not found
+                       this.getLoggerBeanLocal().logWarning(e.getMessage());
+               }
+
+               // Trace message
+               this.getLoggerBeanLocal().logTrace(MessageFormat.format("isProductTitleUsed: isUsed={0} - EXIT!", isUsed)); //NOI18N
+
+               // Return it
+               return isUsed;
+       }
+
+}
diff --git a/src/java/org/mxchange/pizzaservice/model/product/ProductSessionBean.java b/src/java/org/mxchange/pizzaservice/model/product/ProductSessionBean.java
new file mode 100644 (file)
index 0000000..d7d0eef
--- /dev/null
@@ -0,0 +1,103 @@
+/*
+ * Copyright (C) 2016 Roland Häder
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+package org.mxchange.pizzaservice.model.product;
+
+import java.text.MessageFormat;
+import java.util.Iterator;
+import java.util.LinkedList;
+import java.util.List;
+import javax.ejb.EJB;
+import javax.ejb.Stateless;
+import org.mxchange.jcoreee.database.BaseDatabaseBean;
+import org.mxchange.jproduct.model.product.Product;
+import org.mxchange.jshopcore.model.product.AdminProductSessionBeanRemote;
+import org.mxchange.jshopcore.model.product.ProductSessionBeanRemote;
+
+/**
+ * A session bean for non-administrative roles for products
+ * <p>
+ * @author Roland Häder<roland@mxchange.org>
+ */
+@Stateless (name = "product", description = "A bean handling products for all others (non-admin)")
+public class ProductSessionBean extends BaseDatabaseBean implements ProductSessionBeanRemote {
+
+       /**
+        * Serial number
+        */
+       private static final long serialVersionUID = 65_173_487_394_812L;
+
+       /**
+        * Administrative bean
+        */
+       @EJB
+       private AdminProductSessionBeanRemote productBean;
+
+       /**
+        * Default constructor
+        */
+       public ProductSessionBean () {
+       }
+
+       @Override
+       public List<Product> getAvailableProducts () {
+               // Trace message
+               this.getLoggerBeanLocal().logTrace("getAvailableProducts: CALLED!"); //NOI18N
+
+               // The connection must be there
+               if (this.getEntityManager() == null) {
+                       // Connection is not there
+                       throw new NullPointerException("connection is null"); //NOI18N
+               }
+
+               // Get all products
+               List<Product> allProducts = this.productBean.getAllProducts();
+
+               // Trace message
+               this.getLoggerBeanLocal().logTrace(MessageFormat.format("getAvailableProducts: allProducts({0})={1}", allProducts.size(), allProducts)); //NOI18N
+
+               // Init deque
+               List<Product> deque = new LinkedList<>();
+
+               // Get iterator
+               Iterator<Product> iterator = allProducts.iterator();
+
+               // Walk through all and add only available
+               while (iterator.hasNext()) {
+                       // Get element
+                       Product localProduct = iterator.next();
+
+                       // Debug message
+                       this.getLoggerBeanLocal().logDebug(MessageFormat.format("getAvailableProducts: localProduct={0}", localProduct)); //NOI18N
+
+                       // Is this available?
+                       if (localProduct.getProductAvailability()) {
+                               // Debug message
+                               this.getLoggerBeanLocal().logDebug(MessageFormat.format("getAvailableProducts: localProduct={0} - ADDED!", localProduct)); //NOI18N
+
+                               // Add it
+                               deque.add(localProduct);
+                       }
+               }
+
+               // Trace message
+               this.getLoggerBeanLocal().logTrace(MessageFormat.format("getAvailableProducts: deque({0})={1} - EXIT!", deque.size(), deque)); //NOI18N
+
+               // Return it
+               return deque;
+       }
+
+}
diff --git a/src/java/org/mxchange/pizzaservice/model/receipt/PdfReceiptSessionBean.java b/src/java/org/mxchange/pizzaservice/model/receipt/PdfReceiptSessionBean.java
new file mode 100644 (file)
index 0000000..34267c4
--- /dev/null
@@ -0,0 +1,136 @@
+/*
+ * Copyright (C) 2016 Roland Häder
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+package org.mxchange.pizzaservice.model.receipt;
+
+import java.text.MessageFormat;
+import javax.ejb.Stateless;
+import javax.naming.Context;
+import javax.naming.InitialContext;
+import javax.naming.NamingException;
+import org.mxchange.jcoreee.database.BaseDatabaseBean;
+import org.mxchange.jcustomercore.model.customer.Customer;
+import org.mxchange.jshopcore.model.receipt.ReceiptBeanRemote;
+import org.mxchange.jshopcore.model.receipt.WrapableReceipt;
+import org.mxchange.jshopreceipt.receipt.PdfReceiptBeanLocal;
+import org.mxchange.jshopreceipt.receipt.Receipt;
+
+/**
+ * A stateless session bean for producing official receipts in Abobe's whacky
+ * binary format. This class uses GNUjpdf which allows using ordinary graphic
+ * libraries.
+ * <p>
+ * @author Roland Häder<roland@mxchange.org>
+ */
+@Stateless (name = "pdf", description = "A bean creating PDF receipts")
+public class PdfReceiptSessionBean extends BaseDatabaseBean implements ReceiptBeanRemote {
+
+       /**
+        * Serial number
+        */
+       private static final long serialVersionUID = 384_578_171_659_628L;
+
+       /**
+        * Access key
+        */
+       private String accessKey;
+
+       /**
+        * Customer instance
+        */
+       private Customer customer;
+
+       /**
+        * PDF receipt injection
+        */
+       @Receipt
+       private PdfReceiptBeanLocal pdfReceiptBeanLocal;
+
+       /**
+        * Default constructor
+        */
+       public PdfReceiptSessionBean () {
+               try {
+                       // Get initial context
+                       Context context = new InitialContext();
+
+                       // Lookup pdf receipt
+                       this.pdfReceiptBeanLocal = (PdfReceiptBeanLocal) context.lookup("java:global/jshop-receipt-ejb/pdf-receipt!org.mxchange.jshopreceipt.receipt.PdfReceiptBeanLocal"); //NOI18N
+               } catch (final NamingException ex) {
+                       // Continue to throw
+                       throw new RuntimeException(MessageFormat.format("context.lookup() failed: {0}", ex.getMessage()), ex); //NOI18N
+               }
+       }
+
+       @Override
+       public WrapableReceipt createReceiptFromAccessKey (final String accessKey) {
+               // Trace message
+               this.getLoggerBeanLocal().logTrace(MessageFormat.format("createReceiptFromAccessKey: accessKey={0} - CALLED!", accessKey)); //NOI18N
+
+               return null;
+       }
+
+       @Override
+       public String fetchAccessKey (final Customer customer) {
+               // Trace message
+               this.getLoggerBeanLocal().logTrace(MessageFormat.format("fetchAccessKey: customer={0} - EXIT!", customer)); //NOI18N
+
+               // customer should not be null
+               if (null == customer) {
+                       // Abort here
+                       throw new NullPointerException("customer is null"); //NOI18N
+               } else if (this.getCustomer() == null) {
+                       // Don't continue, too.
+                       throw new NullPointerException("this.getCustomer() returns null"); //NOI18N
+               }
+
+               // Default is null
+               String key = null;
+
+               // Is customer the same?
+               if (customer.equals(this.getCustomer())) {
+                       // Set access key
+                       key = this.getAccessKey();
+               }
+
+               // Trace message
+               this.getLoggerBeanLocal().logTrace(MessageFormat.format("fetchAccessKey: key={0} - EXIT!", key)); //NOI18N
+
+               // Return it
+               return key;
+       }
+
+       @Override
+       public String getAccessKey () {
+               return this.accessKey;
+       }
+
+       @Override
+       public void setAccessKey (final String accessKey) {
+               this.accessKey = accessKey;
+       }
+
+       @Override
+       public Customer getCustomer () {
+               return this.customer;
+       }
+
+       @Override
+       public void setCustomer (final Customer customer) {
+               this.customer = customer;
+       }
+
+}
diff --git a/src/java/org/mxchange/pizzaservice/receipt/PdfReceiptBean.java b/src/java/org/mxchange/pizzaservice/receipt/PdfReceiptBean.java
new file mode 100644 (file)
index 0000000..1650329
--- /dev/null
@@ -0,0 +1,56 @@
+/*
+ * Copyright (C) 2016 Roland Häder
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+package org.mxchange.pizzaservice.receipt;
+
+import gnu.jpdf.PDFJob;
+import javax.ejb.Singleton;
+import javax.ejb.Startup;
+import javax.inject.Inject;
+import org.mxchange.jshopreceipt.receipt.PdfReceiptBeanLocal;
+import org.mxchange.jshopreceipt.receipt.Receipt;
+
+/**
+ * A "centralized" logger bean
+ * <p>
+ * @author Roland Häder<roland@mxchange.org>
+ */
+@Startup
+@Singleton (name = "pdf-receipt", description = "An EJB for producing PDF receipts")
+public class PdfReceiptBean implements PdfReceiptBeanLocal {
+
+       /**
+        * PDF job instance
+        */
+       @Inject
+       @Receipt
+       private PDFJob job;
+
+       /**
+        * Default constructor
+        */
+       public PdfReceiptBean () {
+       }
+
+       /**
+        * Getter for PDF job
+        * <p>
+        * @return PDF job
+        */
+       private PDFJob getJob () {
+               return this.job;
+       }
+}
diff --git a/src/java/org/mxchange/pizzaservice/receipt/ReceiptFactory.java b/src/java/org/mxchange/pizzaservice/receipt/ReceiptFactory.java
new file mode 100644 (file)
index 0000000..120a61d
--- /dev/null
@@ -0,0 +1,55 @@
+/*
+ * Copyright (C) 2016 Roland Häder
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+package org.mxchange.pizzaservice.receipt;
+
+import gnu.jpdf.PDFJob;
+import javax.enterprise.inject.Produces;
+import javax.enterprise.inject.spi.InjectionPoint;
+import org.mxchange.jshopreceipt.receipt.Receipt;
+
+/**
+ * A logger factory
+ * <p>
+ * @author Roland Häder<roland@mxchange.org>
+ */
+public class ReceiptFactory {
+
+       /**
+        * Own job
+        */
+       private final PDFJob job;
+
+       /**
+        * Factory method
+        */
+       public ReceiptFactory () {
+               this.job = new PDFJob();
+       }
+
+       /**
+        * Produces a PDF job instance
+        * <p>
+        * @param caller Injection point
+        * <p>
+        * @return PDF job
+        */
+       @Produces
+       @Receipt
+       public PDFJob getJob (final InjectionPoint caller) {
+               return this.job;
+       }
+}