2 * Copyright (C) 2015 Roland Haeder
4 * This program is free software: you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation, either version 3 of the License, or
7 * (at your option) any later version.
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with this program. If not, see <http://www.gnu.org/licenses/>.
17 package org.mxchange.pizzaapplication.application;
19 import java.text.MessageFormat;
20 import java.util.Iterator;
22 import java.util.SortedMap;
23 import java.util.TreeMap;
24 import javax.servlet.ServletContext;
25 import javax.servlet.ServletException;
26 import javax.servlet.http.HttpServletRequest;
27 import javax.servlet.http.HttpSession;
28 import org.mxchange.jcore.BaseFrameworkSystem;
29 import org.mxchange.pizzaapplication.product.PizzaProduct;
30 import org.mxchange.pizzaapplication.product.Product;
34 * @author Roland Haeder
36 public class PizzaServiceApplication extends BaseFrameworkSystem implements PizzaApplication {
40 public static final String MAIN_TITLE = "Pizza-Service";
45 private final SortedMap<String, Product> products;
48 * Some singleton getter for this instance. If the instance is not set in
49 * given application, it will be created.
51 * @param application Servlet context
52 * @return This instance
53 * @throws javax.servlet.ServletException If object is not set correctly
55 public static final PizzaApplication getInstance (final ServletContext application) throws ServletException {
57 new PizzaServiceApplication().getLogger().trace(MessageFormat.format("application={0} - CALLED!", application)); //NOI18N
59 if (application == null) {
61 throw new NullPointerException("application is null"); //NOI18N
65 PizzaServiceApplication instance = null;
67 // Get instance from servlet
68 Object object = application.getAttribute("service"); //NOI18N
71 if (object instanceof PizzaServiceApplication) {
72 // Instance is set, so casting should work
73 instance = (PizzaServiceApplication) object;
74 } else if (object instanceof Object) {
75 // Not correct instance
76 throw new ServletException("service is not set correctly"); //NOI18N
78 // "service" is null, so initialize it
79 instance = new PizzaServiceApplication();
82 application.setAttribute("service", instance); //NOI18N
86 instance.getLogger().trace(MessageFormat.format("instance={0} - EXIT!", instance)); //NOI18N
95 private PizzaServiceApplication () {
96 // Init products instance
97 this.products = new TreeMap<>();
100 this.fillProductsList();
104 public void doBootstrap () {
105 throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
109 public void doMainLoop () {
110 throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
114 public void doShutdown () {
115 throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
119 * Getter for product (list) iterator
121 * @return An interator on all listed products
124 public Iterator<Map.Entry<String, Product>> getProductsIterator () {
125 assert(this.products instanceof SortedMap) : "this.products is not initialized"; //NOI18N
126 return this.products.entrySet().iterator();
130 * Adds given product to list or throws an exception if name is already found
132 * @param name Internal name of product
133 * @param title Product's title
136 private void addProduct (final String name, final String title, final float price) {
138 this.getLogger().trace(MessageFormat.format("name={0},title={1},price={2} - CALLED!", name, title, price)); //NOI18N
140 // Is the name already used?
141 if (this.isProductNameUsed(name)) {
142 // Something went wrong
143 throw new IllegalArgumentException(MessageFormat.format("product {0} is already used.", name)); //NOI18N
147 Product product = new PizzaProduct(name, title, price);
150 this.getLogger().debug(MessageFormat.format("Adding product={0} ...", product)); //NOI18N
153 this.products.put(product.getName(), product);
156 this.getLogger().trace("EXIT!"); //NOI18N
160 * Clears given parameter for product in session
162 * @param product Product instance
163 * @param session Session instance
164 * @param parameter Parameter to clear
166 private void clearSessionAttribute (final Product product, final HttpSession session, final String parameter) {
168 this.getLogger().trace(MessageFormat.format("produce={0},parameter={1},session={2} - CALLED!", product, parameter, session)); //NOI18N
171 this.getLogger().debug(MessageFormat.format("Clearing product={0},parameter={1} ...", product.getName(), parameter)); //NOI18N
172 this.setValueInSession(product, session, parameter, null);
175 this.getLogger().trace("EXIT!"); //NOI18N
179 * Fills products list
180 * @todo Very hard-coded stuff ...
182 private void fillProductsList () {
184 this.getLogger().trace("CALLED!"); //NOI18N
187 this.addProduct("italia", "Pizza Italia", 5.50f); //NOI18N
188 this.addProduct("diablo", "Pizza Diablo", 7.80f); //NOI18N
189 this.addProduct("bolognese", "Spagetti Bolognese", 11.95f); //NOI18N
192 this.getLogger().trace("EXIT!"); //NOI18N
196 * Some getter for value from session
198 * @param product Product instance
199 * @param session Session instance
200 * @param attribute Attribute to get value from
201 * @return Value from session
203 private Object getValueFromSession (final Product product, final HttpSession session, final String attribute) {
205 this.getLogger().trace(MessageFormat.format("product={0},session={1},attribute={2} - CALLED!", product, session, attribute)); //NOI18N
211 synchronized (session) {
212 value = session.getAttribute(String.format(HTTP_PARAM_MASK, product.getName(), attribute));
215 this.getLogger().debug(MessageFormat.format("product={0},attribute={1},value={2}", product.getName(), attribute, value)); //NOI18N
218 this.getLogger().trace(MessageFormat.format("value={0} - EXIT!", value)); //NOI18N
225 * Checks whether given product is already used
227 * @param name Name of product
228 * @return Whether the given product's name is already used
230 private boolean isProductNameUsed (final String name) {
232 this.getLogger().trace(MessageFormat.format("name={0} - CALLED!", name)); //NOI18N
235 return this.products.containsKey(name);
239 * For debugging purpose
241 * @param args Arguments
243 public static void main (String[] args) {
244 // Get instance and start it
245 new PizzaServiceApplication().start();
249 * Checks if the product ordered?
255 private boolean isProductOrdered (final Product product, final HttpSession session) {
257 this.getLogger().trace(MessageFormat.format("product={0},session={1} - CALLED!", product, session)); //NOI18N
260 Object isOrdered = this.getValueFromSession(product, session, SESSION_ORDERED);
261 this.getLogger().debug(MessageFormat.format("product={0},isOrdered={1}", product.getName(), isOrdered)); //NOI18N
264 return ("true".equals(isOrdered)); //NOI18N
268 * Somewhat setter in session
270 * @param product Product instance
271 * @param session Session instance
272 * @param keyPart Key part to include in final key
273 * @param value Value to set
275 private void setValueInSession (final Product product, final HttpSession session, final String keyPart, final Object value) {
277 this.getLogger().trace(MessageFormat.format("product={0},session={1},keyPart={2},value={3} - CALLED!", product, session, keyPart, value)); //NOI18N
279 synchronized(session) {
281 this.getLogger().debug(MessageFormat.format("setValueInSession: Setting value={0} for product={1},keyPart={2}", value, product.getName(), keyPart)); //NOI18N
282 session.setAttribute(String.format(HTTP_PARAM_MASK, product.getName(), keyPart), value);
286 this.getLogger().trace("EXIT!"); //NOI18N
290 * Application starter
292 private void start () {
294 Iterator<Map.Entry<String, Product>> iterator = this.getProductsIterator();
297 while (iterator.hasNext()) {
298 // Get product instance
299 Map.Entry<String, Product> entry = iterator.next();
302 Product product = entry.getValue();
305 this.getLogger().debug(MessageFormat.format("Product {0}, {1}: {2}", product.getName(), product.getTitle(), product.getPrice())); //NOI18N
310 * Some "getter" for amount from session
311 * @param product Product instance
312 * @param session Session instance
313 * @return Amount as string
316 public String getAmountFromSession (final Product product, final HttpSession session) {
318 this.getLogger().trace(MessageFormat.format("product={0},session={1} - CALLED!", product, session)); //NOI18N
320 // Is product and session set?
321 if (product == null) {
323 throw new NullPointerException("product is null"); //NOI18N
324 } else if (session == null) {
326 throw new NullPointerException("session is null"); //NOI18N
330 Object object = this.getValueFromSession(product, session, HTTP_PARAM_AMOUNT);
332 // Is the object null?
333 if (object == null) {
335 this.getLogger().trace("Returning 0 - EXIT!"); //NOI18N
342 this.getLogger().trace(MessageFormat.format("object={0} - EXIT!", object)); //NOI18N
344 // Cast to string and return it
345 return (String) object;
349 * Some "getter" for choose from session
351 * @param product Product instance
352 * @param session Session instance
353 * @return Choose as string
356 public String getChooseFromSession (final Product product, final HttpSession session) {
358 this.getLogger().trace(MessageFormat.format("product={0},session={1} - CALLED!", product, session)); //NOI18N
360 // Is product and session set?
361 if (product == null) {
363 throw new NullPointerException("product is null"); //NOI18N
364 } else if (session == null) {
366 throw new NullPointerException("session is null"); //NOI18N
370 Object object = this.getValueFromSession(product, session, HTTP_PARAM_CHOOSE);
372 // Is the object null?
373 if (object == null) {
375 this.getLogger().debug(MessageFormat.format("Returning empty string for product={0} ...", product.getName())); //NOI18N
380 this.getLogger().trace(MessageFormat.format("object={0} - CALLED!", object)); //NOI18N
382 // Cast to string and return it
383 return (String) object;
387 * Handler for amount from request or session
389 * @param product Product instance
390 * @param request Request instance
391 * @param session Session instance
392 * @return Amount as string
395 public String handleAmountFromRequestSession (final Product product, final HttpServletRequest request, final HttpSession session) {
397 this.getLogger().trace(MessageFormat.format("product={0},request={1},session={2} - CALLED!", product, request, session)); //NOI18N
399 // Is product and session set?
400 if (product == null) {
402 throw new NullPointerException("product is null"); //NOI18N
403 } else if (request == null) {
405 throw new NullPointerException("request is null"); //NOI18N
406 } else if (session == null) {
408 throw new NullPointerException("session is null"); //NOI18N
414 // Check request method
415 if (!"POST".equals(request.getMethod())) { //NOI18N
416 // Not POST, so get from session
417 return this.getAmountFromSession(product, session);
418 } else if (this.handleChooseFromRequestSession(product, request, session).isEmpty()) {
420 this.clearSessionAttribute(product, session, HTTP_PARAM_AMOUNT);
421 this.getLogger().debug(MessageFormat.format("Unsetting for product={0} in session, returning zero ...", product.getName())); //NOI18N
425 // Get attribute from request
426 object = request.getParameter(String.format(HTTP_PARAM_MASK, HTTP_PARAM_AMOUNT, product.getName()));
429 if (object instanceof String) {
430 // Try to parse it to integer
432 Integer value = Integer.valueOf((String) object);
433 } catch (final NumberFormatException ex) {
435 this.getLogger().warn(ex);
439 // Then set it in session
440 this.setValueInSession(product, session, HTTP_PARAM_AMOUNT, object);
443 return (String) object;
447 this.getLogger().trace("Calling getAmountFromSession() ..."); //NOI18N
449 // Get attribute from session
450 return this.getAmountFromSession(product, session);
454 * Handler for choosen (checkbox) from request or session
456 * @param product Product instance
457 * @param request Request instance
458 * @param session Session instance
459 * @return Amount as string
462 public String handleChooseFromRequestSession (final Product product, final HttpServletRequest request, final HttpSession session) {
464 this.getLogger().trace(MessageFormat.format("product={0},request={1},session={2} - CALLED!", product, request, session)); //NOI18N
466 // Is product and session set?
467 if (product == null) {
469 throw new NullPointerException("product is null"); //NOI18N
470 } else if (request == null) {
472 throw new NullPointerException("request is null"); //NOI18N
473 } else if (session == null) {
475 throw new NullPointerException("session is null"); //NOI18N
481 // Check request method
482 if (!"POST".equals(request.getMethod())) { //NOI18N
483 // Not POST, so get from session
484 return this.getChooseFromSession(product, session);
485 } else if (this.isProductOrdered(product, session)) {
486 // Product is ordered
487 return this.getChooseFromSession(product, session);
490 // Get reqzest element
491 object = request.getParameter(String.format(HTTP_PARAM_MASK, HTTP_PARAM_CHOOSE, product.getName()));
492 this.getLogger().debug(MessageFormat.format("product={0},object={1}", product.getName(), object)); //NOI18N
495 if (object == null) {
497 this.getLogger().debug(MessageFormat.format("Unsetting session for product={0} ...", product.getName())); //NOI18N
498 this.clearSessionAttribute(product, session, HTTP_PARAM_CHOOSE);
499 this.clearSessionAttribute(product, session, HTTP_PARAM_AMOUNT);
501 // Return empty string
505 // Then set it in session
506 this.setValueInSession(product, session, HTTP_PARAM_CHOOSE, object);
508 // Cast to string and return it
509 this.getLogger().debug(MessageFormat.format("product={0} - Returning {1} ...", product.getName(), object)); //NOI18N
510 return (String) object;
514 * Some "getter" for choosen (checkbox) from session
516 * @param product Product instance
517 * @param request Request instance
518 * @param session Session instance
519 * @return Amount as string
522 public String getPrintableChoosenFromRequestSession (final Product product, final HttpServletRequest request, final HttpSession session) {
524 this.getLogger().trace(MessageFormat.format("product={0},request={1},session={2} - CALLED!", product, request, session)); //NOI18N
526 // Is product and session set?
527 if (product == null) {
529 throw new NullPointerException("product is null"); //NOI18N
530 } else if (request == null) {
532 throw new NullPointerException("request is null"); //NOI18N
533 } else if (session == null) {
535 throw new NullPointerException("session is null"); //NOI18N
539 String choosen = this.handleChooseFromRequestSession(product, request, session);
540 this.getLogger().debug(MessageFormat.format("product={0},choosen={1}", product.getName(), choosen)); //NOI18N
543 assert(choosen instanceof String): "choosen is null"; //NOI18N
546 if (choosen.isEmpty()) {
552 String amount = this.handleAmountFromRequestSession(product, request, session);
553 this.getLogger().debug(MessageFormat.format("product={0},amount={1}", product.getName(), amount)); //NOI18N
556 assert(amount instanceof String): "amount is null"; //NOI18N
559 if (amount.isEmpty() || "0".equals(amount)) { //NOI18N
560 // Choosen, but no amount
569 * Some "getter" for total price of position from request or session.
570 * Single price and amount is multiplyed.
572 * @param product Product instance
573 * @param request Request instance
574 * @param session Session instance
575 * @return Amount as string
578 public float getTotalPositionPriceFromRequestSession (final Product product, final HttpServletRequest request, final HttpSession session) {
580 this.getLogger().trace(MessageFormat.format("product={0},request={1},session={2} - CALLED!", product, request, session)); //NOI18N
582 // Is product and session set?
583 if (product == null) {
585 throw new NullPointerException("product is null"); //NOI18N
586 } else if (request == null) {
588 throw new NullPointerException("request is null"); //NOI18N
589 } else if (session == null) {
591 throw new NullPointerException("session is null"); //NOI18N
595 String choosen = this.handleChooseFromRequestSession(product, request, session);
596 this.getLogger().debug(MessageFormat.format("product={0},choosen={1}", product.getName(), choosen)); //NOI18N
599 assert(choosen instanceof String): "choosen is null"; //NOI18N
602 if (choosen.isEmpty()) {
604 this.getLogger().debug(MessageFormat.format("product={0},choosen={1} - returning zero ...", product.getName(), choosen)); //NOI18N
609 String amount = this.handleAmountFromRequestSession(product, request, session);
610 this.getLogger().debug(MessageFormat.format("product={0},amount={1}", product.getName(), amount)); //NOI18N
613 assert(amount instanceof String): "amount is null"; //NOI18N
616 if (amount.isEmpty() || "0".equals(amount)) { //NOI18N
618 this.getLogger().debug(MessageFormat.format("product={0},amount={1} - returning zero ...", product.getName(), amount)); //NOI18N
623 Integer value = null;
627 // Get amount as integer
628 value = Integer.valueOf(amount);
629 } catch (final NumberFormatException e) {
631 throw new IllegalArgumentException(e);
635 float price = (product.getPrice() * value);
638 this.getLogger().trace(MessageFormat.format("product={0},price={1} - EXIT!", product.getName(), price)); //NOI18N
640 // Then multiply it with price
645 * Checks whether the given product is choosen, request overules session.
647 * @param product Product instance
648 * @param request Request instance
649 * @param session Session instance
650 * @return Whether the product is choosen
653 public boolean isProductChoosen (final Product product, final HttpServletRequest request, final HttpSession session) {
655 this.getLogger().trace(MessageFormat.format("product={0},request={1},session={2} - CALLED!", product, request, session)); //NOI18N
657 // Is product and session set?
658 if (product == null) {
660 throw new NullPointerException("product is null"); //NOI18N
661 } else if (request == null) {
663 throw new NullPointerException("request is null"); //NOI18N
664 } else if (session == null) {
666 throw new NullPointerException("session is null"); //NOI18N
670 String choosen = this.handleChooseFromRequestSession(product, request, session);
671 this.getLogger().debug(MessageFormat.format("product={0},choosen={1}", product.getName(), choosen)); //NOI18N
674 assert(choosen instanceof String): "choosen is null"; //NOI18N
676 // Is it not choosen?
677 if (choosen.isEmpty()) {
683 String amount = this.handleAmountFromRequestSession(product, request, session);
686 assert(amount instanceof String): "amount is not set"; //NOI18N
689 this.getLogger().trace(MessageFormat.format("amount={0} - EXIT!", amount)); //NOI18N
691 // Must not be empty and not 0
692 return (!amount.isEmpty() && !"0".equals(amount)); //NOI18N
696 * Calculates total price of all choosen products
698 * @param request Request instance
699 * @param session Session instance
700 * @return Total price of all choosen products
703 public float calculateTotalPrice (final HttpServletRequest request, final HttpSession session) {
705 this.getLogger().trace(MessageFormat.format("request={0},session={1} - CALLED!", request, session)); //NOI18N
707 // Is product and session set?
708 if (request == null) {
710 throw new NullPointerException("request is null"); //NOI18N
711 } else if (session == null) {
713 throw new NullPointerException("session is null"); //NOI18N
717 float totalPrice = 0.00f;
720 Iterator<Map.Entry<String, Product>> iterator = this.getProductsIterator();
722 // Walk through all products
723 while (iterator.hasNext()) {
725 Map.Entry<String, Product> entry = iterator.next();
727 // Get product instance
728 Product product = entry.getValue();
731 if (product.isChoosen()) {
732 // Then add product's total price
733 this.getLogger().debug(MessageFormat.format("Calling getTotalPositionPriceFromRequestSession({0},request,session) ...", product.getName())); //NOI18N
734 totalPrice += this.getTotalPositionPriceFromRequestSession(product, request, session);
736 this.getLogger().debug(MessageFormat.format("product={0},totalPrice={1}", product.getName(), totalPrice)); //NOI18N
740 this.getLogger().trace(MessageFormat.format(" totalPrice={0} - EXIT!", totalPrice)); //NOI18N
742 // Return total price
747 * Calculates total amount of all choosen products
749 * @param request Request instance
750 * @param session Session instance
751 * @return Total amount of all choosen products
754 public int calculateTotalAmount (final HttpServletRequest request, final HttpSession session) {
756 this.getLogger().trace(MessageFormat.format("request={0},session={1} - CALLED!", request, session)); //NOI18N
758 // Is product and session set?
759 if (request == null) {
761 throw new NullPointerException("request is null"); //NOI18N
762 } else if (session == null) {
764 throw new NullPointerException("session is null"); //NOI18N
771 Iterator<Map.Entry<String, Product>> iterator = this.getProductsIterator();
773 // Walk through all products
774 while (iterator.hasNext()) {
776 Map.Entry<String, Product> entry = iterator.next();
778 // Get product instance
779 Product product = entry.getValue();
782 if (product.isChoosen()) {
783 // Then add ordered amount
784 this.getLogger().debug(MessageFormat.format("Counting {0} ...", product.getName())); //NOI18N
787 String amount = this.getAmountFromSession(product, session);
790 this.getLogger().debug(MessageFormat.format("amount={0}", amount)); //NOI18N
791 totalAmount += Integer.valueOf(amount);
793 this.getLogger().debug(MessageFormat.format("product={0},totalAmount={1}", product.getName(), totalAmount)); //NOI18N
797 this.getLogger().trace(MessageFormat.format("totalAmount={0} - EXIT!", totalAmount)); //NOI18N
799 // Return total price
804 * Some "getter" for HTML code 'checked="checked"' if the product is choosen
806 * @param product Product instance
807 * @param request Request instance
808 * @param session Session instance
809 * @return Whether the product is choosen
812 public String getCheckedHtmlFromProduct (final Product product, final HttpServletRequest request, final HttpSession session) {
814 this.getLogger().trace(MessageFormat.format("product={0},request={1},session={2} - CALLED!", product, request, session)); //NOI18N
816 // Is product and session set?
817 if (product == null) {
819 throw new NullPointerException("product is null"); //NOI18N
820 } else if (request == null) {
822 throw new NullPointerException("request is null"); //NOI18N
823 } else if (session == null) {
825 throw new NullPointerException("session is null"); //NOI18N
828 // First let's check if the product is choosen
829 if (this.isProductChoosen(product, request, session)) {
831 this.getLogger().trace("Returning checked=\"checked\" - EXIT!"); //NOI18N
834 return "checked=\"checked\""; //NOI18N
837 this.getLogger().trace("Returning empty string - EXIT!"); //NOI18N
845 * Some "getter" for HTML code 'disabled="disabled"' for e.g. submit buttons
847 * @param request Request instance
848 * @param session Session instance
849 * @return Whether the product is choosen
852 public String getDisabledHtmlFromSession (final HttpServletRequest request, final HttpSession session) {
854 this.getLogger().trace(MessageFormat.format("request={0},session={1} - CALLED!", request, session)); //NOI18N
856 // Is product and session set?
857 if (request == null) {
859 throw new NullPointerException("request is null"); //NOI18N
860 } else if (session == null) {
862 throw new NullPointerException("session is null"); //NOI18N
865 // Is something selected?
866 if (this.calculateTotalAmount(request, session) > 0) {
868 this.getLogger().trace("Returning empty string - EXIT!"); //NOI18N
870 // Something has been choosen
874 this.getLogger().trace("Returning disabled=\"disabled\" - EXIT!"); //NOI18N
876 // Nothing choosen yet
877 return "disabled=\"disabled\""; //NOI18N
882 * Marks given product as ordered in session
884 * @param product Product to mark as ordered
885 * @param session Session instance
888 public void markProductAsOrdered(final Product product, final HttpSession session) {
890 this.getLogger().trace(MessageFormat.format("product={0},session={1} - CALLED!", product, session)); //NOI18N
892 // Is product and session set?
893 if (product == null) {
895 throw new NullPointerException("product is null"); //NOI18N
896 } else if (session == null) {
898 throw new NullPointerException("session is null"); //NOI18N
901 // Mark it as ordered by setting flag
902 this.getLogger().debug(MessageFormat.format("Marking product={0} as ordered.", product.getName())); //NOI18N
903 this.setValueInSession(product, session, SESSION_ORDERED, "true"); //NOI18N
906 this.getLogger().trace("EXIT!"); //NOI18N
910 * Unmarks given product as ordered in session
912 * @param product Product to unmark as ordered
913 * @param session Session instance
916 public void unmarkProductAsOrdered(final Product product, final HttpSession session) {
918 this.getLogger().trace(MessageFormat.format("product={0},session={1} - CALLED!", product, session)); //NOI18N
920 // Is product and session set?
921 if (product == null) {
923 throw new NullPointerException("product is null"); //NOI18N
924 } else if (session == null) {
926 throw new NullPointerException("session is null"); //NOI18N
929 // Mark it as ordered by setting flag
930 this.getLogger().debug(MessageFormat.format("Unmarking product={0} as ordered.", product.getName())); //NOI18N
931 this.clearSessionAttribute(product, session, SESSION_ORDERED);
934 this.getLogger().trace("EXIT!"); //NOI18N