From 4934a0e2525cef9b91e06bc6a9961ab44aca4b22 Mon Sep 17 00:00:00 2001
From: =?utf8?q?Roland=20H=C3=A4der?= <roland@mxchange.org>
Date: Sat, 14 Oct 2017 21:02:33 +0200
Subject: [PATCH] Maybe cherry-pick: - added backing beans for product and
 category, administrative and general each
MIME-Version: 1.0
Content-Type: text/plain; charset=utf8
Content-Transfer-Encoding: 8bit

Signed-off-by: Roland Häder <roland@mxchange.org>
---
 .../FinancialAdminCategoryWebRequestBean.java | 153 +++++++++++++
 ...cialAdminCategoryWebRequestController.java |  28 +++
 .../FinancialCategoryWebRequestBean.java      | 146 +++++++++++++
 ...FinancialCategoryWebRequestController.java |  28 +++
 .../FinancialAdminProductWebRequestBean.java  | 204 ++++++++++++++++++
 ...ncialAdminProductWebRequestController.java |  28 +++
 .../FinancialProductWebRequestBean.java       | 148 +++++++++++++
 .../FinancialProductWebRequestController.java |  42 ++++
 8 files changed, 777 insertions(+)
 create mode 100644 src/java/org/mxchange/jfinancials/beans/category/FinancialAdminCategoryWebRequestBean.java
 create mode 100644 src/java/org/mxchange/jfinancials/beans/category/FinancialAdminCategoryWebRequestController.java
 create mode 100644 src/java/org/mxchange/jfinancials/beans/category/FinancialCategoryWebRequestBean.java
 create mode 100644 src/java/org/mxchange/jfinancials/beans/category/FinancialCategoryWebRequestController.java
 create mode 100644 src/java/org/mxchange/jfinancials/beans/product/FinancialAdminProductWebRequestBean.java
 create mode 100644 src/java/org/mxchange/jfinancials/beans/product/FinancialAdminProductWebRequestController.java
 create mode 100644 src/java/org/mxchange/jfinancials/beans/product/FinancialProductWebRequestBean.java
 create mode 100644 src/java/org/mxchange/jfinancials/beans/product/FinancialProductWebRequestController.java

diff --git a/src/java/org/mxchange/jfinancials/beans/category/FinancialAdminCategoryWebRequestBean.java b/src/java/org/mxchange/jfinancials/beans/category/FinancialAdminCategoryWebRequestBean.java
new file mode 100644
index 00000000..3725f670
--- /dev/null
+++ b/src/java/org/mxchange/jfinancials/beans/category/FinancialAdminCategoryWebRequestBean.java
@@ -0,0 +1,153 @@
+/*
+ * 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);
+	}
+
+}
diff --git a/src/java/org/mxchange/jfinancials/beans/category/FinancialAdminCategoryWebRequestController.java b/src/java/org/mxchange/jfinancials/beans/category/FinancialAdminCategoryWebRequestController.java
new file mode 100644
index 00000000..6a292c20
--- /dev/null
+++ b/src/java/org/mxchange/jfinancials/beans/category/FinancialAdminCategoryWebRequestController.java
@@ -0,0 +1,28 @@
+/*
+ * 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 {
+
+}
diff --git a/src/java/org/mxchange/jfinancials/beans/category/FinancialCategoryWebRequestBean.java b/src/java/org/mxchange/jfinancials/beans/category/FinancialCategoryWebRequestBean.java
new file mode 100644
index 00000000..bf1f9615
--- /dev/null
+++ b/src/java/org/mxchange/jfinancials/beans/category/FinancialCategoryWebRequestBean.java
@@ -0,0 +1,146 @@
+/*
+ * 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;
+				}
+			}
+			);
+		}
+	}
+
+}
diff --git a/src/java/org/mxchange/jfinancials/beans/category/FinancialCategoryWebRequestController.java b/src/java/org/mxchange/jfinancials/beans/category/FinancialCategoryWebRequestController.java
new file mode 100644
index 00000000..ac32de13
--- /dev/null
+++ b/src/java/org/mxchange/jfinancials/beans/category/FinancialCategoryWebRequestController.java
@@ -0,0 +1,28 @@
+/*
+ * 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 {
+
+}
diff --git a/src/java/org/mxchange/jfinancials/beans/product/FinancialAdminProductWebRequestBean.java b/src/java/org/mxchange/jfinancials/beans/product/FinancialAdminProductWebRequestBean.java
new file mode 100644
index 00000000..055aa89f
--- /dev/null
+++ b/src/java/org/mxchange/jfinancials/beans/product/FinancialAdminProductWebRequestBean.java
@@ -0,0 +1,204 @@
+/*
+ * 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);
+	}
+
+}
diff --git a/src/java/org/mxchange/jfinancials/beans/product/FinancialAdminProductWebRequestController.java b/src/java/org/mxchange/jfinancials/beans/product/FinancialAdminProductWebRequestController.java
new file mode 100644
index 00000000..768ed80d
--- /dev/null
+++ b/src/java/org/mxchange/jfinancials/beans/product/FinancialAdminProductWebRequestController.java
@@ -0,0 +1,28 @@
+/*
+ * 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 {
+
+}
diff --git a/src/java/org/mxchange/jfinancials/beans/product/FinancialProductWebRequestBean.java b/src/java/org/mxchange/jfinancials/beans/product/FinancialProductWebRequestBean.java
new file mode 100644
index 00000000..e3553dc0
--- /dev/null
+++ b/src/java/org/mxchange/jfinancials/beans/product/FinancialProductWebRequestBean.java
@@ -0,0 +1,148 @@
+/*
+ * 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;
+				}
+			}
+			);
+		}
+	}
+
+}
diff --git a/src/java/org/mxchange/jfinancials/beans/product/FinancialProductWebRequestController.java b/src/java/org/mxchange/jfinancials/beans/product/FinancialProductWebRequestController.java
new file mode 100644
index 00000000..7aff5301
--- /dev/null
+++ b/src/java/org/mxchange/jfinancials/beans/product/FinancialProductWebRequestController.java
@@ -0,0 +1,42 @@
+/*
+ * 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;
+
+}
-- 
2.39.5