From: Roland Häder Date: Sat, 15 Apr 2017 22:00:52 +0000 (+0200) Subject: Not to be confused with services ... better rename it X-Git-Url: https://git.mxchange.org/?a=commitdiff_plain;h=caf32ee411d74f5d49229b88636b1742277a9626;p=pizzaservice-ejb.git Not to be confused with services ... better rename it Signed-off-by: Roland Häder --- diff --git a/src/java/org/mxchange/pizzaapplication/beans/resendlink/PizzaResendLinkSessionBean.java b/src/java/org/mxchange/pizzaapplication/beans/resendlink/PizzaResendLinkSessionBean.java deleted file mode 100644 index 3c2f9f4..0000000 --- a/src/java/org/mxchange/pizzaapplication/beans/resendlink/PizzaResendLinkSessionBean.java +++ /dev/null @@ -1,122 +0,0 @@ -/* - * 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 . - */ -package org.mxchange.pizzaapplication.beans.resendlink; - -import java.text.MessageFormat; -import java.util.Locale; -import javax.ejb.EJB; -import javax.ejb.EJBException; -import javax.ejb.Stateless; -import javax.mail.Address; -import javax.mail.internet.AddressException; -import javax.mail.internet.InternetAddress; -import org.mxchange.jusercore.exceptions.UserNotFoundException; -import org.mxchange.jusercore.exceptions.UserStatusConfirmedException; -import org.mxchange.jusercore.exceptions.UserStatusLockedException; -import org.mxchange.jusercore.model.register.UserRegistrationSessionBeanRemote; -import org.mxchange.jusercore.model.user.LoginUser; -import org.mxchange.jusercore.model.user.User; -import org.mxchange.jusercore.model.user.UserSessionBeanRemote; -import org.mxchange.jusercore.model.user.status.UserAccountStatus; -import org.mxchange.pizzaaplication.database.BasePizzaDatabaseBean; - -/** - * A session-based EJB for resending confirmation links - *

- * @author Roland Häder - */ -@Stateless (name = "resendLink", description = "A bean resending confirmation links") -public class PizzaResendLinkSessionBean extends BasePizzaDatabaseBean implements ResendLinkSessionBeanRemote { - - /** - * Serial number - */ - private static final long serialVersionUID = 71_546_726_857_195_360L; - - /** - * Registration bean - */ - @EJB - private UserRegistrationSessionBeanRemote registerBean; - - /** - * Regular user bean - */ - @EJB - private UserSessionBeanRemote userBean; - - @Override - public void resendConfirmationLink (final User user, final Locale locale, final String baseUrl) throws UserNotFoundException, UserStatusConfirmedException, UserStatusLockedException { - // Log trace message - this.getLoggerBeanLocal().logTrace(MessageFormat.format("{0}.resendConfirmationLink: user={1},locale={2},baseUrl={3} - CALLED!", this.getClass().getSimpleName(), user, locale, baseUrl)); //NOI18N - - // The user instance should be valid - if (null == user) { - // Throw NPE - throw new NullPointerException("user is null"); //NOI18N - } else if (user.getUserId() == null) { - // Throw NPE again - throw new NullPointerException("user.userId is null"); //NOI18N - } else if (user.getUserId() < 1) { - // Invalid id number - throw new IllegalArgumentException(MessageFormat.format("user.userId={0} is not valid", user.getUserId())); //NOI18N - } else if (!this.userBean.ifUserExists(user)) { - // User not found - throw new UserNotFoundException(user); - } else if (user.getUserConfirmKey() == null) { - // Throw NPE again - throw new NullPointerException("this.userConfirmKey is null"); //NOI18N - } else if (user.getUserAccountStatus() == UserAccountStatus.CONFIRMED) { - // User account status is not UNCONFIRMED - throw new UserStatusConfirmedException(user); - } else if (user.getUserAccountStatus() == UserAccountStatus.LOCKED) { - // User account status is not UNCONFIRMED - throw new UserStatusLockedException(user); - } else if (null == locale) { - // Locale should be set - throw new NullPointerException("locale is null"); //NOI18N - } - - // Get new registration key - String confirmationKey = this.registerBean.generateConfirmationKey(user); - - // Get managed instance - User managedUser = this.getEntityManager().find(LoginUser.class, user.getUserId()); - - // Set it in user - managedUser.setUserConfirmKey(confirmationKey); - - // Init variable - Address emailAddress; - - try { - // Create email address and set - emailAddress = new InternetAddress(managedUser.getUserContact().getContactEmailAddress()); - } catch (final AddressException ex) { - // Throw again - throw new EJBException(ex); - } - - // Send email - // TODO: Internationlize the subject line somehow - this.sendEmail("Resend confirmation link", "resend_confirmation_link", emailAddress, user, baseUrl); //NOI18N - - // Log trace message - this.getLoggerBeanLocal().logTrace(MessageFormat.format("{0}.resendConfirmationLink: EXIT!", this.getClass().getSimpleName())); //NOI18N - } - -} diff --git a/src/java/org/mxchange/pizzaapplication/model/basket/BasketSessionBean.java b/src/java/org/mxchange/pizzaapplication/model/basket/BasketSessionBean.java new file mode 100644 index 0000000..16b5ded --- /dev/null +++ b/src/java/org/mxchange/pizzaapplication/model/basket/BasketSessionBean.java @@ -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 . + */ +package org.mxchange.pizzaapplication.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 + *

+ * @author Roland Häder + */ +@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 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/pizzaapplication/model/category/AdminCategorySessionBean.java b/src/java/org/mxchange/pizzaapplication/model/category/AdminCategorySessionBean.java new file mode 100644 index 0000000..78c74a7 --- /dev/null +++ b/src/java/org/mxchange/pizzaapplication/model/category/AdminCategorySessionBean.java @@ -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 . + */ +package org.mxchange.pizzaapplication.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 + *

+ * @author Roland Häder + */ +@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. + *

+ * @param category Category instance + *

+ * @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/pizzaapplication/model/category/CategorySessionBean.java b/src/java/org/mxchange/pizzaapplication/model/category/CategorySessionBean.java new file mode 100644 index 0000000..4e150cf --- /dev/null +++ b/src/java/org/mxchange/pizzaapplication/model/category/CategorySessionBean.java @@ -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 . + */ +package org.mxchange.pizzaapplication.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 + *

+ * @author Roland Häder + */ +@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 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 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/pizzaapplication/model/checkout/CheckoutMessageBean.java b/src/java/org/mxchange/pizzaapplication/model/checkout/CheckoutMessageBean.java new file mode 100644 index 0000000..c0eb8d2 --- /dev/null +++ b/src/java/org/mxchange/pizzaapplication/model/checkout/CheckoutMessageBean.java @@ -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 . + */ +package org.mxchange.pizzaapplication.model.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 + *

+ * @author Roland Häder + */ +@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 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/pizzaapplication/model/customer/ShopCustomerSessionBean.java b/src/java/org/mxchange/pizzaapplication/model/customer/ShopCustomerSessionBean.java new file mode 100644 index 0000000..7a48714 --- /dev/null +++ b/src/java/org/mxchange/pizzaapplication/model/customer/ShopCustomerSessionBean.java @@ -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 . + */ +package org.mxchange.pizzaapplication.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 + *

+ * @author Roland Häder + */ +@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/pizzaapplication/model/product/AdminProductSessionBean.java b/src/java/org/mxchange/pizzaapplication/model/product/AdminProductSessionBean.java new file mode 100644 index 0000000..03fbfef --- /dev/null +++ b/src/java/org/mxchange/pizzaapplication/model/product/AdminProductSessionBean.java @@ -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 . + */ +package org.mxchange.pizzaapplication.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 + *

+ * @author Roland Häder + */ +@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 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 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. + *

+ * @param product Product instance + *

+ * @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/pizzaapplication/model/product/ProductSessionBean.java b/src/java/org/mxchange/pizzaapplication/model/product/ProductSessionBean.java new file mode 100644 index 0000000..1e7af80 --- /dev/null +++ b/src/java/org/mxchange/pizzaapplication/model/product/ProductSessionBean.java @@ -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 . + */ +package org.mxchange.pizzaapplication.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 + *

+ * @author Roland Häder + */ +@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 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 allProducts = this.productBean.getAllProducts(); + + // Trace message + this.getLoggerBeanLocal().logTrace(MessageFormat.format("getAvailableProducts: allProducts({0})={1}", allProducts.size(), allProducts)); //NOI18N + + // Init deque + List deque = new LinkedList<>(); + + // Get iterator + Iterator 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/pizzaapplication/model/receipt/PdfReceiptBean.java b/src/java/org/mxchange/pizzaapplication/model/receipt/PdfReceiptBean.java new file mode 100644 index 0000000..5ddfce2 --- /dev/null +++ b/src/java/org/mxchange/pizzaapplication/model/receipt/PdfReceiptBean.java @@ -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 . + */ +package org.mxchange.pizzaapplication.model.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 + *

+ * @author Roland Häder + */ +@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 + *

+ * @return PDF job + */ + private PDFJob getJob () { + return this.job; + } +} diff --git a/src/java/org/mxchange/pizzaapplication/model/receipt/PdfReceiptSessionBean.java b/src/java/org/mxchange/pizzaapplication/model/receipt/PdfReceiptSessionBean.java new file mode 100644 index 0000000..8590965 --- /dev/null +++ b/src/java/org/mxchange/pizzaapplication/model/receipt/PdfReceiptSessionBean.java @@ -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 . + */ +package org.mxchange.pizzaapplication.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. + *

+ * @author Roland Häder + */ +@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/pizzaapplication/model/receipt/ReceiptFactory.java b/src/java/org/mxchange/pizzaapplication/model/receipt/ReceiptFactory.java new file mode 100644 index 0000000..876f0a8 --- /dev/null +++ b/src/java/org/mxchange/pizzaapplication/model/receipt/ReceiptFactory.java @@ -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 . + */ +package org.mxchange.pizzaapplication.model.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 + *

+ * @author Roland Häder + */ +public class ReceiptFactory { + + /** + * Own job + */ + private final PDFJob job; + + /** + * Factory method + */ + public ReceiptFactory () { + this.job = new PDFJob(); + } + + /** + * Produces a PDF job instance + *

+ * @param caller Injection point + *

+ * @return PDF job + */ + @Produces + @Receipt + public PDFJob getJob (final InjectionPoint caller) { + return this.job; + } +} diff --git a/src/java/org/mxchange/pizzaapplication/model/resendlink/PizzaResendLinkSessionBean.java b/src/java/org/mxchange/pizzaapplication/model/resendlink/PizzaResendLinkSessionBean.java new file mode 100644 index 0000000..8893b38 --- /dev/null +++ b/src/java/org/mxchange/pizzaapplication/model/resendlink/PizzaResendLinkSessionBean.java @@ -0,0 +1,123 @@ +/* + * 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 . + */ +package org.mxchange.pizzaapplication.model.resendlink; + +import java.text.MessageFormat; +import java.util.Locale; +import javax.ejb.EJB; +import javax.ejb.EJBException; +import javax.ejb.Stateless; +import javax.mail.Address; +import javax.mail.internet.AddressException; +import javax.mail.internet.InternetAddress; +import org.mxchange.jusercore.exceptions.UserNotFoundException; +import org.mxchange.jusercore.exceptions.UserStatusConfirmedException; +import org.mxchange.jusercore.exceptions.UserStatusLockedException; +import org.mxchange.jusercore.model.register.UserRegistrationSessionBeanRemote; +import org.mxchange.jusercore.model.user.LoginUser; +import org.mxchange.jusercore.model.user.User; +import org.mxchange.jusercore.model.user.UserSessionBeanRemote; +import org.mxchange.jusercore.model.user.status.UserAccountStatus; +import org.mxchange.pizzaaplication.database.BasePizzaDatabaseBean; +import org.mxchange.pizzaapplication.beans.resendlink.ResendLinkSessionBeanRemote; + +/** + * A session-based EJB for resending confirmation links + *

+ * @author Roland Häder + */ +@Stateless (name = "resendLink", description = "A bean resending confirmation links") +public class PizzaResendLinkSessionBean extends BasePizzaDatabaseBean implements ResendLinkSessionBeanRemote { + + /** + * Serial number + */ + private static final long serialVersionUID = 71_546_726_857_195_360L; + + /** + * Registration bean + */ + @EJB + private UserRegistrationSessionBeanRemote registerBean; + + /** + * Regular user bean + */ + @EJB + private UserSessionBeanRemote userBean; + + @Override + public void resendConfirmationLink (final User user, final Locale locale, final String baseUrl) throws UserNotFoundException, UserStatusConfirmedException, UserStatusLockedException { + // Log trace message + this.getLoggerBeanLocal().logTrace(MessageFormat.format("{0}.resendConfirmationLink: user={1},locale={2},baseUrl={3} - CALLED!", this.getClass().getSimpleName(), user, locale, baseUrl)); //NOI18N + + // The user instance should be valid + if (null == user) { + // Throw NPE + throw new NullPointerException("user is null"); //NOI18N + } else if (user.getUserId() == null) { + // Throw NPE again + throw new NullPointerException("user.userId is null"); //NOI18N + } else if (user.getUserId() < 1) { + // Invalid id number + throw new IllegalArgumentException(MessageFormat.format("user.userId={0} is not valid", user.getUserId())); //NOI18N + } else if (!this.userBean.ifUserExists(user)) { + // User not found + throw new UserNotFoundException(user); + } else if (user.getUserConfirmKey() == null) { + // Throw NPE again + throw new NullPointerException("this.userConfirmKey is null"); //NOI18N + } else if (user.getUserAccountStatus() == UserAccountStatus.CONFIRMED) { + // User account status is not UNCONFIRMED + throw new UserStatusConfirmedException(user); + } else if (user.getUserAccountStatus() == UserAccountStatus.LOCKED) { + // User account status is not UNCONFIRMED + throw new UserStatusLockedException(user); + } else if (null == locale) { + // Locale should be set + throw new NullPointerException("locale is null"); //NOI18N + } + + // Get new registration key + String confirmationKey = this.registerBean.generateConfirmationKey(user); + + // Get managed instance + User managedUser = this.getEntityManager().find(LoginUser.class, user.getUserId()); + + // Set it in user + managedUser.setUserConfirmKey(confirmationKey); + + // Init variable + Address emailAddress; + + try { + // Create email address and set + emailAddress = new InternetAddress(managedUser.getUserContact().getContactEmailAddress()); + } catch (final AddressException ex) { + // Throw again + throw new EJBException(ex); + } + + // Send email + // TODO: Internationlize the subject line somehow + this.sendEmail("Resend confirmation link", "resend_confirmation_link", emailAddress, user, baseUrl); //NOI18N + + // Log trace message + this.getLoggerBeanLocal().logTrace(MessageFormat.format("{0}.resendConfirmationLink: EXIT!", this.getClass().getSimpleName())); //NOI18N + } + +} diff --git a/src/java/org/mxchange/pizzaservice/beans/checkout/CheckoutMessageBean.java b/src/java/org/mxchange/pizzaservice/beans/checkout/CheckoutMessageBean.java deleted file mode 100644 index 7d2b021..0000000 --- a/src/java/org/mxchange/pizzaservice/beans/checkout/CheckoutMessageBean.java +++ /dev/null @@ -1,206 +0,0 @@ -/* - * 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 . - */ -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 - *

- * @author Roland Häder - */ -@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 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 deleted file mode 100644 index 07f7148..0000000 --- a/src/java/org/mxchange/pizzaservice/model/basket/BasketSessionBean.java +++ /dev/null @@ -1,117 +0,0 @@ -/* - * 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 . - */ -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 - *

- * @author Roland Häder - */ -@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 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 deleted file mode 100644 index afce2c3..0000000 --- a/src/java/org/mxchange/pizzaservice/model/category/AdminCategorySessionBean.java +++ /dev/null @@ -1,130 +0,0 @@ -/* - * 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 . - */ -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 - *

- * @author Roland Häder - */ -@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. - *

- * @param category Category instance - *

- * @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 deleted file mode 100644 index 9f95f44..0000000 --- a/src/java/org/mxchange/pizzaservice/model/category/CategorySessionBean.java +++ /dev/null @@ -1,72 +0,0 @@ -/* - * 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 . - */ -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 - *

- * @author Roland Häder - */ -@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 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 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 deleted file mode 100644 index d0274fd..0000000 --- a/src/java/org/mxchange/pizzaservice/model/customer/ShopCustomerSessionBean.java +++ /dev/null @@ -1,151 +0,0 @@ -/* - * 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 . - */ -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 - *

- * @author Roland Häder - */ -@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 deleted file mode 100644 index ae0f909..0000000 --- a/src/java/org/mxchange/pizzaservice/model/product/AdminProductSessionBean.java +++ /dev/null @@ -1,163 +0,0 @@ -/* - * 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 . - */ -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 - *

- * @author Roland Häder - */ -@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 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 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. - *

- * @param product Product instance - *

- * @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 deleted file mode 100644 index d7d0eef..0000000 --- a/src/java/org/mxchange/pizzaservice/model/product/ProductSessionBean.java +++ /dev/null @@ -1,103 +0,0 @@ -/* - * 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 . - */ -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 - *

- * @author Roland Häder - */ -@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 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 allProducts = this.productBean.getAllProducts(); - - // Trace message - this.getLoggerBeanLocal().logTrace(MessageFormat.format("getAvailableProducts: allProducts({0})={1}", allProducts.size(), allProducts)); //NOI18N - - // Init deque - List deque = new LinkedList<>(); - - // Get iterator - Iterator 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 deleted file mode 100644 index 34267c4..0000000 --- a/src/java/org/mxchange/pizzaservice/model/receipt/PdfReceiptSessionBean.java +++ /dev/null @@ -1,136 +0,0 @@ -/* - * 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 . - */ -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. - *

- * @author Roland Häder - */ -@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 deleted file mode 100644 index 1650329..0000000 --- a/src/java/org/mxchange/pizzaservice/receipt/PdfReceiptBean.java +++ /dev/null @@ -1,56 +0,0 @@ -/* - * 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 . - */ -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 - *

- * @author Roland Häder - */ -@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 - *

- * @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 deleted file mode 100644 index 120a61d..0000000 --- a/src/java/org/mxchange/pizzaservice/receipt/ReceiptFactory.java +++ /dev/null @@ -1,55 +0,0 @@ -/* - * 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 . - */ -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 - *

- * @author Roland Häder - */ -public class ReceiptFactory { - - /** - * Own job - */ - private final PDFJob job; - - /** - * Factory method - */ - public ReceiptFactory () { - this.job = new PDFJob(); - } - - /** - * Produces a PDF job instance - *

- * @param caller Injection point - *

- * @return PDF job - */ - @Produces - @Receipt - public PDFJob getJob (final InjectionPoint caller) { - return this.job; - } -}