From f1fe01b9c668895ec8a95c4759c8f13bd645f6b4 Mon Sep 17 00:00:00 2001 From: Roland Haeder Date: Sat, 15 Aug 2015 12:25:32 +0200 Subject: [PATCH] =?utf8?q?Continued=20with=20project:=20-=20added=20showin?= =?utf8?q?g=20product's=20category=20in=20admin=20area=20-=20added=20metho?= =?utf8?q?d=20getPrintableProduktCategory()=20for=20this=20-=20fixed=20log?= =?utf8?q?ger=20XML=20file=20-=20added=20method=20getCategory()=20of=20giv?= =?utf8?q?en=20Product=20instance=20to=20category=20database=20frontend=20?= =?utf8?q?-=20added=20method=20isProductTitleUsed()=20to=20pre-check=20if?= =?utf8?q?=20the=20title=20has=20been=20used.=20This=20avoids=20an=20excep?= =?utf8?q?tion=20thrown=20in=20doAdminAddProduct()=20which=20expects=20tha?= =?utf8?q?t=20the=20product's=20title=20is=20not=20yet=20used.=20Signed-of?= =?utf8?q?f-by:Roland=20H=C3=A4der=20?= MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit --- src/java/log4j2.xml | 3 +- .../application/PizzaApplication.java | 18 ++++ .../application/PizzaServiceApplication.java | 83 ++++++++++++++++++- .../frontend/category/CategoryFrontend.java | 16 ++++ .../PizzaCategoryDatabaseFrontend.java | 69 ++++++++++++++- .../product/PizzaProductDatabaseFrontend.java | 8 +- .../pizzaapplication/product/BaseProduct.java | 4 +- web/admin/product.jsp | 11 ++- web/form_handler/admin/do_product.jsp | 13 ++- 9 files changed, 208 insertions(+), 17 deletions(-) diff --git a/src/java/log4j2.xml b/src/java/log4j2.xml index 8860f19e..1ebbd9fd 100644 --- a/src/java/log4j2.xml +++ b/src/java/log4j2.xml @@ -15,7 +15,7 @@ GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . --> - + @@ -23,7 +23,6 @@ along with this program. If not, see . - diff --git a/src/java/org/mxchange/pizzaapplication/application/PizzaApplication.java b/src/java/org/mxchange/pizzaapplication/application/PizzaApplication.java index dc0140bb..c1ebe252 100644 --- a/src/java/org/mxchange/pizzaapplication/application/PizzaApplication.java +++ b/src/java/org/mxchange/pizzaapplication/application/PizzaApplication.java @@ -233,6 +233,15 @@ public interface PizzaApplication extends Application { */ public String getPrintableProduktAvailability (final Product product); + /** + * Returns a printable (human-readable) string of product's category + * + * @param product Product instance to check + * @return Human-readable version of product availability + * @throws javax.servlet.ServletException If something unexpected happened + */ + public String getPrintableProduktCategory (final Product product) throws ServletException; + /** * Marks all choosen products as ordered * @@ -260,6 +269,15 @@ public interface PizzaApplication extends Application { */ public void doAdminAddProduct (final HttpServletRequest request) throws ServletException, ProductTitleAlreadyUsedException; + /** + * Checks if product's title is already used. + * + * @param request Request instance + * @return Whether the product's title has already been used + * @throws javax.servlet.ServletException If something unexpected happened + */ + public boolean isProductTitleUsed (final HttpServletRequest request) throws ServletException; + /** * Generates link HTML code for given category's parent id, if set. This * link then points to products.jsp?category_id=x diff --git a/src/java/org/mxchange/pizzaapplication/application/PizzaServiceApplication.java b/src/java/org/mxchange/pizzaapplication/application/PizzaServiceApplication.java index a9a89d2e..2c389deb 100644 --- a/src/java/org/mxchange/pizzaapplication/application/PizzaServiceApplication.java +++ b/src/java/org/mxchange/pizzaapplication/application/PizzaServiceApplication.java @@ -16,14 +16,16 @@ */ package org.mxchange.pizzaapplication.application; -import org.mxchange.pizzaapplication.exceptions.CategoryTitleAlreadyUsedException; import java.io.IOException; +import java.io.UnsupportedEncodingException; import java.lang.reflect.Field; import java.lang.reflect.InvocationTargetException; import java.sql.SQLException; import java.text.MessageFormat; import java.util.Iterator; import java.util.Map; +import java.util.logging.Level; +import java.util.logging.Logger; import javax.servlet.ServletContext; import javax.servlet.ServletException; import javax.servlet.http.HttpServletRequest; @@ -42,6 +44,7 @@ import org.mxchange.pizzaapplication.database.frontend.category.PizzaCategoryDat import org.mxchange.pizzaapplication.database.frontend.product.PizzaProductDatabaseFrontend; import org.mxchange.pizzaapplication.database.frontend.product.ProductFrontend; import org.mxchange.pizzaapplication.database.product.PizzaProductDatabaseConstants; +import org.mxchange.pizzaapplication.exceptions.CategoryTitleAlreadyUsedException; import org.mxchange.pizzaapplication.exceptions.ProductTitleAlreadyUsedException; import org.mxchange.pizzaapplication.product.Product; @@ -1401,4 +1404,82 @@ public class PizzaServiceApplication extends BasePizzaServiceSystem implements P // No parent set return "Keine"; } + + @Override + public String getPrintableProduktCategory (final Product product) throws ServletException { + // Trace message + this.getLogger().trace("product=" + product + " - CALLED!"); + + // product must not be null + if (product == null) { + // Abort here + throw new NullPointerException("product is null"); + } + + // Declare category + Category category; + + try { + // Get Category instance from product over the frontend + category = this.categoryFrontend.getCategory(product); + } catch (final IOException | SQLException | BadTokenException | CorruptedDatabaseFileException | NoSuchMethodException | IllegalAccessException | IllegalArgumentException | InvocationTargetException ex) { + throw new ServletException(ex); + } + + // Debug message + this.getLogger().debug("category=" + category); + + String title = null; + try { + // Now get title from it and return it + title = category.decodedTitle(); + } catch (final UnsupportedEncodingException ex) { + // Continue to throw as cause + throw new ServletException(ex); + } + + // Trace message + this.getLogger().trace("title=" + title + " - EXIT!"); + + // Return it + return title; + } + + @Override + public boolean isProductTitleUsed (final HttpServletRequest request) throws ServletException { + // Trace message + this.getLogger().trace("request=" + request + " - CALLED!"); + + // Init title + String title = request.getParameter(PizzaProductDatabaseConstants.COLUMN_TITLE); + + // request must not be null and "title" must be found and non-empty + if (request == null) { + // Abort here + throw new NullPointerException("request is null"); + } else if (title == null) { + // title is not set + throw new IllegalArgumentException(MessageFormat.format("{0} is not set.", PizzaProductDatabaseConstants.COLUMN_TITLE)); //NOI18N + } else if (title.isEmpty()) { + // Is left empty + throw new IllegalArgumentException(MessageFormat.format("{0} is empty.", PizzaProductDatabaseConstants.COLUMN_TITLE)); //NOI18N + } + + // Default is not used + boolean isUsed = false; + + try { + // So that all is tested, try to find the product + isUsed = this.isProductTitleUsed(title); + } catch (final IOException | SQLException | BadTokenException | CorruptedDatabaseFileException | NoSuchMethodException | IllegalAccessException | IllegalArgumentException | InvocationTargetException ex) { + // Continue to throw all as cause + throw new ServletException(ex); + } + + // Trace message + this.getLogger().trace("isUsed=" + isUsed + " - EXIT!"); + + // Return it + return isUsed; + } } diff --git a/src/java/org/mxchange/pizzaapplication/database/frontend/category/CategoryFrontend.java b/src/java/org/mxchange/pizzaapplication/database/frontend/category/CategoryFrontend.java index 39007b7c..29aa737c 100644 --- a/src/java/org/mxchange/pizzaapplication/database/frontend/category/CategoryFrontend.java +++ b/src/java/org/mxchange/pizzaapplication/database/frontend/category/CategoryFrontend.java @@ -24,6 +24,7 @@ import org.mxchange.jcore.database.frontend.DatabaseFrontend; import org.mxchange.jcore.exceptions.BadTokenException; import org.mxchange.jcore.exceptions.CorruptedDatabaseFileException; import org.mxchange.pizzaapplication.category.Category; +import org.mxchange.pizzaapplication.product.Product; /** * An interface for product database frontends @@ -70,4 +71,19 @@ public interface CategoryFrontend extends DatabaseFrontend { * @throws java.lang.reflect.InvocationTargetException Any other problems? */ public boolean isCategoryTitleUsed (final String title) throws IOException, SQLException, BadTokenException, CorruptedDatabaseFileException, NoSuchMethodException, IllegalAccessException, IllegalArgumentException, InvocationTargetException; + + /** + * Gets a Category instance for given Product instance. + * + * @param product Product instance + * @return A category instance + * @throws java.io.IOException If any IO error occurs + * @throws org.mxchange.jcore.exceptions.BadTokenException If a bad token was found in a file-based database backend's file ... ;-) + * @throws java.sql.SQLException If any SQL error occurs + * @throws org.mxchange.jcore.exceptions.CorruptedDatabaseFileException If the database file is damaged + * @throws java.lang.NoSuchMethodException If a method was not found + * @throws java.lang.IllegalAccessException If the method cannot be accessed + * @throws java.lang.reflect.InvocationTargetException Any other problems? + */ + public Category getCategory (final Product product) throws IOException, SQLException, BadTokenException, CorruptedDatabaseFileException, NoSuchMethodException, IllegalAccessException, IllegalArgumentException, InvocationTargetException; } diff --git a/src/java/org/mxchange/pizzaapplication/database/frontend/category/PizzaCategoryDatabaseFrontend.java b/src/java/org/mxchange/pizzaapplication/database/frontend/category/PizzaCategoryDatabaseFrontend.java index c87f7919..12e16b1d 100644 --- a/src/java/org/mxchange/pizzaapplication/database/frontend/category/PizzaCategoryDatabaseFrontend.java +++ b/src/java/org/mxchange/pizzaapplication/database/frontend/category/PizzaCategoryDatabaseFrontend.java @@ -24,7 +24,7 @@ import java.text.MessageFormat; import java.util.Iterator; import java.util.Map; import org.mxchange.jcore.criteria.searchable.SearchCriteria; -import org.mxchange.jcore.criteria.searchable.SearchableCritera; +import org.mxchange.jcore.criteria.searchable.SearchableCriteria; import org.mxchange.jcore.database.frontend.BaseDatabaseFrontend; import org.mxchange.jcore.database.result.DatabaseResult; import org.mxchange.jcore.database.result.Result; @@ -35,6 +35,7 @@ import org.mxchange.jcore.exceptions.UnsupportedDatabaseBackendException; import org.mxchange.pizzaapplication.category.Category; import org.mxchange.pizzaapplication.category.product.ProductCategory; import org.mxchange.pizzaapplication.database.category.PizzaCategoryDatabaseConstants; +import org.mxchange.pizzaapplication.product.Product; /** * Stores and retrieves Contact instances @@ -148,7 +149,7 @@ public class PizzaCategoryDatabaseFrontend extends BaseDatabaseFrontend implemen this.getLogger().trace("CALLED!"); //NOI18N // Instance search criteria - SearchableCritera critera = new SearchCriteria(); + SearchableCriteria critera = new SearchCriteria(); // Run the query Result result = this.getBackend().doSelectByCriteria(critera); @@ -223,7 +224,7 @@ public class PizzaCategoryDatabaseFrontend extends BaseDatabaseFrontend implemen this.getLogger().trace(MessageFormat.format("title={0} - CALLED!", title)); // Get search criteria - SearchableCritera criteria = new SearchCriteria(); + SearchableCriteria criteria = new SearchCriteria(); // Add criteria criteria.addCriteria(PizzaCategoryDatabaseConstants.COLUMN_TITLE, title); @@ -235,7 +236,7 @@ public class PizzaCategoryDatabaseFrontend extends BaseDatabaseFrontend implemen Result result = this.getBackend().doSelectByCriteria(criteria); // Debug log - this.getLogger().debug(MessageFormat.format("result({0}={1}", result, result.size())); + this.getLogger().debug(MessageFormat.format("result({0})={1}", result, result.size())); // Now check size of the result boolean isFound = (result.size() == 1); @@ -302,4 +303,64 @@ public class PizzaCategoryDatabaseFrontend extends BaseDatabaseFrontend implemen // Return column id return PizzaCategoryDatabaseConstants.COLUMN_ID; } + + @Override + public Category getCategory (final Product product) throws IOException, BadTokenException, CorruptedDatabaseFileException, SQLException, NoSuchMethodException, IllegalAccessException, IllegalArgumentException, InvocationTargetException { + // Trace message + this.getLogger().trace("product=" + product + " - CALLED!"); + + // product must not be null + if (product == null) { + // Abort here + throw new NullPointerException("product is null"); + } + + // Get category id from it + Long id = product.getCategory(); + + // Debug message + this.getLogger().debug("id=" + id); + + // It should be >0 here + assert(id > 0) : "id=" + id + " must be larger zero"; + + // Then construct a search instance + SearchableCriteria criteria = new SearchCriteria(); + + // Add id to it + criteria.addCriteria(PizzaCategoryDatabaseConstants.COLUMN_ID, id); + + // Only one entry is find + criteria.setLimit(1); + + // Run it on backend + Result result = this.getBackend().doSelectByCriteria(criteria); + + // Debug log + this.getLogger().debug(MessageFormat.format("result({0})={1}", result, result.size())); + + // Init category instance + Category category = null; + + // Is there one entry? + if (result.hasNext()) { + // Read result from it + Storeable storeable = result.next(); + + // Debug message + this.getLogger().debug("storeable=" + storeable); + + // Is it instance of Category? + if (storeable instanceof Category) { + // Then cast it + category = (Category) storeable; + } + } + + // Trace message + this.getLogger().trace("category=" + category + " - EXIT!"); + + // Return it + return category; + } } diff --git a/src/java/org/mxchange/pizzaapplication/database/frontend/product/PizzaProductDatabaseFrontend.java b/src/java/org/mxchange/pizzaapplication/database/frontend/product/PizzaProductDatabaseFrontend.java index 993d10a8..91d5a986 100644 --- a/src/java/org/mxchange/pizzaapplication/database/frontend/product/PizzaProductDatabaseFrontend.java +++ b/src/java/org/mxchange/pizzaapplication/database/frontend/product/PizzaProductDatabaseFrontend.java @@ -24,7 +24,7 @@ import java.text.MessageFormat; import java.util.Iterator; import java.util.Map; import org.mxchange.jcore.criteria.searchable.SearchCriteria; -import org.mxchange.jcore.criteria.searchable.SearchableCritera; +import org.mxchange.jcore.criteria.searchable.SearchableCriteria; import org.mxchange.jcore.database.frontend.BaseDatabaseFrontend; import org.mxchange.jcore.database.result.DatabaseResult; import org.mxchange.jcore.database.result.Result; @@ -113,7 +113,7 @@ public class PizzaProductDatabaseFrontend extends BaseDatabaseFrontend implement this.getLogger().trace("CALLED!"); //NOI18N // Instance search criteria - SearchableCritera critera = new SearchCriteria(); + SearchableCriteria critera = new SearchCriteria(); // Add criteria critera.addCriteria(PizzaProductDatabaseConstants.COLUMN_AVAILABLE, true); @@ -149,7 +149,7 @@ public class PizzaProductDatabaseFrontend extends BaseDatabaseFrontend implement this.getLogger().trace("CALLED!"); //NOI18N // Instance search criteria - SearchableCritera critera = new SearchCriteria(); + SearchableCriteria critera = new SearchCriteria(); // Run the query Result result = this.getBackend().doSelectByCriteria(critera); @@ -229,7 +229,7 @@ public class PizzaProductDatabaseFrontend extends BaseDatabaseFrontend implement this.getLogger().trace(MessageFormat.format("title={0} - CALLED!", title)); // Get search criteria - SearchableCritera criteria = new SearchCriteria(); + SearchableCriteria criteria = new SearchCriteria(); // Add criteria criteria.addCriteria(PizzaProductDatabaseConstants.COLUMN_TITLE, title); diff --git a/src/java/org/mxchange/pizzaapplication/product/BaseProduct.java b/src/java/org/mxchange/pizzaapplication/product/BaseProduct.java index 60f3623b..f3dbf3c4 100644 --- a/src/java/org/mxchange/pizzaapplication/product/BaseProduct.java +++ b/src/java/org/mxchange/pizzaapplication/product/BaseProduct.java @@ -159,11 +159,11 @@ public class BaseProduct extends BaseFrameworkSystem implements Product { return 0; } else if (this.getId() > product.getId()) { // This id is larger than compared to - return -1; + return 1; } // The other id is larger - return 1; + return -1; } @Override diff --git a/web/admin/product.jsp b/web/admin/product.jsp index 9f827724..b3da16e3 100644 --- a/web/admin/product.jsp +++ b/web/admin/product.jsp @@ -54,6 +54,9 @@ Einzelpreis: + + Kategorie: + Verfügbarkeit: @@ -64,7 +67,8 @@ - ${product.getId()} + ${product.getId()}: + ${product.getTitle()} @@ -72,13 +76,16 @@ ${product.getPrice()} + + ${app.getPrintableProduktCategory(product)} + ${app.getPrintableProduktAvailability(product)} - + diff --git a/web/form_handler/admin/do_product.jsp b/web/form_handler/admin/do_product.jsp index 679f21b2..87afa019 100644 --- a/web/form_handler/admin/do_product.jsp +++ b/web/form_handler/admin/do_product.jsp @@ -19,8 +19,17 @@ if ("POST".equals(request.getMethod())) { //NOI18N // Is "add/edit/delete" set? if (request.getParameter("add") != null) { //NOI18N - // Add new product - app.doAdminAddProduct(request); + // Is it already added? + if (app.isProductTitleUsed(request)) { + // Debug message + app.getLogger().debug("Already used, redirecting ..."); + + // Already added, so redirect here, else a ServletException will be thrown + response.sendRedirect(request.getContextPath() + "/admin/product.jsp?already=1"); + } else { + // Add new product + app.doAdminAddProduct(request); + } } else if (request.getParameter("edit") != null) { //NOI18N // @TODO } else if (request.getParameter("delete") != null) { //NOI18N -- 2.39.5