X-Git-Url: https://git.mxchange.org/?a=blobdiff_plain;f=src%2Fjava%2Forg%2Fmxchange%2Fpizzaapplication%2Fapplication%2FPizzaServiceApplication.java;h=d8253814c2c7a000741ccc59f10bb1774ccbd29c;hb=ad3a217eb62ab36fab7004786b42e44edc063171;hp=27afd3217dac325d622534df9734b23db223e7f5;hpb=9527ce19be444ab3ea72e12d2362b64387473d69;p=pizzaservice-war.git diff --git a/src/java/org/mxchange/pizzaapplication/application/PizzaServiceApplication.java b/src/java/org/mxchange/pizzaapplication/application/PizzaServiceApplication.java index 27afd321..d8253814 100644 --- a/src/java/org/mxchange/pizzaapplication/application/PizzaServiceApplication.java +++ b/src/java/org/mxchange/pizzaapplication/application/PizzaServiceApplication.java @@ -16,24 +16,39 @@ */ package org.mxchange.pizzaapplication.application; +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.SortedMap; -import java.util.TreeMap; import javax.servlet.ServletContext; import javax.servlet.ServletException; import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpSession; import org.mxchange.jcore.contact.Gender; +import org.mxchange.jcore.exceptions.BadTokenException; +import org.mxchange.jcore.exceptions.CorruptedDatabaseFileException; +import org.mxchange.jcore.exceptions.UnsupportedDatabaseBackendException; import org.mxchange.pizzaapplication.BasePizzaServiceSystem; +import org.mxchange.pizzaapplication.category.Category; import org.mxchange.pizzaapplication.customer.Customer; import org.mxchange.pizzaapplication.customer.PizzaServiceCustomer; -import org.mxchange.pizzaapplication.product.PizzaProduct; +import org.mxchange.pizzaapplication.database.category.PizzaCategoryDatabaseConstants; +import org.mxchange.pizzaapplication.database.frontend.category.CategoryFrontend; +import org.mxchange.pizzaapplication.database.frontend.category.PizzaCategoryDatabaseFrontend; +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; /** + * Main application class * * @author Roland Haeder */ @@ -44,44 +59,60 @@ public class PizzaServiceApplication extends BasePizzaServiceSystem implements P public static final String MAIN_TITLE = "Pizza-Service"; /** - * Product list + * Frontend for products */ - private final SortedMap products; + private ProductFrontend productFrontend; + + /** + * Frontend for categories + */ + private CategoryFrontend categoryFrontend; /** * Some singleton getter for this instance. If the instance is not set in * given application, it will be created. * - * @param application Servlet context + * @param context Servlet context * @return This instance * @throws javax.servlet.ServletException If object is not set correctly */ - public static final PizzaApplication getInstance (final ServletContext application) throws ServletException { + public static final PizzaApplication getInstance (final ServletContext context) throws ServletException { // Check application instance - if (application == null) { + if (context == null) { // Not set throw new NullPointerException("application is null"); //NOI18N } - // Init instance - PizzaServiceApplication instance = null; + // Init instance + PizzaApplication instance = null; - // Get instance from servlet - Object object = application.getAttribute("service"); //NOI18N + // Get instance from servlet application (aka. "application scope") + Object object = context.getAttribute("app"); //NOI18N // Is it set? - if (object instanceof PizzaServiceApplication) { + if (object instanceof PizzaApplication) { // Instance is set, so casting should work - instance = (PizzaServiceApplication) object; + instance = (PizzaApplication) object; + + // Debug message + instance.getLogger().debug(MessageFormat.format("Using existing instance {0} ...", object)); //NOI18N } else if (object instanceof Object) { // Not correct instance - throw new ServletException("service is not set correctly"); //NOI18N + throw new ServletException("app is not set correctly"); //NOI18N } else { - // "service" is null, so initialize it - instance = new PizzaServiceApplication(); + try { + // "service" is null, so initialize it + instance = new PizzaServiceApplication(); + instance.init(context); + + // Debug message + instance.getLogger().debug(MessageFormat.format("Created new instance {0} ...", object)); //NOI18N + } catch (final UnsupportedDatabaseBackendException | SQLException | IOException | BadTokenException ex) { + throw new ServletException(ex); + } // And set it here - application.setAttribute("service", instance); //NOI18N + context.setAttribute("app", instance); //NOI18N } // Trace message @@ -92,267 +123,147 @@ public class PizzaServiceApplication extends BasePizzaServiceSystem implements P } /** - * Private constructor - */ - private PizzaServiceApplication () { - // Init products instance - this.products = new TreeMap<>(); - - // Init bundle - this.initBundle(); - - // Fill products list - this.fillProductsList(); - } - - @Override - public void doBootstrap () { - throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. - } - - @Override - public void doMainLoop () { - throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. - } - - @Override - public void doShutdown () { - throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. - } - - /** - * Getter for product (list) iterator - * - * @return An interator on all listed products - */ - @Override - public Iterator> getProductsIterator () { - assert(this.products instanceof SortedMap) : "this.products is not initialized"; //NOI18N - return this.products.entrySet().iterator(); - } - - /** - * Adds given product to list or throws an exception if name is already found + * For debugging purpose * - * @param name Internal name of product - * @param title Product's title - * @param price Price - */ - private void addProduct (final String name, final String title, final float price) { - // Trace message - this.getLogger().trace(MessageFormat.format("name={0},title={1},price={2} - CALLED!", name, title, price)); //NOI18N - - // Is the name already used? - if (this.isProductNameUsed(name)) { - // Something went wrong - throw new IllegalArgumentException(MessageFormat.format("product {0} is already used.", name)); //NOI18N - } - - // Instance product - Product product = new PizzaProduct(name, title, price); - - // Debug message - this.getLogger().debug(MessageFormat.format("Adding product={0} ...", product)); //NOI18N - - // Add it - this.products.put(product.getName(), product); - - // Trace message - this.getLogger().trace("EXIT!"); //NOI18N - } - - /** - * Clears given parameter for product in session - * - * @param product Product instance - * @param session Session instance - * @param parameter Parameter to clear + * @param args Arguments */ - private void clearSessionAttribute (final Product product, final HttpSession session, final String parameter) { - // Trace message - this.getLogger().trace(MessageFormat.format("produce={0},parameter={1},session={2} - CALLED!", product, parameter, session)); //NOI18N - - // Clear in session - this.getLogger().debug(MessageFormat.format("Clearing product={0},parameter={1} ...", product.getName(), parameter)); //NOI18N - this.setValueInSession(product, session, parameter, null); - - // Trace message - this.getLogger().trace("EXIT!"); //NOI18N + public static void main (String[] args) { + // Get instance and start it + new PizzaServiceApplication().start(); } - /** - * Fills products list - * @todo Very hard-coded stuff ... - */ - private void fillProductsList () { - // Trace message - this.getLogger().trace("CALLED!"); //NOI18N + @Override + public void init (final ServletContext context) throws UnsupportedDatabaseBackendException, SQLException, IOException, BadTokenException { + // Temporary initialize default bundle + // @TODO The JSF may have better internatialization support + this.initBundle(); - // Add products - this.addProduct("italia", "Pizza Italia", 5.50f); //NOI18N - this.addProduct("diablo", "Pizza Diablo", 7.80f); //NOI18N - this.addProduct("bolognese", "Spagetti Bolognese", 11.95f); //NOI18N + // Initialize properties from config + this.initProperties(context); - // Trace message - this.getLogger().trace("EXIT!"); //NOI18N + // Init database frontends + this.initDatabaseFrontends(); } /** - * Some getter for value from session - * - * @param product Product instance - * @param session Session instance - * @param attribute Attribute to get value from - * @return Value from session + * Default constructor */ - private Object getValueFromSession (final Product product, final HttpSession session, final String attribute) { - // Trace message - this.getLogger().trace(MessageFormat.format("product={0},session={1},attribute={2} - CALLED!", product, session, attribute)); //NOI18N - - // Init variable - Object value = this.getValueFromSession(session, String.format(HTTP_PARAM_MASK, product.getName(), attribute)); - - this.getLogger().debug(MessageFormat.format("product={0},attribute={1},value={2}", product.getName(), attribute, value)); //NOI18N - - // Trace message - this.getLogger().trace(MessageFormat.format("value={0} - EXIT!", value)); //NOI18N - - // Return it - return value; + private PizzaServiceApplication () { } /** - * Some getter for value from session + * Calculates total amount of all choosen products * + * @param request Request instance * @param session Session instance - * @param key Key to get value from - * @return Value from session + * @return Total amount of all choosen products */ - private Object getValueFromSession (final HttpSession session, final String key) { + @Override + public int calculateTotalAmount (final HttpServletRequest request, final HttpSession session) throws ServletException { // Trace message - this.getLogger().trace(MessageFormat.format("session={043},key={1} - CALLED!", session, key)); //NOI18N - - // Init value - Object value = null; + this.getLogger().trace(MessageFormat.format("request={0},session={1} - CALLED!", request, session)); //NOI18N - // Get it synchronized from session - synchronized (session) { - value = session.getAttribute(key); + // Is product and session set? + if (request == null) { + // Not set + throw new NullPointerException("request is null"); //NOI18N + } else if (session == null) { + // Not set + throw new NullPointerException("session is null"); //NOI18N } - // Trace message - this.getLogger().trace(MessageFormat.format("value={0} - EXIT!", value)); //NOI18N + // Init/declare total price and iterator + int totalAmount = 0; + Iterator iterator = this.getAvailableProducts(); - // Return it - return value; - } + // "Walk" over all products + while (iterator.hasNext()) { + // Get next product + Product product = iterator.next(); - /** - * Checks whether given product is already used - * - * @param name Name of product - * @return Whether the given product's name is already used - */ - private boolean isProductNameUsed (final String name) { - // Trace message - this.getLogger().trace(MessageFormat.format("name={0} - CALLED!", name)); //NOI18N + // Is this choosen? + if (this.isProductChoosen(product, request, session)) { + // Then add ordered amount + this.getLogger().debug(MessageFormat.format("Counting {0} ...", product.getId())); //NOI18N - // Is it found? - return this.products.containsKey(name); - } + // Getting amount + String amount = this.getAmountFromSession(product, session); - /** - * For debugging purpose - * - * @param args Arguments - */ - public static void main (String[] args) { - // Get instance and start it - new PizzaServiceApplication().start(); - } + // Add it up + this.getLogger().debug(MessageFormat.format("amount={0}", amount)); //NOI18N + totalAmount += Integer.valueOf(amount); + } + this.getLogger().debug(MessageFormat.format("product={0},totalAmount={1}", product.getId(), totalAmount)); //NOI18N + } - /** - * Checks if the product ordered? - * - * @param product - * @param session - * @return - */ - private boolean isProductOrdered (final Product product, final HttpSession session) { // Trace message - this.getLogger().trace(MessageFormat.format("product={0},session={1} - CALLED!", product, session)); //NOI18N - - // Get session - Object isOrdered = this.getValueFromSession(product, session, SESSION_ORDERED); - this.getLogger().debug(MessageFormat.format("product={0},isOrdered={1}", product.getName(), isOrdered)); //NOI18N + this.getLogger().trace(MessageFormat.format("totalAmount={0} - EXIT!", totalAmount)); //NOI18N - // Return result - return ("true".equals(isOrdered)); //NOI18N + // Return total price + return totalAmount; } /** - * Somewhat setter in session + * Calculates total price of all choosen products * - * @param product Product instance + * @param request Request instance * @param session Session instance - * @param keyPart Key part to include in final key - * @param value Value to set + * @return Total price of all choosen products */ - private void setValueInSession (final Product product, final HttpSession session, final String keyPart, final Object value) { + @Override + public float calculateTotalPrice (final HttpServletRequest request, final HttpSession session) throws ServletException { // Trace message - this.getLogger().trace(MessageFormat.format("product={0},session={1},keyPart={2},value={3} - CALLED!", product, session, keyPart, value)); //NOI18N + this.getLogger().trace(MessageFormat.format("request={0},session={1} - CALLED!", request, session)); //NOI18N - synchronized(session) { - // Set it synced - this.getLogger().debug(MessageFormat.format("setValueInSession: Setting value={0} for product={1},keyPart={2}", value, product.getName(), keyPart)); //NOI18N - session.setAttribute(String.format(HTTP_PARAM_MASK, product.getName(), keyPart), value); + // Is product and session set? + if (request == null) { + // Not set + throw new NullPointerException("request is null"); //NOI18N + } else if (session == null) { + // Not set + throw new NullPointerException("session is null"); //NOI18N } - // Trace message - this.getLogger().trace("EXIT!"); //NOI18N - } + // Init total price + float totalPrice = 0.00f; - /** - * Application starter - */ - private void start () { // Get iterator - Iterator> iterator = this.getProductsIterator(); + Iterator iterator = this.getAvailableProducts(); - // Run over it + // "Walk" over all products while (iterator.hasNext()) { - // Get product instance - Map.Entry entry = iterator.next(); - - // Get value - Product product = entry.getValue(); + // Get next product + Product product = iterator.next(); - // Output data - this.getLogger().debug(MessageFormat.format("Product {0}, {1}: {2}", product.getName(), product.getTitle(), product.getPrice())); //NOI18N + // Is this choosen? + if (this.isProductChoosen(product, request, session)) { + // Then add product's total price + this.getLogger().debug(MessageFormat.format("Calling getTotalPositionPriceFromRequestSession({0},request,session) ...", product.getId())); //NOI18N + totalPrice += this.getTotalPositionPriceFromRequestSession(product, request, session); + } + this.getLogger().debug(MessageFormat.format("product={0},totalPrice={1}", product.getId(), totalPrice)); //NOI18N } - // Generate fake Customer instance - Customer customer = new PizzaServiceCustomer(); + // Trace message + this.getLogger().trace(MessageFormat.format(" totalPrice={0} - EXIT!", totalPrice)); //NOI18N - /* - * Need a least a gender ... :( See, that is why I don't like default - * constructors, you can easily miss something important and bam! You - * get an NPE. The fix here is, to have construtors (or factories) which - * requires all required instances that needs to be set to get a - * consitent object back. - */ + // Return total price + return totalPrice; + } - // Gender is MALE now - customer.setGender(Gender.MALE); + @Override + public void doBootstrap () { + throw new UnsupportedOperationException("Not supported yet."); //NOI18N + } - // Get iterator on all its fields - Iterator> it = customer.iterator(); + @Override + public void doMainLoop () { + throw new UnsupportedOperationException("Not supported yet."); //NOI18N + } - // Output it - while (it.hasNext()) { - Map.Entry entry = it.next(); - this.getLogger().debug(MessageFormat.format("entry {0}={1}", entry.getKey(), entry.getValue())); - } + @Override + public void doShutdown () { + throw new UnsupportedOperationException("Not supported yet."); //NOI18N } /** @@ -395,6 +306,47 @@ public class PizzaServiceApplication extends BasePizzaServiceSystem implements P return (String) object; } + /** + * Some "getter" for HTML code 'checked="checked"' if the product is choosen + * + * @param product Product instance + * @param request Request instance + * @param session Session instance + * @return Whether the product is choosen + */ + @Override + public String getCheckedHtmlFromProduct (final Product product, final HttpServletRequest request, final HttpSession session) { + // Trace message + this.getLogger().trace(MessageFormat.format("product={0},request={1},session={2} - CALLED!", product, request, session)); //NOI18N + + // Is product and session set? + if (product == null) { + // Not set + throw new NullPointerException("product is null"); //NOI18N + } else if (request == null) { + // Not set + throw new NullPointerException("request is null"); //NOI18N + } else if (session == null) { + // Not set + throw new NullPointerException("session is null"); //NOI18N + } + + // First let's check if the product is choosen + if (this.isProductChoosen(product, request, session)) { + // Trace message + this.getLogger().trace("Returning checked=\"checked\" - EXIT!"); //NOI18N + + // Is choosen + return "checked=\"checked\""; //NOI18N + } else { + // Trace message + this.getLogger().trace("Returning empty string - EXIT!"); //NOI18N + + // Not choosen + return ""; //NOI18N + } + } + /** * Some "getter" for choose from session * @@ -407,7 +359,7 @@ public class PizzaServiceApplication extends BasePizzaServiceSystem implements P // Trace message this.getLogger().trace(MessageFormat.format("product={0},session={1} - CALLED!", product, session)); //NOI18N - // Is product and session set? + // Is product and session set? if (product == null) { // Not set throw new NullPointerException("product is null"); //NOI18N @@ -417,12 +369,12 @@ public class PizzaServiceApplication extends BasePizzaServiceSystem implements P } // Get attribute - Object object = this.getValueFromSession(product, session, HTTP_PARAM_CHOOSE); + Object object = this.getValueFromSession(product, session, HTTP_PARAM_ITEM_ID); // Is the object null? if (object == null) { // Not found - this.getLogger().debug(MessageFormat.format("Returning empty string for product={0} ...", product.getName())); //NOI18N + this.getLogger().debug(MessageFormat.format("Returning empty string for product={0} ...", product.getId())); //NOI18N return ""; //NOI18N } @@ -434,90 +386,19 @@ public class PizzaServiceApplication extends BasePizzaServiceSystem implements P } /** - * Handler for amount from request or session - * - * @param product Product instance - * @param request Request instance - * @param session Session instance - * @return Amount as string - */ - @Override - public String handleAmountFromRequestSession (final Product product, final HttpServletRequest request, final HttpSession session) { - // Trace message - this.getLogger().trace(MessageFormat.format("product={0},request={1},session={2} - CALLED!", product, request, session)); //NOI18N - - // Is product and session set? - if (product == null) { - // Not set - throw new NullPointerException("product is null"); //NOI18N - } else if (request == null) { - // Not set - throw new NullPointerException("request is null"); //NOI18N - } else if (session == null) { - // Not set - throw new NullPointerException("session is null"); //NOI18N - } - - // Init variabke - Object object; - - // Check request method - if (!"POST".equals(request.getMethod())) { //NOI18N - // Not POST, so get from session - return this.getAmountFromSession(product, session); - } else if (this.handleChooseFromRequestSession(product, request, session).isEmpty()) { - // Not choosen - this.clearSessionAttribute(product, session, HTTP_PARAM_AMOUNT); - this.getLogger().debug(MessageFormat.format("Unsetting for product={0} in session, returning zero ...", product.getName())); //NOI18N - return "0"; //NOI18N - } - - // Get attribute from request - object = request.getParameter(String.format(HTTP_PARAM_MASK, HTTP_PARAM_AMOUNT, product.getName())); - - // Is it set? - if (object instanceof String) { - // Try to parse it to integer - try { - Integer value = Integer.valueOf((String) object); - } catch (final NumberFormatException ex) { - // Not valid input - this.getLogger().warn(ex); - return "0"; //NOI18N - } - - // Then set it in session - this.setValueInSession(product, session, HTTP_PARAM_AMOUNT, object); - - // And return it - return (String) object; - } - - // Trace message - this.getLogger().trace("Calling getAmountFromSession() ..."); //NOI18N - - // Get attribute from session - return this.getAmountFromSession(product, session); - } - - /** - * Handler for choosen (checkbox) from request or session + * Some "getter" for HTML code 'disabled="disabled"' for e.g. submit buttons * - * @param product Product instance * @param request Request instance * @param session Session instance - * @return Amount as string + * @return Whether the product is choosen */ @Override - public String handleChooseFromRequestSession (final Product product, final HttpServletRequest request, final HttpSession session) { + public String getDisabledHtmlFromSession (final HttpServletRequest request, final HttpSession session) throws ServletException { // Trace message - this.getLogger().trace(MessageFormat.format("product={0},request={1},session={2} - CALLED!", product, request, session)); //NOI18N + this.getLogger().trace(MessageFormat.format("request={0},session={1} - CALLED!", request, session)); //NOI18N // Is product and session set? - if (product == null) { - // Not set - throw new NullPointerException("product is null"); //NOI18N - } else if (request == null) { + if (request == null) { // Not set throw new NullPointerException("request is null"); //NOI18N } else if (session == null) { @@ -525,39 +406,26 @@ public class PizzaServiceApplication extends BasePizzaServiceSystem implements P throw new NullPointerException("session is null"); //NOI18N } - // Init variabke - Object object; - - // Check request method - if (!"POST".equals(request.getMethod())) { //NOI18N - // Not POST, so get from session - return this.getChooseFromSession(product, session); - } else if (this.isProductOrdered(product, session)) { - // Product is ordered - return this.getChooseFromSession(product, session); - } + // Get "enabled" from request scope + Boolean enabled = Boolean.parseBoolean((String) request.getAttribute("enabled")); //NOI18N - // Get reqzest element - object = request.getParameter(String.format(HTTP_PARAM_MASK, HTTP_PARAM_CHOOSE, product.getName())); - this.getLogger().debug(MessageFormat.format("product={0},object={1}", product.getName(), object)); //NOI18N + // Debug message + this.getLogger().debug(MessageFormat.format("enabled={0}", enabled)); //NOI18N - // Is it null? - if (object == null) { - // Unset session - this.getLogger().debug(MessageFormat.format("Unsetting session for product={0} ...", product.getName())); //NOI18N - this.clearSessionAttribute(product, session, HTTP_PARAM_CHOOSE); - this.clearSessionAttribute(product, session, HTTP_PARAM_AMOUNT); + // Is something selected? + if ((enabled) || (this.calculateTotalAmount(request, session) > 0)) { + // Trace message + this.getLogger().trace("Returning empty string - EXIT!"); //NOI18N - // Return empty string + // Something has been choosen return ""; //NOI18N - } - - // Then set it in session - this.setValueInSession(product, session, HTTP_PARAM_CHOOSE, object); + } else { + // Trace message + this.getLogger().trace("Returning disabled=\"disabled\" - EXIT!"); //NOI18N - // Cast to string and return it - this.getLogger().debug(MessageFormat.format("product={0} - Returning {1} ...", product.getName(), object)); //NOI18N - return (String) object; + // Nothing choosen yet + return "disabled=\"disabled\""; //NOI18N + } } /** @@ -586,8 +454,9 @@ public class PizzaServiceApplication extends BasePizzaServiceSystem implements P } // Get element + this.getLogger().debug(MessageFormat.format("Calling handleChooseFromRequestSession({0},{1},{2}) ...", product.getId(), request, session)); //NOI18N String choosen = this.handleChooseFromRequestSession(product, request, session); - this.getLogger().debug(MessageFormat.format("product={0},choosen={1}", product.getName(), choosen)); //NOI18N + this.getLogger().debug(MessageFormat.format("product={0},choosen={1}", product.getId(), choosen)); //NOI18N // Must not be null assert(choosen instanceof String): "choosen is null"; //NOI18N @@ -600,7 +469,7 @@ public class PizzaServiceApplication extends BasePizzaServiceSystem implements P // Get amount String amount = this.handleAmountFromRequestSession(product, request, session); - this.getLogger().debug(MessageFormat.format("product={0},amount={1}", product.getName(), amount)); //NOI18N + this.getLogger().debug(MessageFormat.format("product={0},amount={1}", product.getId(), amount)); //NOI18N // Must not be null assert(amount instanceof String): "amount is null"; //NOI18N @@ -615,6 +484,113 @@ public class PizzaServiceApplication extends BasePizzaServiceSystem implements P } } + /** + * Checks if given Product instance is available and returns a printable + * (human-readable) string. + * + * @param product Product instance to check + * @return Human-readable version of product availability + */ + @Override + public String getPrintableProduktAvailability (final Product product) { + // Trace message + this.getLogger().trace(MessageFormat.format("product={0} - CALLED!", product)); //NOI18N + + // Is it null? + if (product == null) { + // Should not be null + throw new NullPointerException("product is null"); //NOI18N + } + + // Get availability + if (product.getAvailable() == true) { + // Is available + return "Ja"; + } else { + // Not, not for public + return "Nein"; + } + } + + /** + * Some getter for printable value from session or an empty string for null. + * + * @param session Session instance + * @param key Key to get + * @return Value from key, empty string for null + */ + @Override + public Object getPrintableValeFromSession (final HttpSession session, final String key) { + // Trace message + this.getLogger().trace(MessageFormat.format("session={0},key={1} - CALLED", session, key)); //NOI18N + + // Are both parameter not null? + if (session == null) { + // Abort here + throw new NullPointerException("session is null"); //NOI18N + } else if (key == null) { + // Abort here + throw new NullPointerException("key is null"); //NOI18N + } + + // Now get it + Object value = this.getValueFromSession(session, key); + + // Debug message + this.getLogger().debug(MessageFormat.format("value={0}", value)); //NOI18N + + // Trace message + this.getLogger().trace(MessageFormat.format("Calling this.convertNullToEmpty({0}) ... - EXIT!", value)); //NOI18N + + // Return actual value + return this.convertNullToEmpty(value); + } + + /** + * Some "getter" for a an array of only available products + * + * @return All products + */ + @Override + public Iterator getAvailableProducts () throws ServletException { + try { + // Ask frontend for a list of products + return this.productFrontend.getAvailableProducts(); + } catch (final IOException | BadTokenException | SQLException | CorruptedDatabaseFileException | NoSuchMethodException | IllegalAccessException | InvocationTargetException ex) { + throw new ServletException(ex); + } + } + + /** + * Some "getter" for a an array of all products + * + * @return All products + */ + @Override + public Iterator getAllProducts () throws ServletException { + try { + // Ask frontend for a list of products + return this.productFrontend.getAllProducts(); + } catch (final IOException | BadTokenException | SQLException | CorruptedDatabaseFileException | NoSuchMethodException | IllegalAccessException | InvocationTargetException ex) { + throw new ServletException(ex); + } + } + + /** + * Some "getter" for a an array of all categories + * + * @return All categories + */ + @Override + public Iterator getCategories () throws ServletException { + try { + // Ask frontend for a list of categories + return this.categoryFrontend.getCategories(); + } catch (final IOException | BadTokenException | SQLException | CorruptedDatabaseFileException | NoSuchMethodException | IllegalAccessException | InvocationTargetException ex) { + throw new ServletException(ex); + } + } + /** * Some "getter" for total price of position from request or session. * Single price and amount is multiplyed. @@ -642,8 +618,9 @@ public class PizzaServiceApplication extends BasePizzaServiceSystem implements P } // Get choosen + this.getLogger().debug(MessageFormat.format("Calling handleChooseFromRequestSession({0},{1},{2}) ...", product.getId(), request, session)); //NOI18N String choosen = this.handleChooseFromRequestSession(product, request, session); - this.getLogger().debug(MessageFormat.format("product={0},choosen={1}", product.getName(), choosen)); //NOI18N + this.getLogger().debug(MessageFormat.format("product={0},choosen={1}", product.getId(), choosen)); //NOI18N // Must not be null assert(choosen instanceof String): "choosen is null"; //NOI18N @@ -651,13 +628,13 @@ public class PizzaServiceApplication extends BasePizzaServiceSystem implements P // Is it set? if (choosen.isEmpty()) { // Is empty - this.getLogger().debug(MessageFormat.format("product={0},choosen={1} - returning zero ...", product.getName(), choosen)); //NOI18N + this.getLogger().debug(MessageFormat.format("product={0},choosen={1} - returning zero ...", product.getId(), choosen)); //NOI18N return 0.00f; } // Get amount String amount = this.handleAmountFromRequestSession(product, request, session); - this.getLogger().debug(MessageFormat.format("product={0},amount={1}", product.getName(), amount)); //NOI18N + this.getLogger().debug(MessageFormat.format("product={0},amount={1}", product.getId(), amount)); //NOI18N // Must not be null assert(amount instanceof String): "amount is null"; //NOI18N @@ -665,7 +642,7 @@ public class PizzaServiceApplication extends BasePizzaServiceSystem implements P // Is it empty? if (amount.isEmpty() || "0".equals(amount)) { //NOI18N // Is empty - this.getLogger().debug(MessageFormat.format("product={0},amount={1} - returning zero ...", product.getName(), amount)); //NOI18N + this.getLogger().debug(MessageFormat.format("product={0},amount={1} - returning zero ...", product.getId(), amount)); //NOI18N return 0.00f; } @@ -685,12 +662,79 @@ public class PizzaServiceApplication extends BasePizzaServiceSystem implements P float price = (product.getPrice() * value); // Trace message - this.getLogger().trace(MessageFormat.format("product={0},price={1} - EXIT!", product.getName(), price)); //NOI18N + this.getLogger().trace(MessageFormat.format("product={0},price={1} - EXIT!", product.getId(), price)); //NOI18N // Then multiply it with price return price; } + /** + * Handler for amount from request or session + * + * @param product Product instance + * @param request Request instance + * @param session Session instance + * @return Amount as string + */ + @Override + public String handleAmountFromRequestSession (final Product product, final HttpServletRequest request, final HttpSession session) { + // Trace message + this.getLogger().trace(MessageFormat.format("product={0},request={1},session={2} - CALLED!", product, request, session)); //NOI18N + + // Is product and session set? + if (product == null) { + // Not set + throw new NullPointerException("product is null"); //NOI18N + } else if (request == null) { + // Not set + throw new NullPointerException("request is null"); //NOI18N + } else if (session == null) { + // Not set + throw new NullPointerException("session is null"); //NOI18N + } + + // Init variabke + Object object; + + // Check request method + if (!"POST".equals(request.getMethod())) { //NOI18N + // Not POST, so get from session + return this.getAmountFromSession(product, session); + } else if (this.handleChooseFromRequestSession(product, request, session).isEmpty()) { + // Not choosen + this.clearSessionAttribute(product, session, HTTP_PARAM_AMOUNT); + this.getLogger().debug(MessageFormat.format("Unsetting for product={0} in session, returning zero ...", product.getId())); //NOI18N + return "0"; //NOI18N + } + + // Get attribute from request + object = request.getParameter(String.format(HTTP_PARAM_MASK, HTTP_PARAM_AMOUNT, product.getId())); + + // Is it set? + if (object instanceof String) { + // Try to parse it to integer + try { + Integer value = Integer.valueOf((String) object); + } catch (final NumberFormatException ex) { + // Not valid input + this.getLogger().warn(ex); + return "0"; //NOI18N + } + + // Then set it in session + this.setValueInSession(product, session, HTTP_PARAM_AMOUNT, object); + + // And return it + return (String) object; + } + + // Trace message + this.getLogger().trace("Calling getAmountFromSession() ..."); //NOI18N + + // Get attribute from session + return this.getAmountFromSession(product, session); + } + /** * Checks whether the given product is choosen, request overules session. * @@ -717,8 +761,9 @@ public class PizzaServiceApplication extends BasePizzaServiceSystem implements P } // Get choosen + this.getLogger().debug(MessageFormat.format("Calling handleChooseFromRequestSession({0},{1},{2}) ...", product.getId(), request, session)); //NOI18N String choosen = this.handleChooseFromRequestSession(product, request, session); - this.getLogger().debug(MessageFormat.format("product={0},choosen={1}", product.getName(), choosen)); //NOI18N + this.getLogger().debug(MessageFormat.format("product={0},choosen={1}", product.getId(), choosen)); //NOI18N // Must not be null assert(choosen instanceof String): "choosen is null"; //NOI18N @@ -743,199 +788,151 @@ public class PizzaServiceApplication extends BasePizzaServiceSystem implements P } /** - * Calculates total price of all choosen products + * Marks all choosen products as ordered * * @param request Request instance * @param session Session instance - * @return Total price of all choosen products */ @Override - public float calculateTotalPrice (final HttpServletRequest request, final HttpSession session) { + public void markAllChoosenProductsAsOrdered (final HttpServletRequest request, final HttpSession session) throws ServletException { // Trace message this.getLogger().trace(MessageFormat.format("request={0},session={1} - CALLED!", request, session)); //NOI18N - // Is product and session set? - if (request == null) { - // Not set - throw new NullPointerException("request is null"); //NOI18N - } else if (session == null) { - // Not set - throw new NullPointerException("session is null"); //NOI18N - } + // Init iterator + Iterator iterator = this.getAvailableProducts(); - // Init total price - float totalPrice = 0.00f; - - // Get iterator - Iterator> iterator = this.getProductsIterator(); - - // Walk through all products + // "Walk" over all products while (iterator.hasNext()) { - // Get entry - Map.Entry entry = iterator.next(); + // Get next product + Product product = iterator.next(); - // Get product instance - Product product = entry.getValue(); + // Debug message + this.getLogger().debug(MessageFormat.format("product={0}", product)); //NOI18N - // Is this choosen? - if (product.isChoosen()) { - // Then add product's total price - this.getLogger().debug(MessageFormat.format("Calling getTotalPositionPriceFromRequestSession({0},request,session) ...", product.getName())); //NOI18N - totalPrice += this.getTotalPositionPriceFromRequestSession(product, request, session); + // Is it choosen? + if (this.isProductChoosen(product, request, session)) { + // Mark product as ordered + this.markProductAsOrdered(product, session); } - this.getLogger().debug(MessageFormat.format("product={0},totalPrice={1}", product.getName(), totalPrice)); //NOI18N } // Trace message - this.getLogger().trace(MessageFormat.format(" totalPrice={0} - EXIT!", totalPrice)); //NOI18N - - // Return total price - return totalPrice; + this.getLogger().trace("EXIT!"); //NOI18N } /** - * Calculates total amount of all choosen products + * Marks given product as choosen in session * - * @param request Request instance + * @param product Product to mark as ordered * @param session Session instance - * @return Total amount of all choosen products */ @Override - public int calculateTotalAmount (final HttpServletRequest request, final HttpSession session) { + public void markProductAsChoosen (final Product product, final HttpSession session) { // Trace message - this.getLogger().trace(MessageFormat.format("request={0},session={1} - CALLED!", request, session)); //NOI18N + this.getLogger().trace(MessageFormat.format("product={0},session={1} - CALLED!", product, session)); //NOI18N // Is product and session set? - if (request == null) { + if (product == null) { // Not set - throw new NullPointerException("request is null"); //NOI18N + throw new NullPointerException("product is null"); //NOI18N } else if (session == null) { // Not set throw new NullPointerException("session is null"); //NOI18N } - // Init total price - int totalAmount = 0; - - // Get iterator - Iterator> iterator = this.getProductsIterator(); - - // Walk through all products - while (iterator.hasNext()) { - // Get entry - Map.Entry entry = iterator.next(); - - // Get product instance - Product product = entry.getValue(); - - // Is this choosen? - if (product.isChoosen()) { - // Then add ordered amount - this.getLogger().debug(MessageFormat.format("Counting {0} ...", product.getName())); //NOI18N - - // Getting amount - String amount = this.getAmountFromSession(product, session); - - // Add it up - this.getLogger().debug(MessageFormat.format("amount={0}", amount)); //NOI18N - totalAmount += Integer.valueOf(amount); - } - this.getLogger().debug(MessageFormat.format("product={0},totalAmount={1}", product.getName(), totalAmount)); //NOI18N - } + // Mark it as ordered by setting flag + this.getLogger().debug(MessageFormat.format("Marking product={0} as choosen.", product.getId())); //NOI18N + this.setValueInSession(product, session, HTTP_PARAM_ITEM_ID, "1"); //NOI18N // Trace message - this.getLogger().trace(MessageFormat.format("totalAmount={0} - EXIT!", totalAmount)); //NOI18N - - // Return total price - return totalAmount; + this.getLogger().trace("EXIT!"); //NOI18N } /** - * Some "getter" for HTML code 'checked="checked"' if the product is choosen + * Marks given product as ordered in session * - * @param product Product instance - * @param request Request instance + * @param product Product to mark as ordered * @param session Session instance - * @return Whether the product is choosen */ @Override - public String getCheckedHtmlFromProduct (final Product product, final HttpServletRequest request, final HttpSession session) { + public void markProductAsOrdered (final Product product, final HttpSession session) { // Trace message - this.getLogger().trace(MessageFormat.format("product={0},request={1},session={2} - CALLED!", product, request, session)); //NOI18N + this.getLogger().trace(MessageFormat.format("product={0},session={1} - CALLED!", product, session)); //NOI18N // Is product and session set? if (product == null) { // Not set throw new NullPointerException("product is null"); //NOI18N - } else if (request == null) { - // Not set - throw new NullPointerException("request is null"); //NOI18N } else if (session == null) { // Not set throw new NullPointerException("session is null"); //NOI18N } - // First let's check if the product is choosen - if (this.isProductChoosen(product, request, session)) { - // Trace message - this.getLogger().trace("Returning checked=\"checked\" - EXIT!"); //NOI18N + // Mark it as ordered by setting flag + this.getLogger().debug(MessageFormat.format("Marking product={0} as ordered.", product.getId())); //NOI18N + this.setValueInSession(product, session, SESSION_ORDERED, "true"); //NOI18N - // Is choosen - return "checked=\"checked\""; //NOI18N - } else { - // Trace message - this.getLogger().trace("Returning empty string - EXIT!"); //NOI18N + // Trace message + this.getLogger().trace("EXIT!"); //NOI18N + } - // Not choosen - return ""; //NOI18N + /** + * Somewhat setter in session + * + * @param session Session instance + * @param key Session key to set + * @param value Value to set + */ + @Override + public void setValueInSession (final HttpSession session, final String key, final Object value) { + // Trace message + this.getLogger().trace(MessageFormat.format("session={0},key={1},value={2} - CALLED!", session, key, value)); //NOI18N + + synchronized(session) { + // Set it synced + session.setAttribute(key, value); } + + // Trace message + this.getLogger().trace("EXIT!"); //NOI18N } /** - * Some "getter" for HTML code 'disabled="disabled"' for e.g. submit buttons + * Unmarks given product as choosen in session * - * @param request Request instance + * @param product Product to unmark as choosen * @param session Session instance - * @return Whether the product is choosen */ @Override - public String getDisabledHtmlFromSession (final HttpServletRequest request, final HttpSession session) { + public void unmarkProductAsChoosen (final Product product, final HttpSession session) { // Trace message - this.getLogger().trace(MessageFormat.format("request={0},session={1} - CALLED!", request, session)); //NOI18N + this.getLogger().trace(MessageFormat.format("product={0},session={1} - CALLED!", product, session)); //NOI18N // Is product and session set? - if (request == null) { + if (product == null) { // Not set - throw new NullPointerException("request is null"); //NOI18N + throw new NullPointerException("product is null"); //NOI18N } else if (session == null) { // Not set throw new NullPointerException("session is null"); //NOI18N } - // Is something selected? - if (this.calculateTotalAmount(request, session) > 0) { - // Trace message - this.getLogger().trace("Returning empty string - EXIT!"); //NOI18N - - // Something has been choosen - return ""; //NOI18N - } else { - // Trace message - this.getLogger().trace("Returning disabled=\"disabled\" - EXIT!"); //NOI18N + // Mark it as ordered by setting flag + this.getLogger().debug(MessageFormat.format("Unmarking product={0} as choosen.", product.getId())); //NOI18N + this.clearSessionAttribute(product, session, HTTP_PARAM_ITEM_ID); - // Nothing choosen yet - return "disabled=\"disabled\""; //NOI18N - } + // Trace message + this.getLogger().trace("EXIT!"); //NOI18N } /** - * Marks given product as ordered in session + * Unmarks given product as ordered in session * - * @param product Product to mark as ordered + * @param product Product to unmark as ordered * @param session Session instance */ @Override - public void markProductAsOrdered(final Product product, final HttpSession session) { + public void unmarkProductAsOrdered (final Product product, final HttpSession session) { // Trace message this.getLogger().trace(MessageFormat.format("product={0},session={1} - CALLED!", product, session)); //NOI18N @@ -949,72 +946,709 @@ public class PizzaServiceApplication extends BasePizzaServiceSystem implements P } // Mark it as ordered by setting flag - this.getLogger().debug(MessageFormat.format("Marking product={0} as ordered.", product.getName())); //NOI18N - this.setValueInSession(product, session, SESSION_ORDERED, "true"); //NOI18N + this.getLogger().debug(MessageFormat.format("Unmarking product={0} as ordered.", product.getId())); //NOI18N + this.clearSessionAttribute(product, session, SESSION_ORDERED); // Trace message this.getLogger().trace("EXIT!"); //NOI18N } /** - * Unmarks given product as ordered in session + * Clears given parameter for product in session * - * @param product Product to unmark as ordered + * @param product Product instance * @param session Session instance + * @param parameter Parameter to clear */ - @Override - public void unmarkProductAsOrdered(final Product product, final HttpSession session) { + private void clearSessionAttribute (final Product product, final HttpSession session, final String parameter) { // Trace message - this.getLogger().trace(MessageFormat.format("product={0},session={1} - CALLED!", product, session)); //NOI18N + this.getLogger().trace(MessageFormat.format("produce={0},parameter={1},session={2} - CALLED!", product, parameter, session)); //NOI18N + + // Clear in session + this.getLogger().debug(MessageFormat.format("Clearing product={0},parameter={1} ...", product.getId(), parameter)); //NOI18N + this.setValueInSession(product, session, parameter, null); + + // Trace message + this.getLogger().trace("EXIT!"); //NOI18N + } + + /** + * Some getter for value from session + * + * @param product Product instance + * @param session Session instance + * @param attribute Attribute to get value from + * @return Value from session + */ + private Object getValueFromSession (final Product product, final HttpSession session, final String attribute) { + // Trace message + this.getLogger().trace(MessageFormat.format("product={0},session={1},attribute={2} - CALLED!", product, session, attribute)); //NOI18N + + // Init variable + Object value = this.getValueFromSession(session, String.format(HTTP_PARAM_MASK, attribute, product.getId())); + + this.getLogger().debug(MessageFormat.format("product={0},attribute={1},value={2}", product.getId(), attribute, value)); //NOI18N + + // Trace message + this.getLogger().trace(MessageFormat.format("value={0} - EXIT!", value)); //NOI18N + + // Return it + return value; + } + + /** + * Some getter for value from session + * + * @param session Session instance + * @param key Key to get value from + * @return Value from session + */ + private Object getValueFromSession (final HttpSession session, final String key) { + // Trace message + this.getLogger().trace(MessageFormat.format("session={0},key={1} - CALLED!", session, key)); //NOI18N + + // Init value + Object value; + + // Get it synchronized from session + synchronized (session) { + value = session.getAttribute(key); + } + + // Trace message + this.getLogger().trace(MessageFormat.format("value={0} - EXIT!", value)); //NOI18N + + // Return it + return value; + } + + /** + * Handler for choosen (checkbox) from request or session + * + * @param product Product instance + * @param request Request instance + * @param session Session instance + * @return Amount as string + */ + private String handleChooseFromRequestSession (final Product product, final HttpServletRequest request, final HttpSession session) { + // Trace message + this.getLogger().trace(MessageFormat.format("product={0},request={1},session={2} - CALLED!", product, request, session)); //NOI18N // Is product and session set? if (product == null) { // Not set throw new NullPointerException("product is null"); //NOI18N + } else if (request == null) { + // Not set + throw new NullPointerException("request is null"); //NOI18N } else if (session == null) { // Not set throw new NullPointerException("session is null"); //NOI18N } - // Mark it as ordered by setting flag - this.getLogger().debug(MessageFormat.format("Unmarking product={0} as ordered.", product.getName())); //NOI18N - this.clearSessionAttribute(product, session, SESSION_ORDERED); + // Init variabke + Object object; + + // Check request method + if (!"POST".equals(request.getMethod())) { //NOI18N + // Not POST, so get from session + this.getLogger().trace(MessageFormat.format("Calling this.getChooseFromSession({0},{1}) ... - EXIT!", product.getId(), session)); //NOI18N + return this.getChooseFromSession(product, session); + } else if (this.isProductOrdered(product, session)) { + // Product is ordered + this.getLogger().trace(MessageFormat.format("Calling this.getChooseFromSession({0},{1}) ... - EXIT!", product.getId(), session)); //NOI18N + return this.getChooseFromSession(product, session); + } else if (!this.getChooseFromSession(product, session).isEmpty()) { + // Found in session + this.getLogger().trace(MessageFormat.format("Calling this.getChooseFromSession({0},{1}) ... - EXIT!", product.getId(), session)); //NOI18N + return this.getChooseFromSession(product, session); + } + + // Get reqzest element + object = request.getParameter(String.format(HTTP_PARAM_MASK, HTTP_PARAM_ITEM_ID, product.getId())); + this.getLogger().debug(MessageFormat.format("product={0},object={1}", product.getId(), object)); //NOI18N + // Is it null? + if (object == null) { + // Unset session + this.getLogger().debug(MessageFormat.format("Unsetting session for product={0} ...", product.getId())); //NOI18N + this.clearSessionAttribute(product, session, HTTP_PARAM_ITEM_ID); + this.clearSessionAttribute(product, session, HTTP_PARAM_AMOUNT); + + // Return empty string + return ""; //NOI18N + } + + // Then set it in session + this.setValueInSession(product, session, HTTP_PARAM_ITEM_ID, object); + + // Cast to string and return it + this.getLogger().debug(MessageFormat.format("product={0} - Returning {1} ...", product.getId(), object)); //NOI18N + return (String) object; + } + + /** + * Initializes database frontends. + */ + private void initDatabaseFrontends () throws UnsupportedDatabaseBackendException, SQLException { + // Product frontend + this.productFrontend = new PizzaProductDatabaseFrontend(); + + // Category frontend + this.categoryFrontend = new PizzaCategoryDatabaseFrontend(); + } + + /** + * Checks whether given category title is already used + * + * @param title Title of category to check + * @return Whether it has been found + */ + private boolean isCategoryTitleUsed(final String title) throws IOException, SQLException, BadTokenException, CorruptedDatabaseFileException, NoSuchMethodException, IllegalAccessException, IllegalArgumentException, InvocationTargetException { + // Delegate to frontend + return this.categoryFrontend.isCategoryTitleUsed(title); + } + + /** + * Checks if given product title is already used + * @param title Product title to check + * @return Whether the product title has already been used + */ + private boolean isProductTitleUsed (final String title) throws IOException, SQLException, BadTokenException, CorruptedDatabaseFileException, NoSuchMethodException, IllegalAccessException, IllegalArgumentException, InvocationTargetException { + // Delegate to frontend + return this.productFrontend.isProductTitleUsed(title); + } + + /** + * Checks if the product ordered? + * + * @param product Product instance + * @param session HttpSession instance + * @return Whether the product has been ordered + */ + private boolean isProductOrdered (final Product product, final HttpSession session) { // Trace message - this.getLogger().trace("EXIT!"); //NOI18N + this.getLogger().trace(MessageFormat.format("product={0},session={1} - CALLED!", product, session)); //NOI18N + + // Get session + Object isOrdered = this.getValueFromSession(product, session, SESSION_ORDERED); + this.getLogger().debug(MessageFormat.format("product={0},isOrdered={1}", product.getId(), isOrdered)); //NOI18N + + // Return result + return ("true".equals(isOrdered)); //NOI18N } /** - * Some getter for printable value from session or an empty string for null. + * Somewhat setter in session * + * @param product Product instance * @param session Session instance - * @param key Key to get - * @return Value from key, empty string for null + * @param keyPart Key part to include in final key + * @param value Value to set */ - @Override - public Object getPrintableValeFromSession (final HttpSession session, final String key) { + private void setValueInSession (final Product product, final HttpSession session, final String keyPart, final Object value) { // Trace message - this.getLogger().trace(MessageFormat.format("session={0},key={1} - CALLED", session, key)); + this.getLogger().trace(MessageFormat.format("product={0},session={1},keyPart={2},value={3} - CALLED!", product, session, keyPart, value)); //NOI18N - // Are both parameter not null? - if (session == null) { + // Set it synced + this.getLogger().debug(MessageFormat.format("Setting value={0} for product={1},keyPart={2}", value, product.getId(), keyPart)); //NOI18N + this.setValueInSession(session, String.format(HTTP_PARAM_MASK, keyPart, product.getId()), value); + + // Trace message + this.getLogger().trace("EXIT!"); //NOI18N + } + + /** + * Application starter + */ + private void start() { + // Init bundle + this.initBundle(); + + try { + // Init properties + this.initProperties(); + + // And frontends + this.initDatabaseFrontends(); + } catch (final IOException | UnsupportedDatabaseBackendException | SQLException ex) { // Abort here - throw new NullPointerException("session is null"); - } else if (key == null) { + this.abortProgramWithException(ex); + } + + // Init instance + Iterator iterator = null; + + try { + // Get iterator + iterator = this.getAvailableProducts(); + } catch (final ServletException ex) { + this.abortProgramWithException(ex); + } + + // "Walk" over all products + while ((iterator instanceof Iterator) && (iterator.hasNext())) { + // Get next product + Product product = iterator.next(); + + // Output data + this.getLogger().debug(MessageFormat.format("Product {0}, {1}: {2}", product.getId(), product.getTitle(), product.getPrice())); //NOI18N + } + + // Generate fake Customer instance + Customer customer = new PizzaServiceCustomer(); + + /* + * Need a least a gender ... :( See, that is why I don't like default + * constructors, you can easily miss something important and bam! You + * get an NPE. The fix here is, to have construtors (or factories) which + * requires all required instances that needs to be set to get a + * consitent object back. + */ + + // Gender is MALE now + customer.setGender(Gender.MALE); + + // Init iterator + Iterator> it = null; + + try { + // Get iterator on all its fields + it = customer.iterator(); + } catch (final NoSuchMethodException | IllegalAccessException | InvocationTargetException ex) { + this.abortProgramWithException(ex); + } + + // Output it + while ((it instanceof Iterator) && (it.hasNext())) { + Map.Entry entry = it.next(); + this.getLogger().debug(MessageFormat.format("entry {0}={1}", entry.getKey(), entry.getValue())); //NOI18N + } + } + + /** + * Adds given category data from request to database + * + * @param request Request instance + */ + @Override + public void doAdminAddCategory (final HttpServletRequest request) throws ServletException, CategoryTitleAlreadyUsedException { + // Trace message + this.getLogger().trace(MessageFormat.format("request={0} - CALLED!", request)); //NOI18N + + // request must not be null + if (request == null) { + // Is null + throw new NullPointerException("request is null"); //NOI18N + } + + // Get all fields + String title = request.getParameter(PizzaCategoryDatabaseConstants.COLUMN_TITLE); + String parent = request.getParameter(PizzaCategoryDatabaseConstants.COLUMN_PARENT); + + // Debug message + this.getLogger().debug(MessageFormat.format("title={0},parent={1}", title, parent)); //NOI18N + + // Init variables for casting + Integer id = 0; + + // Check all fields + if (title == null) { + // "title" not set + throw new IllegalArgumentException(MessageFormat.format("{0} is not set.", PizzaCategoryDatabaseConstants.COLUMN_TITLE)); //NOI18N + } else if (title.isEmpty()) { + // Is left empty + throw new IllegalArgumentException(MessageFormat.format("{0} is empty.", PizzaCategoryDatabaseConstants.COLUMN_TITLE)); //NOI18N + } else if ((parent != null) && (!parent.isEmpty())) { + // "parent" is set, so check it + try { + id = Integer.parseInt(parent); + } catch (final NumberFormatException e) { + // Not valid number + throw new IllegalArgumentException(e); + } + } + + try { + // Try to check if title is used already + if (this.isCategoryTitleUsed(title)) { + // Title already used + throw new CategoryTitleAlreadyUsedException(request); + } + } catch (final IOException | SQLException | BadTokenException | CorruptedDatabaseFileException | NoSuchMethodException | IllegalAccessException | InvocationTargetException ex) { + throw new ServletException(ex); + } + + try { + // The category is not found, so add it to database + this.categoryFrontend.addCategory(title, id); + } catch (final SQLException | IOException ex) { + // Continue to throw it + throw new ServletException(ex); + } + + // Trace message + this.getLogger().trace("EXIT!"); //NOI18N + } + + /** + * Adds given product data from request to database + * + * @param request Request instance + */ + @Override + public void doAdminAddProduct (final HttpServletRequest request) throws ServletException, ProductTitleAlreadyUsedException { + // Trace message + this.getLogger().trace(MessageFormat.format("request={0} - CALLED!", request)); //NOI18N + + // request must not be null + if (request == null) { + // Is null + throw new NullPointerException("request is null"); //NOI18N + } + + // Get title, price and category id + String title = request.getParameter(PizzaProductDatabaseConstants.COLUMN_TITLE); + String price = request.getParameter(PizzaProductDatabaseConstants.COLUMN_PRICE); + String category = request.getParameter(PizzaProductDatabaseConstants.COLUMN_CATEGORY); + String available = request.getParameter(PizzaProductDatabaseConstants.COLUMN_AVAILABLE); + + // Debug message + this.getLogger().debug(MessageFormat.format("title={0},price={1},category={2},available={3}", title, price, category, available)); //NOI18N + + // Variables for converting + Long id = null; + Float p = null; + + // Check all fields + if (title == null) { + // "title" 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 + } else if (price == null) { + // "price" not set + throw new IllegalArgumentException(MessageFormat.format("{0} is not set.", PizzaProductDatabaseConstants.COLUMN_PRICE)); //NOI18N + } else if (price.isEmpty()) { + // Is left empty + throw new IllegalArgumentException(MessageFormat.format("{0} is empty.", PizzaProductDatabaseConstants.COLUMN_PRICE)); //NOI18N + } else if (category == null) { + // "title" not set + throw new IllegalArgumentException(MessageFormat.format("{0} is not set.", PizzaProductDatabaseConstants.COLUMN_CATEGORY)); //NOI18N + } else if (category.isEmpty()) { + // Is left empty + throw new IllegalArgumentException(MessageFormat.format("{0} is empty.", PizzaProductDatabaseConstants.COLUMN_CATEGORY)); //NOI18N + } else if (available == null) { + // "title" not set + throw new IllegalArgumentException(MessageFormat.format("{0} is not set.", PizzaProductDatabaseConstants.COLUMN_AVAILABLE)); //NOI18N + } else if (available.isEmpty()) { + // Is left empty + throw new IllegalArgumentException(MessageFormat.format("{0} is empty.", PizzaProductDatabaseConstants.COLUMN_AVAILABLE)); //NOI18N + } else if ((!"true".equals(available)) && (!"false".equals(available))) { //NOI18N + // Invalid value + throw new IllegalArgumentException(MessageFormat.format("{0} is invalid: {1}", PizzaProductDatabaseConstants.COLUMN_AVAILABLE, available)); //NOI18N + } + + // Parse numbers + try { + id = Long.parseLong(category); + p = Float.parseFloat(price); + } catch (final NumberFormatException e) { + // Not valid number + throw new IllegalArgumentException(e); + } + + // Parse boolean + Boolean a = Boolean.parseBoolean(available); + + // Test on product title + try { + // Try to check if title is used already + if (this.isProductTitleUsed(title)) { + // Title already used + throw new ProductTitleAlreadyUsedException(request); + } + } catch (final IOException | SQLException | BadTokenException | CorruptedDatabaseFileException | NoSuchMethodException | IllegalAccessException | InvocationTargetException ex) { + throw new ServletException(ex); + } + + try { + // The product is not found, so add it to database + this.productFrontend.addProduct(title, p, id, a); + } catch (final SQLException | IOException ex) { + // Continue to throw it + throw new ServletException(ex); + } + + // Trace message + this.getLogger().trace("EXIT!"); //NOI18N + } + + /** + * Generates link HTML code for given category's parent id, if set. This + * link then points to products.jsp?category_id=x + * + * @param category Category instance + * @return HTML code + */ + @Override + public String generateLinkForParent (final Category category) { + // Trace message + this.getLogger().trace(MessageFormat.format("category={0} - CALLED!", category)); //NOI18N + + // category must not be null + if (category == null) { + // Is null + throw new NullPointerException("category is null"); //NOI18N + } + + // Get parent id + Long parent = category.getParent(); + + // Is the id set? + if (parent > 0) { + // Product HTML code for link + throw new UnsupportedOperationException(MessageFormat.format("parent={0} - Unfinished!", parent)); //NOI18N + } + + // No parent set + return "Keine"; + } + + @Override + public String getPrintableProduktCategory (final Product product) throws ServletException { + // Trace message + this.getLogger().trace(MessageFormat.format("product={0} - CALLED!", product)); //NOI18N + + // product must not be null + if (product == null) { // Abort here - throw new NullPointerException("key is null"); + throw new NullPointerException("product is null"); //NOI18N } - // Now get it - Object value = this.getValueFromSession(session, key); + // 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(MessageFormat.format("value={0}", value)); + this.getLogger().debug(MessageFormat.format("category={0}", category)); //NOI18N + + 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(MessageFormat.format("Calling this.convertNullToEmpty({0}) ... - EXIT!", value)); + this.getLogger().trace(MessageFormat.format("title={0} - EXIT!", title)); //NOI18N - // Return actual value - return this.convertNullToEmpty(value); + // Return it + return title; + } + + /** + * Checks if product's title is already used. + * + * @param request Request instance + * @return Whether the product title is already used + * @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? + */ + private boolean isProductTitleUsed (final HttpServletRequest request) throws IOException, SQLException, BadTokenException, CorruptedDatabaseFileException, NoSuchMethodException, IllegalAccessException, IllegalArgumentException, InvocationTargetException { + // Trace message + this.getLogger().trace(MessageFormat.format("request={0} - CALLED!", request)); //NOI18N + + // 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"); //NOI18N + } 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 = this.isProductTitleUsed(title); + + // Trace message + this.getLogger().trace(MessageFormat.format("isUsed={0} - EXIT!", isUsed)); //NOI18N + + // Return it + return isUsed; + } + + /** + * Handles admin form requests + * @param request Request instance + * @param response Response instance + * @throws ServletException If something unexpected happened + */ + @Override + public void doAdminHandleProductForms (final HttpServletRequest request, final HttpServletResponse response) throws ServletException { + // Trace message + this.getLogger().trace(MessageFormat.format("request={0},response={1} - CALLED!", request, response)); //NOI18N + + // request and response must both be set + if (request == null) { + // request is null + throw new NullPointerException("request is null"); //NOI18N + } else if (response == null) { + // response is null + throw new NullPointerException("response is null"); //NOI18N + } + + // Try this operations + try { + // Is it post? + if ("POST".equals(request.getMethod())) { //NOI18N + // Is "add/edit/delete" set? + if (request.getParameter("add") != null) { //NOI18N + // Is it already added? + if (this.isProductTitleUsed(request)) { + // Debug message + this.getLogger().debug("Already used, redirecting ..."); //NOI18N + + // Already added, so redirect here, else a ServletException will be thrown + response.sendRedirect(String.format("%s/admin/product.jsp?already=1", request.getContextPath())); //NOI18N + } else { + // Add new product + this.doAdminAddProduct(request); + } + } else if (request.getParameter("edit") != null) { //NOI18N + // @TODO + } else if (request.getParameter("delete") != null) { //NOI18N + // @TODO + } + + // Redirect to proper URL + // @TODO Commented out for developing: + //response.sendRedirect(request.getContextPath() + "/finished.jsp"); + } + } catch (final IOException | SQLException | BadTokenException | CorruptedDatabaseFileException | ProductTitleAlreadyUsedException | NoSuchMethodException | IllegalAccessException | InvocationTargetException | IllegalArgumentException ex) { + // Throw it as cause + throw new ServletException(ex); + } + + // Trace message + this.getLogger().trace("EXIT!"); //NOI18N + } + + /** + * Handles admin form requests + * @param request Request instance + * @param response Response instance + * @throws ServletException If something unexpected happened + */ + @Override + public void doAdminHandleCategoryForms (final HttpServletRequest request, final HttpServletResponse response) throws ServletException { + // Trace message + this.getLogger().trace(MessageFormat.format("request={0},response={1} - CALLED!", request, response)); //NOI18N + + // request and response must both be set + if (request == null) { + // request is null + throw new NullPointerException("request is null"); //NOI18N + } else if (response == null) { + // response is null + throw new NullPointerException("response is null"); //NOI18N + } + + // Try this operations + try { + // Is it post? + if ("POST".equals(request.getMethod())) { //NOI18N + // Is "add/edit/delete" set? + if (request.getParameter("add") != null) { //NOI18N + // Is the category title already used? + if (this.isCategoryTitleUsed(request)) { + // Debug message + this.getLogger().debug("Already used, redirecting ..."); //NOI18N + + // Already added, so redirect here, else a ServletException will be thrown + response.sendRedirect(String.format("%s/admin/category.jsp?already=1", request.getContextPath())); //NOI18N + } else { + // Add new category + this.doAdminAddCategory(request); + } + } else if (request.getParameter("edit") != null) { //NOI18N + // @TODO + } else if (request.getParameter("delete") != null) { //NOI18N + // @TODO + } + + // Redirect to proper URL + // @TODO Commented out for developing: + //response.sendRedirect(request.getContextPath() + "/finished.jsp"); + } + } catch (final IOException | SQLException | BadTokenException | CorruptedDatabaseFileException | CategoryTitleAlreadyUsedException | NoSuchMethodException | IllegalAccessException | InvocationTargetException | IllegalArgumentException ex) { + // Throw it as cause + throw new ServletException(ex); + } + + // Trace message + this.getLogger().trace("EXIT!"); //NOI18N + } + + /** + * Checks if category's title is already used. + * + * @param request Request instance + * @return Whether the product title is already used + * @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? + */ + private boolean isCategoryTitleUsed (final HttpServletRequest request) throws IOException, SQLException, BadTokenException, CorruptedDatabaseFileException, NoSuchMethodException, IllegalAccessException, IllegalArgumentException, InvocationTargetException { + // Trace message + this.getLogger().trace(MessageFormat.format("request={0} - CALLED!", request)); //NOI18N + + // Init title + String title = request.getParameter(PizzaCategoryDatabaseConstants.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"); //NOI18N + } else if (title == null) { + // title is not set + throw new IllegalArgumentException(MessageFormat.format("{0} is not set.", PizzaCategoryDatabaseConstants.COLUMN_TITLE)); //NOI18N + } else if (title.isEmpty()) { + // Is left empty + throw new IllegalArgumentException(MessageFormat.format("{0} is empty.", PizzaCategoryDatabaseConstants.COLUMN_TITLE)); //NOI18N + } + + // Default is not used + boolean isUsed = this.isCategoryTitleUsed(title); + + // Trace message + this.getLogger().trace(MessageFormat.format("isUsed={0} - EXIT!", isUsed)); //NOI18N + + // Return it + return isUsed; } }