--- /dev/null
+/*
+ * Copyright (C) 2016, 2017 Roland Häder
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+package org.mxchange.jfinancials.beans.category;
+
+import javax.ejb.EJB;
+import javax.enterprise.context.RequestScoped;
+import javax.enterprise.event.Event;
+import javax.enterprise.inject.Any;
+import javax.faces.view.facelets.FaceletException;
+import javax.inject.Inject;
+import javax.inject.Named;
+import org.mxchange.jfinancials.beans.BaseFinancialsBean;
+import org.mxchange.jproduct.events.category.AddedCategoryEvent;
+import org.mxchange.jproduct.events.category.CategoryAddedEvent;
+import org.mxchange.jproduct.exceptions.CannotAddCategoryException;
+import org.mxchange.jproduct.exceptions.CategoryTitleAlreadyUsedException;
+import org.mxchange.jproduct.model.category.AdminCategorySessionBeanRemote;
+import org.mxchange.jproduct.model.category.Category;
+import org.mxchange.jproduct.model.category.ProductCategory;
+
+/**
+ * Main application class
+ * <p>
+ * @author Roland Häder<roland@mxchange.org>
+ */
+@Named ("adminCategoryController")
+@RequestScoped
+public class FinancialAdminCategoryWebRequestBean extends BaseFinancialsBean implements FinancialAdminCategoryWebRequestController {
+
+ /**
+ * Serial number
+ */
+ private static final long serialVersionUID = 5_819_375_183_472_871L;
+
+ /**
+ * Event for added shop categories
+ */
+ @Inject
+ @Any
+ private Event<AddedCategoryEvent> categoryAddedEvent;
+
+ /**
+ * Remote bean for categories
+ */
+ @EJB(lookup = "java:global/jfinancials-ejb/adminCategory!org.mxchange.jproduct.model.category.AdminCategorySessionBeanRemote")
+ private AdminCategorySessionBeanRemote categoryBean;
+
+ /**
+ * Category categoryTitle
+ */
+ private String categoryTitle;
+
+ /**
+ * Parent category
+ */
+ private Category parentCategory;
+
+ /**
+ * Default constructor
+ */
+ public FinancialAdminCategoryWebRequestBean () {
+ // Call super constructor
+ super();
+ }
+
+ /**
+ * Adds given category data from request to database
+ * <p>
+ * @throws javax.faces.view.facelets.FaceletException If something
+ * unexpected happened
+ */
+ public void addCategory () throws FaceletException {
+ try {
+ // Create category
+ final Category category = new ProductCategory();
+
+ // Set fields
+ category.setParentCategory(this.getParentCategory());
+ category.setCategoryTitle(this.getCategoryTitle());
+
+ // Deligate to remote bean
+ final Category updatedCategory = this.categoryBean.doAdminAddCategory(category);
+
+ // Fire event
+ this.categoryAddedEvent.fire(new CategoryAddedEvent(updatedCategory));
+
+ // Unset all older values
+ this.clear();
+ } catch (final CategoryTitleAlreadyUsedException | CannotAddCategoryException ex) {
+ // Continue to throw
+ throw new FaceletException(ex);
+ }
+ }
+
+ /**
+ * Getter for category title
+ * <p>
+ * @return the title
+ */
+ public String getCategoryTitle () {
+ return this.categoryTitle;
+ }
+
+ /**
+ * Setter for category title
+ * <p>
+ * @param categoryTitle the title to set
+ */
+ public void setCategoryTitle (final String categoryTitle) {
+ this.categoryTitle = categoryTitle;
+ }
+
+ /**
+ * Getter for parent id
+ * <p>
+ * @return Parent id
+ */
+ public Category getParentCategory () {
+ return this.parentCategory;
+ }
+
+ /**
+ * Setter for parent category
+ * <p>
+ * @param parentCategory Parent category to set
+ */
+ public void setParentCategory (final Category parentCategory) {
+ this.parentCategory = parentCategory;
+ }
+
+ /**
+ * Clears this bean (example: when category has been added)
+ */
+ private void clear () {
+ this.setCategoryTitle(""); //NOI18N
+ this.setParentCategory(null);
+ }
+
+}
--- /dev/null
+/*
+ * Copyright (C) 2016, 2017 Roland Häder
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+package org.mxchange.jfinancials.beans.category;
+
+import java.io.Serializable;
+
+/**
+ * An interface for product controllers for "ADMIN" role
+ * <p>
+ * @author Roland Häder<roland@mxchange.org>
+ */
+public interface FinancialAdminCategoryWebRequestController extends Serializable {
+
+}
--- /dev/null
+/*
+ * Copyright (C) 2016, 2017 Roland Häder
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+package org.mxchange.jfinancials.beans.category;
+
+import fish.payara.cdi.jsr107.impl.NamedCache;
+import java.text.MessageFormat;
+import java.util.Comparator;
+import java.util.Iterator;
+import java.util.List;
+import javax.annotation.PostConstruct;
+import javax.cache.Cache;
+import javax.ejb.EJB;
+import javax.enterprise.context.RequestScoped;
+import javax.enterprise.event.Observes;
+import javax.inject.Inject;
+import javax.inject.Named;
+import org.mxchange.jfinancials.beans.BaseFinancialsBean;
+import org.mxchange.jproduct.events.category.AddedCategoryEvent;
+import org.mxchange.jproduct.model.category.Category;
+import org.mxchange.jproduct.model.category.CategorySessionBeanRemote;
+
+/**
+ * General (product) category controller
+ * <p>
+ * @author Roland Häder<roland@mxchange.org>
+ */
+@Named ("categoryController")
+@RequestScoped
+public class FinancialCategoryWebRequestBean extends BaseFinancialsBean implements FinancialCategoryWebRequestController {
+
+ /**
+ * Serial number
+ */
+ private static final long serialVersionUID = 58_137_539_530_279L;
+
+ /**
+ * List of all categories
+ */
+ private List<Category> allCategories;
+
+ /**
+ * EJB for general category stuff
+ */
+ @EJB (lookup = "java:global/jfinancials-ejb/category!org.mxchange.jproduct.model.category.CategorySessionBeanRemote")
+ private CategorySessionBeanRemote categoryBean;
+
+ /**
+ * Cache for all product categories
+ */
+ @Inject
+ @NamedCache (cacheName = "categoryCache")
+ private Cache<Long, Category> categoryCache;
+
+ /**
+ * Observes events fired after a new product category has been added
+ * <p>
+ * @param event Event to be observed
+ */
+ public void afterShopCategoryAdded (@Observes final AddedCategoryEvent event) {
+ // Is all valid?
+ if (null == event) {
+ // Throw NPE
+ throw new NullPointerException("event is null"); //NOI18N
+ } else if (event.getAddedCategory() == null) {
+ // Throw again ...
+ throw new NullPointerException("event.addedCategory is null"); //NOI18N
+ } else if (event.getAddedCategory().getCategoryId() == null) {
+ // And again ...
+ throw new NullPointerException("event.addedCategory.categoryId is null"); //NOI18N
+ } else if (event.getAddedCategory().getCategoryId() < 1) {
+ // Id is invalid
+ throw new IllegalArgumentException(MessageFormat.format("event.addedCategory.categoryId={0} is not valid.", event.getAddedCategory().getCategoryId())); //NOI18N
+ }
+
+ // Add the category
+ this.allCategories.add(event.getAddedCategory());
+ }
+
+ /**
+ * Getter for a list of all categories
+ * <p>
+ * @return All categories
+ */
+ @SuppressWarnings ("ReturnOfCollectionOrArrayField")
+ public List<Category> allCategories () {
+ // Return it
+ return this.allCategories;
+ }
+
+ /**
+ * Initialization of this bean
+ */
+ @PostConstruct
+ public void init () {
+ // Is cache there?
+ if (!this.categoryCache.iterator().hasNext()) {
+ // Get whole list
+ final List<Category> categories = this.categoryBean.allCategories();
+
+ // "Walk" through all entries and add to cache
+ for (final Category category : categories) {
+ // Add it by primary key
+ this.categoryCache.put(category.getCategoryId(), category);
+ }
+ }
+
+ // Is the list empty, but filled cache?
+ if (this.allCategories.isEmpty() && this.categoryCache.iterator().hasNext()) {
+ // Get iterator
+ final Iterator<Cache.Entry<Long, Category>> iterator = this.categoryCache.iterator();
+
+ // Build up list
+ while (iterator.hasNext()) {
+ // GEt next element
+ final Cache.Entry<Long, Category> next = iterator.next();
+
+ // Add to list
+ this.allCategories.add(next.getValue());
+ }
+
+ // Sort list
+ this.allCategories.sort(new Comparator<Category>() {
+ @Override
+ public int compare (final Category o1, final Category o2) {
+ return o1.getCategoryId() > o2.getCategoryId() ? 1 : o1.getCategoryId() < o2.getCategoryId() ? -1 : 0;
+ }
+ }
+ );
+ }
+ }
+
+}
--- /dev/null
+/*
+ * Copyright (C) 2016, 2017 Roland Häder
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+package org.mxchange.jfinancials.beans.category;
+
+import java.io.Serializable;
+
+/**
+ * An interface for (product) categories
+ * <p>
+ * @author Roland Häder<roland@mxchange.org>
+ */
+public interface FinancialCategoryWebRequestController extends Serializable {
+
+}
--- /dev/null
+/*
+ * Copyright (C) 2016, 2017 Roland Häder
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+package org.mxchange.jfinancials.beans.product;
+
+import javax.ejb.EJB;
+import javax.enterprise.context.RequestScoped;
+import javax.enterprise.event.Event;
+import javax.enterprise.inject.Any;
+import javax.faces.view.facelets.FaceletException;
+import javax.inject.Inject;
+import javax.inject.Named;
+import org.mxchange.jfinancials.beans.BaseFinancialsBean;
+import org.mxchange.jproduct.events.product.AddedProductEvent;
+import org.mxchange.jproduct.events.product.ProductAddedEvent;
+import org.mxchange.jproduct.exceptions.CannotAddProductException;
+import org.mxchange.jproduct.exceptions.ProductTitleAlreadyUsedException;
+import org.mxchange.jproduct.model.category.Category;
+import org.mxchange.jproduct.model.product.AdminProductSessionBeanRemote;
+import org.mxchange.jproduct.model.product.GenericProduct;
+import org.mxchange.jproduct.model.product.Product;
+
+/**
+ * Main application class
+ * <p>
+ * @author Roland Häder<roland@mxchange.org>
+ */
+@Named ("adminProductController")
+@RequestScoped
+public class FinancialAdminProductWebRequestBean extends BaseFinancialsBean implements FinancialAdminProductWebRequestController {
+
+ /**
+ * Serial number
+ */
+ private static final long serialVersionUID = 5_819_375_183_472_871L;
+
+ /**
+ * Event for added product
+ */
+ @Inject
+ @Any
+ private Event<AddedProductEvent> addedProductEvent;
+
+ /**
+ * Available
+ */
+ private Boolean productAvailability;
+
+ /**
+ * Category instance
+ */
+ private Category productCategory;
+
+ /**
+ * Property productPrice
+ */
+ private Float productPrice;
+
+ /**
+ * Remote bean for products
+ */
+ @EJB (lookup = "java:global/jfinancial-ejb/adminProduct!org.mxchange.jproduct.model.product.AdminProductSessionBeanRemote")
+ private AdminProductSessionBeanRemote productRemoteBean;
+
+ /**
+ * Property productTitle
+ */
+ private String productTitle;
+
+ /**
+ * Default constructor
+ */
+ public FinancialAdminProductWebRequestBean () {
+ // Call super constructor
+ super();
+ }
+
+ /**
+ * Adds given product data from request to database
+ * <p>
+ * @throws javax.faces.view.facelets.FaceletException If something
+ * unexpected happened
+ */
+ public void addProduct () throws FaceletException {
+ try {
+ // Create product instance
+ final Product product = new GenericProduct();
+
+ // Add all
+ product.setProductAvailability(this.getProductAvailability());
+ product.setProductCategory(this.getProductCategory());
+ product.setProductPrice(this.getProductPrice());
+ product.setProductTitle(this.getProductTitle());
+
+ // Call bean
+ final Product updatedProduct = this.productRemoteBean.doAdminAddProduct(product);
+
+ // Fire event
+ this.addedProductEvent.fire(new ProductAddedEvent(updatedProduct));
+
+ // Set all to null
+ this.clear();
+ } catch (final ProductTitleAlreadyUsedException | CannotAddProductException ex) {
+ // Continue to throw
+ throw new FaceletException(ex);
+ }
+ }
+
+ /**
+ * Getter for product's available property
+ * <p>
+ * @return Product's available property
+ */
+ public Boolean getProductAvailability () {
+ return this.productAvailability;
+ }
+
+ /**
+ * Setter for product's available property
+ * <p>
+ * @param productAvailability Product's available property
+ */
+ public void setProductAvailability (final Boolean productAvailability) {
+ this.productAvailability = productAvailability;
+ }
+
+ /**
+ * Getter for product's category
+ * <p>
+ * @return Product's category
+ */
+ public Category getProductCategory () {
+ return this.productCategory;
+ }
+
+ /**
+ * Setter for product's category instance
+ * <p>
+ * @param productCategory Product's category instance
+ */
+ public void setProductCategory (final Category productCategory) {
+ this.productCategory = productCategory;
+ }
+
+ /**
+ * Getter for product's price property
+ * <p>
+ * @return Product's price property
+ */
+ public Float getProductPrice () {
+ return this.productPrice;
+ }
+
+ /**
+ * Setter for product's price property
+ * <p>
+ * @param productPrice Product's price property
+ */
+ public void setProductPrice (final Float productPrice) {
+ this.productPrice = productPrice;
+ }
+
+ /**
+ * Getter for product's title property
+ * <p>
+ * @return Product's title
+ */
+ public String getProductTitle () {
+ return this.productTitle;
+ }
+
+ /**
+ * Setter for product's title property
+ * <p>
+ * @param productTitle Product's title
+ */
+ public void setProductTitle (final String productTitle) {
+ this.productTitle = productTitle;
+ }
+
+ /**
+ * Clears this bean (example: product has been added)
+ */
+ private void clear () {
+ this.setProductAvailability(Boolean.FALSE);
+ this.setProductCategory(null);
+ this.setProductPrice(null);
+ this.setProductTitle(null);
+ }
+
+}
--- /dev/null
+/*
+ * Copyright (C) 2016, 2017 Roland Häder
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+package org.mxchange.jfinancials.beans.product;
+
+import java.io.Serializable;
+
+/**
+ * An interface for product controllers for "ADMIN" role
+ * <p>
+ * @author Roland Häder<roland@mxchange.org>
+ */
+public interface FinancialAdminProductWebRequestController extends Serializable {
+
+}
--- /dev/null
+/*
+ * Copyright (C) 2016, 2017 Roland Häder
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+package org.mxchange.jfinancials.beans.product;
+
+import fish.payara.cdi.jsr107.impl.NamedCache;
+import java.text.MessageFormat;
+import java.util.Comparator;
+import java.util.Iterator;
+import java.util.List;
+import javax.annotation.PostConstruct;
+import javax.cache.Cache;
+import javax.ejb.EJB;
+import javax.enterprise.context.RequestScoped;
+import javax.enterprise.event.Observes;
+import javax.faces.FacesException;
+import javax.inject.Inject;
+import javax.inject.Named;
+import org.mxchange.jfinancials.beans.BaseFinancialsBean;
+import org.mxchange.jproduct.events.product.AddedProductEvent;
+import org.mxchange.jproduct.model.product.Product;
+import org.mxchange.jproduct.model.product.ProductSessionBeanRemote;
+
+/**
+ * General product controller
+ * <p>
+ * @author Roland Häder<roland@mxchange.org>
+ */
+@Named ("productController")
+@RequestScoped
+public class FinancialProductWebRequestBean extends BaseFinancialsBean implements FinancialProductWebRequestController {
+
+ /**
+ * Serial number
+ */
+ private static final long serialVersionUID = 58_137_539_530_279L;
+
+ /**
+ * List for all available products
+ */
+ private List<Product> allProducts;
+
+ /**
+ * EJB for general product purposes
+ */
+ @EJB (lookup = "java:global/jfinancials-ejb/product!org.mxchange.jproduct.model.product.ProductSessionBeanRemote")
+ private ProductSessionBeanRemote productBean;
+
+ /**
+ * Cached products
+ */
+ @Inject
+ @NamedCache (cacheName = "productCache")
+ private Cache<Long, Product> productCache;
+
+ /**
+ * Observes events fired after a new product has been added
+ * <p>
+ * @param event Event to be observed
+ * <p>
+ * @todo Move this to own controller
+ */
+ public void afterProductAdded (@Observes final AddedProductEvent event) {
+ // Is all valid?
+ if (null == event) {
+ // Throw NPE
+ throw new NullPointerException("event is null"); //NOI18N
+ } else if (event.getAddedProduct() == null) {
+ // Throw again ...
+ throw new NullPointerException("event.addedProduct is null"); //NOI18N
+ } else if (event.getAddedProduct().getProductId() == null) {
+ // And again ...
+ throw new NullPointerException("event.addedProduct.productId is null"); //NOI18N
+ } else if (event.getAddedProduct().getProductId() < 1) {
+ // Id is invalid
+ throw new IllegalArgumentException(MessageFormat.format("event.addedProduct.productId={0} is not valid.", event.getAddedProduct().getProductId())); //NOI18N
+ }
+
+ // Is the product available?
+ if (event.getAddedProduct().getProductAvailability()) {
+ // Add it
+ this.allProducts.add(event.getAddedProduct());
+ }
+ }
+
+ @Override
+ @SuppressWarnings ("ReturnOfCollectionOrArrayField")
+ public List<Product> allProducts () throws FacesException {
+ // Return it
+ return this.allProducts;
+ }
+
+ /**
+ * Initialization of this bean
+ */
+ @PostConstruct
+ public void init () {
+ // Is cache there?
+ if (!this.productCache.iterator().hasNext()) {
+ // Get whole list
+ final List<Product> products = this.productBean.allProducts();
+
+ // "Walk" through all entries and add to cache
+ for (final Product product : products) {
+ // Add it by primary key
+ this.productCache.put(product.getProductId(), product);
+ }
+ }
+
+ // Is the list empty, but filled cache?
+ if (this.allProducts.isEmpty() && this.productCache.iterator().hasNext()) {
+ // Get iterator
+ final Iterator<Cache.Entry<Long, Product>> iterator = this.productCache.iterator();
+
+ // Build up list
+ while (iterator.hasNext()) {
+ // GEt next element
+ final Cache.Entry<Long, Product> next = iterator.next();
+
+ // Add to list
+ this.allProducts.add(next.getValue());
+ }
+
+ // Sort list
+ this.allProducts.sort(new Comparator<Product>() {
+ @Override
+ public int compare (final Product o1, final Product o2) {
+ return o1.getProductId() > o2.getProductId() ? 1 : o1.getProductId() < o2.getProductId() ? -1 : 0;
+ }
+ }
+ );
+ }
+ }
+
+}
--- /dev/null
+/*
+ * Copyright (C) 2016, 2017 Roland Häder
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+package org.mxchange.jfinancials.beans.product;
+
+import java.io.Serializable;
+import java.util.List;
+import javax.ejb.Local;
+import javax.faces.view.facelets.FaceletException;
+import org.mxchange.jproduct.model.product.Product;
+
+/**
+ * An interface for products
+ * <p>
+ * @author Roland Häder<roland@mxchange.org>
+ */
+@Local
+public interface FinancialProductWebRequestController extends Serializable {
+
+ /**
+ * Some "getter" for a linked list of only available products
+ * <p>
+ * @return Only available products
+ * <p>
+ * @throws javax.faces.view.facelets.FaceletException If anything went wrong
+ */
+ List<Product> allProducts () throws FaceletException;
+
+}