From e25614a295c91641c5bc209580075c147a6a2c29 Mon Sep 17 00:00:00 2001
From: =?utf8?q?Roland=20H=C3=A4der?= <roland@mxchange.org>
Date: Wed, 28 Sep 2022 19:10:11 +0200
Subject: [PATCH] Product-only: - introduced validator JSF tags for product and
 category - edit views must bypass duplicate i18n key check - ops, had to
 rename wrongly named template

---
 .../FinancialsGenericProductValidator.java    | 42 ++++++++++---------
 .../FinancialsProductCategoryValidator.java   | 26 +++++++++++-
 ....jsf.taglib.xml => product.jsf.taglib.xml} | 26 +++++++++++-
 .../admin_form_generic_product_data.tpl       |  4 +-
 ...l => admin_form_product_category_data.tpl} |  3 +-
 web/WEB-INF/web.xml                           |  2 +-
 .../admin_generic_product_delete.xhtml        |  1 -
 .../admin_generic_product_edit.xhtml          |  4 +-
 .../admin_generic_product_show.xhtml          |  1 -
 .../admin_product_category_edit.xhtml         |  4 +-
 .../admin_product_category_list.xhtml         |  2 +-
 11 files changed, 84 insertions(+), 31 deletions(-)
 rename web/WEB-INF/{product-links.jsf.taglib.xml => product.jsf.taglib.xml} (53%)
 rename web/WEB-INF/templates/admin/product_category/{admin_form_generic_product_data.tpl => admin_form_product_category_data.tpl} (93%)

diff --git a/src/java/org/mxchange/jfinancials/validator/generic_product/FinancialsGenericProductValidator.java b/src/java/org/mxchange/jfinancials/validator/generic_product/FinancialsGenericProductValidator.java
index 97126044..4a18fb55 100644
--- a/src/java/org/mxchange/jfinancials/validator/generic_product/FinancialsGenericProductValidator.java
+++ b/src/java/org/mxchange/jfinancials/validator/generic_product/FinancialsGenericProductValidator.java
@@ -46,6 +46,28 @@ public class FinancialsGenericProductValidator extends BaseStringValidator {
 	 */
 	private static final long serialVersionUID = 1_086_256_763_716_450L;
 
+	/**
+	 * Whether bypass duplicate i18n key check
+	 */
+	private Boolean bypassDuplicateI18nKey;
+
+	/**
+	 * Default constructor
+	 */
+	public FinancialsGenericProductValidator () {
+		// Set allowEmpty to FALSE by default
+		this.bypassDuplicateI18nKey = Boolean.FALSE;
+	}
+
+	/**
+	 * Setter for bypassDuplicateI18nKey flag
+	 * <p>
+	 * @param bypassDuplicateI18nKey Whether to bypass i18n key duplicate-check
+	 */
+	public void setBypassDuplicateI18nKey (final Boolean bypassDuplicateI18nKey) {
+		this.bypassDuplicateI18nKey = bypassDuplicateI18nKey;
+	}
+
 	@Override
 	public void validate (final FacesContext context, final UIComponent component, final Object productI18nKey) throws ValidatorException {
 		// The required field
@@ -60,26 +82,8 @@ public class FinancialsGenericProductValidator extends BaseStringValidator {
 			PRODUCT_LIST_CONTROLLER = CDI.current().select(FinancialsProductListWebViewBean.class).get();
 		}
 
-		// Don't allow duplicates by default
-		Boolean allowDuplicates = Boolean.FALSE;
-
-		// Is attribute "allowEmptyRequiredData" set?
-		if (component.getAttributes().containsKey("allowDuplicates")) { //NOI18N
-			// Get attribute
-			final Object attribute = component.getAttributes().get("allowDuplicates"); //NOI18N
-
-			// Make sure, it is Boolean as no String is accepted anymore
-			if (!(attribute instanceof String)) {
-				// Not valid attribute, please use "true" or "false" (default)
-				throw new IllegalArgumentException("allowDuplicates must be of type String. Please use \"true\" or \"false\" for f:attribute value."); //NOI18N
-			}
-
-			// Securely cast it
-			allowDuplicates = Boolean.parseBoolean((String) attribute);
-		}
-
 		// Check, if the name has already been used
-		if (!allowDuplicates && PRODUCT_LIST_CONTROLLER.isProductI18nKeyAdded((String) productI18nKey)) {
+		if (!this.bypassDuplicateI18nKey && PRODUCT_LIST_CONTROLLER.isProductI18nKeyAdded((String) productI18nKey)) {
 			// Create message
 			final String message = MessageFormat.format("I18n key {0} is already used. Please type an other.", productI18nKey);
 
diff --git a/src/java/org/mxchange/jfinancials/validator/product_category/FinancialsProductCategoryValidator.java b/src/java/org/mxchange/jfinancials/validator/product_category/FinancialsProductCategoryValidator.java
index d85edcde..307fbadb 100644
--- a/src/java/org/mxchange/jfinancials/validator/product_category/FinancialsProductCategoryValidator.java
+++ b/src/java/org/mxchange/jfinancials/validator/product_category/FinancialsProductCategoryValidator.java
@@ -33,7 +33,7 @@ import org.mxchange.jfinancials.beans.product_category.list.FinancialsCategoryLi
  * <p>
  * @author Roland Häder<roland@mxchange.org>
  */
-@FacesValidator(value = "ProductCategoryValidator")
+@FacesValidator (value = "ProductCategoryValidator")
 public class FinancialsProductCategoryValidator extends BaseStringValidator {
 
 	/**
@@ -46,6 +46,28 @@ public class FinancialsProductCategoryValidator extends BaseStringValidator {
 	 */
 	private static final long serialVersionUID = 1_086_256_763_716_450L;
 
+	/**
+	 * Whether bypass duplicate i18n key check
+	 */
+	private Boolean bypassDuplicateI18nKey;
+
+	/**
+	 * Default constructor
+	 */
+	public FinancialsProductCategoryValidator () {
+		// Set allowEmpty to FALSE by default
+		this.bypassDuplicateI18nKey = Boolean.FALSE;
+	}
+
+	/**
+	 * Setter for bypassDuplicateI18nKey flag
+	 * <p>
+	 * @param bypassDuplicateI18nKey Whether to bypass i18n key duplicate-check
+	 */
+	public void setBypassDuplicateI18nKey (final Boolean bypassDuplicateI18nKey) {
+		this.bypassDuplicateI18nKey = bypassDuplicateI18nKey;
+	}
+
 	@Override
 	public void validate (final FacesContext context, final UIComponent component, final Object categoryI18nKey) throws ValidatorException {
 		// The required field
@@ -61,7 +83,7 @@ public class FinancialsProductCategoryValidator extends BaseStringValidator {
 		}
 
 		// Check, if the name has already been used
-		if (CATEGORY_LIST_CONTROLLER.isCategoryI18nKeyAdded((String) categoryI18nKey)) {
+		if (!this.bypassDuplicateI18nKey && CATEGORY_LIST_CONTROLLER.isCategoryI18nKeyAdded((String) categoryI18nKey)) {
 			// Create message
 			final String message = MessageFormat.format("I18n key {0} is already used. Please type an other.", categoryI18nKey);
 
diff --git a/web/WEB-INF/product-links.jsf.taglib.xml b/web/WEB-INF/product.jsf.taglib.xml
similarity index 53%
rename from web/WEB-INF/product-links.jsf.taglib.xml
rename to web/WEB-INF/product.jsf.taglib.xml
index 56a8ae7c..7b36b252 100644
--- a/web/WEB-INF/product-links.jsf.taglib.xml
+++ b/web/WEB-INF/product.jsf.taglib.xml
@@ -21,5 +21,29 @@ along with this program.  If not, see <http://www.gnu.org/licenses/>.
 	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 	xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-facelettaglibrary_2_2.xsd"
 >
-	<namespace>http://mxchange.org/jsf/jproduct/links</namespace>
+	<namespace>http://mxchange.org/jsf/product/validators</namespace>
+	<tag>
+		<tag-name>genericProductValidator</tag-name>
+		<validator>
+			<validator-id>GenericProductValidator</validator-id>
+		</validator>
+		<attribute>
+			<description>Whether check for duplicate i18n keys is bypassed which makes only sense in "edit" views.</description>
+			<name>bypassDuplicateI18nKey</name>
+			<type>java.lang.Boolean</type>
+			<required>false</required>
+		</attribute>
+	</tag>
+	<tag>
+		<tag-name>productCategoryValidator</tag-name>
+		<validator>
+			<validator-id>ProductCategoryValidator</validator-id>
+		</validator>
+		<attribute>
+			<description>Whether check for duplicate i18n keys is bypassed which makes only sense in "edit" views.</description>
+			<name>bypassDuplicateI18nKey</name>
+			<type>java.lang.Boolean</type>
+			<required>false</required>
+		</attribute>
+	</tag>
 </facelet-taglib>
diff --git a/web/WEB-INF/templates/admin/generic_product/admin_form_generic_product_data.tpl b/web/WEB-INF/templates/admin/generic_product/admin_form_generic_product_data.tpl
index 07fc7bd8..503d4c61 100644
--- a/web/WEB-INF/templates/admin/generic_product/admin_form_generic_product_data.tpl
+++ b/web/WEB-INF/templates/admin/generic_product/admin_form_generic_product_data.tpl
@@ -4,6 +4,7 @@
 	xmlns:f="http://xmlns.jcp.org/jsf/core"
 	xmlns:ui="http://xmlns.jcp.org/jsf/facelets"
 	xmlns:p="http://primefaces.org/ui"
+	xmlns:validator="http://mxchange.org/jsf/product/validators"
 	>
 
 	<p:fieldset
@@ -54,8 +55,7 @@
 				title="#{product.ADMIN_ENTER_GENERIC_PRODUCT_I18N_KEY_TITLE}"
 				validatorMessage="#{product.ADMIN_ENTERED_PRODUCT_I18N_KEY_ALREADY_ADDED}"
 				>
-				<f:validator validatorId="GenericProductValidator" />
-				<f:attribute name="allowDuplicates" value="#{allowDuplicates}" />
+				<validator:genericProductValidator bypassDuplicateI18nKey="#{bypassDuplicateI18nKey}" />
 			</p:inputText>
 
 			<p:outputLabel for="productNumber" value="#{product.ADMIN_ENTER_GENERIC_PRODUCT_NUMBER}" />
diff --git a/web/WEB-INF/templates/admin/product_category/admin_form_generic_product_data.tpl b/web/WEB-INF/templates/admin/product_category/admin_form_product_category_data.tpl
similarity index 93%
rename from web/WEB-INF/templates/admin/product_category/admin_form_generic_product_data.tpl
rename to web/WEB-INF/templates/admin/product_category/admin_form_product_category_data.tpl
index b658e8eb..9ba4fdbf 100644
--- a/web/WEB-INF/templates/admin/product_category/admin_form_generic_product_data.tpl
+++ b/web/WEB-INF/templates/admin/product_category/admin_form_product_category_data.tpl
@@ -4,6 +4,7 @@
 	xmlns:f="http://xmlns.jcp.org/jsf/core"
 	xmlns:ui="http://xmlns.jcp.org/jsf/facelets"
 	xmlns:p="http://primefaces.org/ui"
+	xmlns:validator="http://mxchange.org/jsf/product/validators"
 	>
 
 	<p:fieldset legend="#{product.ADMIN_PRODUCT_CATEGORY_DATA_LEGEND}">
@@ -47,7 +48,7 @@
 				title="#{product.ADMIN_ENTER_CATEGORY_I18N_KEY_TITLE}"
 				validatorMessage="#{product.ADMIN_ENTERED_CATEGORY_I18N_KEY_ALREADY_ADDED}"
 				>
-				<f:validator validatorId="ProductCategoryValidator" />
+				<validator:genericProductValidator bypassDuplicateI18nKey="#{bypassDuplicateI18nKey}" />
 			</p:inputText>
 
 			<p:outputLabel for="categoryShownInStatistics" value="#{product.ADMIN_ENABLE_CATEGORY_IN_STATISTICS}" />
diff --git a/web/WEB-INF/web.xml b/web/WEB-INF/web.xml
index 07e266c5..f6bb5d2a 100644
--- a/web/WEB-INF/web.xml
+++ b/web/WEB-INF/web.xml
@@ -30,7 +30,7 @@
 	<context-param>
 		<description>Generic custom JSF tags library</description>
 		<param-name>javax.faces.FACELETS_LIBRARIES</param-name>
-		<param-value>/WEB-INF/widgets.jsf.taglib.xml;/WEB-INF/validators.jsf.taglib.xml;/WEB-INF/links.jsf.taglib.xml;/WEB-INF/project-links.jsf.taglib.xml;;/WEB-INF/product-links.jsf.taglib.xml</param-value>
+		<param-value>/WEB-INF/widgets.jsf.taglib.xml;/WEB-INF/validators.jsf.taglib.xml;/WEB-INF/links.jsf.taglib.xml;/WEB-INF/project-links.jsf.taglib.xml;;/WEB-INF/product.jsf.taglib.xml</param-value>
 	</context-param>
 	<context-param>
 		<description>Project stage</description>
diff --git a/web/admin/generic_product/admin_generic_product_delete.xhtml b/web/admin/generic_product/admin_generic_product_delete.xhtml
index 75837d77..a19da9e2 100644
--- a/web/admin/generic_product/admin_generic_product_delete.xhtml
+++ b/web/admin/generic_product/admin_generic_product_delete.xhtml
@@ -11,7 +11,6 @@
 	<ui:define name="metadata">
 		<f:metadata>
 			<f:viewParam
-				id="productId"
 				name="productId"
 				value="#{adminGenericProductActionController.currentProduct}"
 				converter="GenericProductConverter"
diff --git a/web/admin/generic_product/admin_generic_product_edit.xhtml b/web/admin/generic_product/admin_generic_product_edit.xhtml
index 0b01325c..90a562c2 100644
--- a/web/admin/generic_product/admin_generic_product_edit.xhtml
+++ b/web/admin/generic_product/admin_generic_product_edit.xhtml
@@ -57,7 +57,9 @@
 					<h:outputText value="#{product.ADMIN_EDIT_GENERIC_PRODUCT_MINIMUM_DATA}" />
 				</h:panelGroup>
 
-				<ui:include src="/WEB-INF/templates/admin/generic_product/admin_form_generic_product_data.tpl" />
+				<ui:include src="/WEB-INF/templates/admin/generic_product/admin_form_generic_product_data.tpl">
+					<ui:param name="bypassDuplicateI18nKey" value="true" />
+				</ui:include>
 
 				<f:facet name="footer">
 					<p:panelGrid columns="2" layout="grid">
diff --git a/web/admin/generic_product/admin_generic_product_show.xhtml b/web/admin/generic_product/admin_generic_product_show.xhtml
index 412f69bb..e0e8fc30 100644
--- a/web/admin/generic_product/admin_generic_product_show.xhtml
+++ b/web/admin/generic_product/admin_generic_product_show.xhtml
@@ -11,7 +11,6 @@
 	<ui:define name="metadata">
 		<f:metadata>
 			<f:viewParam
-				id="productId"
 				name="productId"
 				value="#{adminGenericProductActionController.currentProduct}"
 				converter="GenericProductConverter"
diff --git a/web/admin/product_category/admin_product_category_edit.xhtml b/web/admin/product_category/admin_product_category_edit.xhtml
index e7934c14..ceeaa0db 100644
--- a/web/admin/product_category/admin_product_category_edit.xhtml
+++ b/web/admin/product_category/admin_product_category_edit.xhtml
@@ -57,7 +57,9 @@
 					<h:outputText value="#{product.ADMIN_EDIT_PRODUCT_CATEGORY_MINIMUM_DATA}" />
 				</h:panelGroup>
 
-				<ui:include src="/WEB-INF/templates/admin/product_category/admin_form_generic_product_data.tpl" />
+				<ui:include src="/WEB-INF/templates/admin/product_category/admin_form_product_category_data.tpl">
+					<ui:param name="bypassDuplicateI18nKey" value="true" />
+				</ui:include>
 
 				<f:facet name="footer">
 					<p:panelGrid columns="2" layout="grid">
diff --git a/web/admin/product_category/admin_product_category_list.xhtml b/web/admin/product_category/admin_product_category_list.xhtml
index ccbcdcba..45905926 100644
--- a/web/admin/product_category/admin_product_category_list.xhtml
+++ b/web/admin/product_category/admin_product_category_list.xhtml
@@ -294,7 +294,7 @@
 					<h:outputText value="#{product.ADMIN_ADD_PRODUCT_CATEGORY_MINIMUM_DATA}" />
 				</h:panelGroup>
 
-				<ui:include src="/WEB-INF/templates/admin/product_category/admin_form_generic_product_data.tpl" />
+				<ui:include src="/WEB-INF/templates/admin/product_category/admin_form_product_category_data.tpl" />
 
 				<f:facet name="footer">
 					<p:panelGrid columns="2" layout="grid">
-- 
2.39.5