]> git.mxchange.org Git - pizzaservice-war.git/blob - src/java/org/mxchange/pizzaapplication/application/PizzaServiceApplication.java
8a8adac8769b233946ed8f836a83839fd5e495d6
[pizzaservice-war.git] / src / java / org / mxchange / pizzaapplication / application / PizzaServiceApplication.java
1 /*
2  * Copyright (C) 2015 Roland Haeder
3  *
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.
8  *
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.
13  *
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/>.
16  */
17 package org.mxchange.pizzaapplication.application;
18
19 import java.io.IOException;
20 import java.lang.reflect.Field;
21 import java.lang.reflect.InvocationTargetException;
22 import java.sql.SQLException;
23 import java.text.MessageFormat;
24 import java.util.Iterator;
25 import java.util.Map;
26 import java.util.SortedMap;
27 import java.util.TreeMap;
28 import javax.servlet.ServletContext;
29 import javax.servlet.ServletException;
30 import javax.servlet.http.HttpServletRequest;
31 import javax.servlet.http.HttpSession;
32 import org.mxchange.jcore.contact.Gender;
33 import org.mxchange.jcore.exceptions.BadTokenException;
34 import org.mxchange.jcore.exceptions.UnsupportedDatabaseBackendException;
35 import org.mxchange.pizzaapplication.BasePizzaServiceSystem;
36 import org.mxchange.pizzaapplication.customer.Customer;
37 import org.mxchange.pizzaapplication.customer.PizzaServiceCustomer;
38 import org.mxchange.pizzaapplication.database.frontend.product.PizzaProductDatabaseFrontend;
39 import org.mxchange.pizzaapplication.database.frontend.product.ProductFrontend;
40 import org.mxchange.pizzaapplication.product.Product;
41
42 /**
43  *
44  * @author Roland Haeder
45  */
46 public class PizzaServiceApplication extends BasePizzaServiceSystem implements PizzaApplication {
47         /**
48          * Main title
49          */
50         public static final String MAIN_TITLE = "Pizza-Service";
51
52         /**
53          * Some singleton getter for this instance. If the instance is not set in
54          * given application, it will be created.
55          *
56          * @param context Servlet context
57          * @return This instance
58          * @throws javax.servlet.ServletException If object is not set correctly
59          */
60         public static final PizzaApplication getInstance (final ServletContext context) throws ServletException {
61                 // Check application instance
62                 if (context == null) {
63                         // Not set
64                         throw new NullPointerException("application is null"); //NOI18N
65                 }
66
67                 // Init instance
68                 PizzaApplication instance = null;
69
70                 // Get instance from servlet application (aka. "application scope")
71                 Object object = context.getAttribute("app"); //NOI18N
72
73                 // Is it set?
74                 if (object instanceof PizzaApplication) {
75                         // Instance is set, so casting should work
76                         instance = (PizzaApplication) object;
77                 } else if (object instanceof Object) {
78                         // Not correct instance
79                         throw new ServletException("app is not set correctly"); //NOI18N
80                 } else {
81                         try {
82                                 // "service" is null, so initialize it
83                                 instance = new PizzaServiceApplication(context);
84                         } catch (final UnsupportedDatabaseBackendException | SQLException | IOException | BadTokenException ex) {
85                                 throw new ServletException(ex);
86                         }
87
88                         // And set it here
89                         context.setAttribute("app", instance); //NOI18N
90                 }
91
92                 // Trace message
93                 instance.getLogger().trace(MessageFormat.format("instance={0} - EXIT!", instance)); //NOI18N
94
95                 // Return it
96                 return instance;
97         }
98
99         /**
100          * For debugging purpose
101          *
102          * @param args Arguments
103          */
104         public static void main (String[] args) {
105                 // Get instance and start it
106                 new PizzaServiceApplication().start();
107         }
108
109         /**
110          * Product list 
111          */
112         private final SortedMap<String, Product> products;
113
114         /**
115          * Private constructor
116          */
117         private PizzaServiceApplication () {
118                 // Init products instance
119                 this.products = new TreeMap<>();
120         }
121
122         /**
123          * Constructor with servet configuration
124          *
125          * @param context Servlet context
126          */
127         private PizzaServiceApplication (final ServletContext context) throws UnsupportedDatabaseBackendException, SQLException, IOException, BadTokenException {
128                 // Call other constructor first
129                 this();
130
131                 // Temporary initialize default bundle
132                 // @TODO The JSF may have better internatialization support
133                 this.initBundle();
134
135                 // Initialize properties from config
136                 this.initProperties(context);
137
138                 // Load available products
139                 this.fillProductsList();
140         }
141
142         /**
143          * Calculates total amount of all choosen products
144          *
145          * @param request Request instance
146          * @param session Session instance
147          * @return Total amount of all choosen products
148          */
149         @Override
150         public int calculateTotalAmount (final HttpServletRequest request, final HttpSession session) {
151                 // Trace message
152                 this.getLogger().trace(MessageFormat.format("request={0},session={1} - CALLED!", request, session)); //NOI18N
153
154                 // Is product and session set?
155                 if (request == null) {
156                         // Not set
157                         throw new NullPointerException("request is null"); //NOI18N
158                 } else if (session == null) {
159                         // Not set
160                         throw new NullPointerException("session is null"); //NOI18N
161                 }
162
163                 // Init total price
164                 int totalAmount = 0;
165
166                 // "Walk" over all products
167                 for (final Product product : this.getProducts()) {
168                         // Is this choosen?
169                         if (this.isProductChoosen(product, request, session)) {
170                                 // Then add ordered amount
171                                 this.getLogger().debug(MessageFormat.format("Counting {0} ...", product.getName())); //NOI18N
172
173                                 // Getting amount
174                                 String amount = this.getAmountFromSession(product, session);
175
176                                 // Add it up
177                                 this.getLogger().debug(MessageFormat.format("amount={0}", amount)); //NOI18N
178                                 totalAmount += Integer.valueOf(amount);
179                         }
180                         this.getLogger().debug(MessageFormat.format("product={0},totalAmount={1}", product.getName(), totalAmount)); //NOI18N
181                 }
182
183                 // Trace message
184                 this.getLogger().trace(MessageFormat.format("totalAmount={0} - EXIT!", totalAmount)); //NOI18N
185
186                 // Return total price
187                 return totalAmount;
188         }
189
190         /**
191          * Calculates total price of all choosen products
192          *
193          * @param request Request instance
194          * @param session Session instance
195          * @return Total price of all choosen products
196          */
197         @Override
198         public float calculateTotalPrice (final HttpServletRequest request, final HttpSession session) {
199                 // Trace message
200                 this.getLogger().trace(MessageFormat.format("request={0},session={1} - CALLED!", request, session)); //NOI18N
201
202                 // Is product and session set?
203                 if (request == null) {
204                         // Not set
205                         throw new NullPointerException("request is null"); //NOI18N
206                 } else if (session == null) {
207                         // Not set
208                         throw new NullPointerException("session is null"); //NOI18N
209                 }
210
211                 // Init total price
212                 float totalPrice = 0.00f;
213
214                 // "Walk" over all products
215                 for (final Product product : this.getProducts()) {
216                         // Is this choosen?
217                         if (this.isProductChoosen(product, request, session)) {
218                                 // Then add product's total price
219                                 this.getLogger().debug(MessageFormat.format("Calling getTotalPositionPriceFromRequestSession({0},request,session) ...", product.getName())); //NOI18N
220                                 totalPrice += this.getTotalPositionPriceFromRequestSession(product, request, session);
221                         }
222                         this.getLogger().debug(MessageFormat.format("product={0},totalPrice={1}", product.getName(), totalPrice)); //NOI18N
223                 }
224
225                 // Trace message
226                 this.getLogger().trace(MessageFormat.format(" totalPrice={0} - EXIT!", totalPrice)); //NOI18N
227
228                 // Return total price
229                 return totalPrice;
230         }
231
232         @Override
233         public void doBootstrap () {
234                 throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
235         }
236
237         @Override
238         public void doMainLoop () {
239                 throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
240         }
241
242         @Override
243         public void doShutdown () {
244                 throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
245         }
246
247         /**
248          * Some "getter" for amount from session
249          *
250          * @param product Product instance
251          * @param session Session instance
252          * @return Amount as string
253          */
254         @Override
255         public String getAmountFromSession (final Product product, final HttpSession session) {
256                 // Trace message
257                 this.getLogger().trace(MessageFormat.format("product={0},session={1} - CALLED!", product, session)); //NOI18N
258
259                 // Is product and session set?
260                 if (product == null) {
261                         // Not set
262                         throw new NullPointerException("product is null"); //NOI18N
263                 } else if (session == null) {
264                         // Not set
265                         throw new NullPointerException("session is null"); //NOI18N
266                 }
267
268                 // Get attribute
269                 Object object = this.getValueFromSession(product, session, HTTP_PARAM_AMOUNT);
270
271                 // Is the object null?
272                 if (object == null) {
273                         // Trace message
274                         this.getLogger().trace("Returning 0 - EXIT!"); //NOI18N
275
276                         // Not found
277                         return "0"; //NOI18N
278                 }
279
280                 // Trace message
281                 this.getLogger().trace(MessageFormat.format("object={0} - EXIT!", object)); //NOI18N
282
283                 // Cast to string and return it
284                 return (String) object;
285         }
286
287         /**
288          * Some "getter" for HTML code 'checked="checked"' if the product is choosen
289          * 
290          * @param product Product instance
291          * @param request Request instance
292          * @param session Session instance
293          * @return Whether the product is choosen
294          */
295         @Override
296         public String getCheckedHtmlFromProduct (final Product product, final HttpServletRequest request, final HttpSession session) {
297                 // Trace message
298                 this.getLogger().trace(MessageFormat.format("product={0},request={1},session={2} - CALLED!", product, request, session)); //NOI18N
299
300                 // Is product and session set?
301                 if (product == null) {
302                         // Not set
303                         throw new NullPointerException("product is null"); //NOI18N
304                 } else if (request == null) {
305                         // Not set
306                         throw new NullPointerException("request is null"); //NOI18N
307                 } else if (session == null) {
308                         // Not set
309                         throw new NullPointerException("session is null"); //NOI18N
310                 }
311
312                 // First let's check if the product is choosen
313                 if (this.isProductChoosen(product, request, session)) {
314                         // Trace message
315                         this.getLogger().trace("Returning checked=\"checked\" - EXIT!"); //NOI18N
316
317                         // Is choosen
318                         return "checked=\"checked\""; //NOI18N
319                 } else {
320                         // Trace message
321                         this.getLogger().trace("Returning empty string - EXIT!"); //NOI18N
322
323                         // Not choosen
324                         return ""; //NOI18N
325                 }
326         }
327
328         /**
329          * Some "getter" for choose from session
330          * 
331          * @param product Product instance
332          * @param session Session instance
333          * @return Choose as string
334          */
335         @Override
336         public String getChooseFromSession (final Product product, final HttpSession session) {
337                 // Trace message
338                 this.getLogger().trace(MessageFormat.format("product={0},session={1} - CALLED!", product, session)); //NOI18N
339
340                 // Is product and session set?
341                 if (product == null) {
342                         // Not set
343                         throw new NullPointerException("product is null"); //NOI18N
344                 } else if (session == null) {
345                         // Not set
346                         throw new NullPointerException("session is null"); //NOI18N
347                 }
348
349                 // Get attribute
350                 Object object = this.getValueFromSession(product, session, HTTP_PARAM_CHOOSE);
351
352                 // Is the object null?
353                 if (object == null) {
354                         // Not found
355                         this.getLogger().debug(MessageFormat.format("Returning empty string for product={0} ...", product.getName())); //NOI18N
356                         return ""; //NOI18N
357                 }
358
359                 // Trace message
360                 this.getLogger().trace(MessageFormat.format("object={0} - CALLED!", object)); //NOI18N
361
362                 // Cast to string and return it
363                 return (String) object;
364         }
365
366         /**
367          * Some "getter" for HTML code 'disabled="disabled"' for e.g. submit buttons
368          *
369          * @param request Request instance
370          * @param session Session instance
371          * @return Whether the product is choosen
372          */
373         @Override
374         public String getDisabledHtmlFromSession (final HttpServletRequest request, final HttpSession session) {
375                 // Trace message
376                 this.getLogger().trace(MessageFormat.format("request={0},session={1} - CALLED!", request, session)); //NOI18N
377
378                 // Is product and session set?
379                 if (request == null) {
380                         // Not set
381                         throw new NullPointerException("request is null"); //NOI18N
382                 } else if (session == null) {
383                         // Not set
384                         throw new NullPointerException("session is null"); //NOI18N
385                 }
386
387                 // Is something selected?
388                 if (this.calculateTotalAmount(request, session) > 0) {
389                         // Trace message
390                         this.getLogger().trace("Returning empty string - EXIT!"); //NOI18N
391
392                         // Something has been choosen
393                         return ""; //NOI18N
394                 } else {
395                         // Trace message
396                         this.getLogger().trace("Returning disabled=\"disabled\" - EXIT!"); //NOI18N
397
398                         // Nothing choosen yet
399                         return "disabled=\"disabled\""; //NOI18N
400                 }
401         }
402
403         /**
404          * Some "getter" for choosen (checkbox) from session
405          *
406          * @param product Product instance
407          * @param request Request instance
408          * @param session Session instance
409          * @return Amount as string
410          */
411         @Override
412         public String getPrintableChoosenFromRequestSession (final Product product, final HttpServletRequest request, final HttpSession session) {
413                 // Trace message
414                 this.getLogger().trace(MessageFormat.format("product={0},request={1},session={2} - CALLED!", product, request, session)); //NOI18N
415
416                 // Is product and session set?
417                 if (product == null) {
418                         // Not set
419                         throw new NullPointerException("product is null"); //NOI18N
420                 } else if (request == null) {
421                         // Not set
422                         throw new NullPointerException("request is null"); //NOI18N
423                 } else if (session == null) {
424                         // Not set
425                         throw new NullPointerException("session is null"); //NOI18N
426                 }
427
428                 // Get element
429                 this.getLogger().debug(MessageFormat.format("Calling handleChooseFromRequestSession({0},{1},{2}) ...", product.getName(), request, session)); //NOI18N
430                 String choosen = this.handleChooseFromRequestSession(product, request, session);
431                 this.getLogger().debug(MessageFormat.format("product={0},choosen={1}", product.getName(), choosen)); //NOI18N
432
433                 // Must not be null
434                 assert(choosen instanceof String): "choosen is null"; //NOI18N
435
436                 // Is it empty?
437                 if (choosen.isEmpty()) {
438                         // Not choosen
439                         return "Nein";
440                 }
441
442                 // Get amount
443                 String amount = this.handleAmountFromRequestSession(product, request, session);
444                 this.getLogger().debug(MessageFormat.format("product={0},amount={1}", product.getName(), amount)); //NOI18N
445
446                 // Must not be null
447                 assert(amount instanceof String): "amount is null"; //NOI18N
448
449                 // Is it empty?
450                 if (amount.isEmpty() || "0".equals(amount)) { //NOI18N
451                         // Choosen, but no amount
452                         return "Nein";
453                 } else {
454                         // Is choosen
455                         return "Ja";
456                 }
457         }
458
459         /**
460          * Checks if given Product instance is available and returns a printable
461          * (human-readable) string.
462          * 
463          * @param product Product instance to check
464          * @return Human-readable version of product availability
465          */
466         @Override
467         public String getPrintableProduktAvailability (final Product product) {
468                 throw new UnsupportedOperationException(MessageFormat.format("Not supported yet: product={0}", product));
469         }
470
471         /**
472          * Some getter for printable value from session or an empty string for null.
473          *
474          * @param session Session instance
475          * @param key Key to get
476          * @return Value from key, empty string for null
477          */
478         @Override
479         public Object getPrintableValeFromSession (final HttpSession session, final String key) {
480                 // Trace message
481                 this.getLogger().trace(MessageFormat.format("session={0},key={1} - CALLED", session, key)); //NOI18N
482
483                 // Are both parameter not null?
484                 if (session == null) {
485                         // Abort here
486                         throw new NullPointerException("session is null"); //NOI18N
487                 } else  if (key == null) {
488                         // Abort here
489                         throw new NullPointerException("key is null"); //NOI18N
490                 }
491
492                 // Now get it
493                 Object value = this.getValueFromSession(session, key);
494
495                 // Debug message
496                 this.getLogger().debug(MessageFormat.format("value={0}", value)); //NOI18N
497
498                 // Trace message
499                 this.getLogger().trace(MessageFormat.format("Calling this.convertNullToEmpty({0}) ... - EXIT!", value)); //NOI18N
500
501                 // Return actual value
502                 return this.convertNullToEmpty(value);
503         }
504
505         /**
506          * Some "getter" for a an array of all products
507          *
508          * @return Unmarked products
509          */
510         @Override
511         public Product[] getProducts () {
512                 return this.products.values().toArray(new Product[this.products.size()]);
513         }
514
515         /**
516          * Some "getter" for total price of position from request or session.
517          * Single price and amount is multiplyed.
518          *
519          * @param product Product instance
520          * @param request Request instance
521          * @param session Session instance
522          * @return Amount as string
523          */
524         @Override
525         public float getTotalPositionPriceFromRequestSession (final Product product, final HttpServletRequest request, final HttpSession session) {
526                 // Trace message
527                 this.getLogger().trace(MessageFormat.format("product={0},request={1},session={2} - CALLED!", product, request, session)); //NOI18N
528
529                 // Is product and session set?
530                 if (product == null) {
531                         // Not set
532                         throw new NullPointerException("product is null"); //NOI18N
533                 } else if (request == null) {
534                         // Not set
535                         throw new NullPointerException("request is null"); //NOI18N
536                 } else if (session == null) {
537                         // Not set
538                         throw new NullPointerException("session is null"); //NOI18N
539                 }
540
541                 // Get choosen
542                 this.getLogger().debug(MessageFormat.format("Calling handleChooseFromRequestSession({0},{1},{2}) ...", product.getName(), request, session)); //NOI18N
543                 String choosen = this.handleChooseFromRequestSession(product, request, session);
544                 this.getLogger().debug(MessageFormat.format("product={0},choosen={1}", product.getName(), choosen)); //NOI18N
545
546                 // Must not be null
547                 assert(choosen instanceof String): "choosen is null"; //NOI18N
548
549                 // Is it set?
550                 if (choosen.isEmpty()) {
551                         // Is empty
552                         this.getLogger().debug(MessageFormat.format("product={0},choosen={1} - returning zero ...", product.getName(), choosen)); //NOI18N
553                         return 0.00f;
554                 }
555
556                 // Get amount
557                 String amount = this.handleAmountFromRequestSession(product, request, session);
558                 this.getLogger().debug(MessageFormat.format("product={0},amount={1}", product.getName(), amount)); //NOI18N
559
560                 // Must not be null
561                 assert(amount instanceof String): "amount is null"; //NOI18N
562
563                 // Is it empty?
564                 if (amount.isEmpty() || "0".equals(amount)) { //NOI18N
565                         // Is empty
566                         this.getLogger().debug(MessageFormat.format("product={0},amount={1} - returning zero ...", product.getName(), amount)); //NOI18N
567                         return 0.00f;
568                 }
569
570                 // Init variable
571                 Integer value = null;
572
573                 // Try it
574                 try {
575                         // Get amount as integer
576                         value = Integer.valueOf(amount);
577                 } catch (final NumberFormatException e) {
578                         // Bat input
579                         throw new IllegalArgumentException(e);
580                 }
581
582                 // Calculate price
583                 float price = (product.getPrice() * value);
584
585                 // Trace message
586                 this.getLogger().trace(MessageFormat.format("product={0},price={1} - EXIT!", product.getName(), price)); //NOI18N
587
588                 // Then multiply it with price
589                 return price;
590         }
591
592         /**
593          * Gets an array of products from product iterator and unmarks them as ordered
594          *
595          * @param session HttpSession instance
596          * @return Unmarked products
597          */
598         @Override
599         public Product[] getUnmarkedProducts (final HttpSession session) {
600                 // Init array
601                 Product[] array = this.getProducts();
602
603                 // Unmark are all as ordered
604                 for (final Product product : array) {
605                         this.unmarkProductAsOrdered(product, session);
606                 }
607
608                 // Return finished array
609                 return array;
610         }
611
612         /**
613          * Handler for amount from request or session
614          *
615          * @param product Product instance
616          * @param request Request instance
617          * @param session Session instance
618          * @return Amount as string
619          */
620         @Override
621         public String handleAmountFromRequestSession (final Product product, final HttpServletRequest request, final HttpSession session) {
622                 // Trace message
623                 this.getLogger().trace(MessageFormat.format("product={0},request={1},session={2} - CALLED!", product, request, session)); //NOI18N
624
625                 // Is product and session set?
626                 if (product == null) {
627                         // Not set
628                         throw new NullPointerException("product is null"); //NOI18N
629                 } else if (request == null) {
630                         // Not set
631                         throw new NullPointerException("request is null"); //NOI18N
632                 } else if (session == null) {
633                         // Not set
634                         throw new NullPointerException("session is null"); //NOI18N
635                 }
636
637                 // Init variabke
638                 Object object;
639
640                 // Check request method
641                 if (!"POST".equals(request.getMethod())) { //NOI18N
642                         // Not POST, so get from session
643                         return this.getAmountFromSession(product, session);
644                 } else if (this.handleChooseFromRequestSession(product, request, session).isEmpty()) {
645                         // Not choosen
646                         this.clearSessionAttribute(product, session, HTTP_PARAM_AMOUNT);
647                         this.getLogger().debug(MessageFormat.format("Unsetting for product={0} in session, returning zero ...", product.getName())); //NOI18N
648                         return "0"; //NOI18N
649                 }
650
651                 // Get attribute from request
652                 object = request.getParameter(String.format(HTTP_PARAM_MASK, HTTP_PARAM_AMOUNT, product.getName()));
653
654                 // Is it set?
655                 if (object instanceof String) {
656                         // Try to parse it to integer
657                         try {
658                                 Integer value = Integer.valueOf((String) object);
659                         } catch (final NumberFormatException ex) {
660                                 // Not valid input
661                                 this.getLogger().warn(ex);
662                                 return "0"; //NOI18N
663                         }
664
665                         // Then set it in session
666                         this.setValueInSession(product, session, HTTP_PARAM_AMOUNT, object);
667
668                         // And return it
669                         return (String) object;
670                 }
671
672                 // Trace message
673                 this.getLogger().trace("Calling getAmountFromSession() ..."); //NOI18N
674
675                 // Get attribute from session
676                 return this.getAmountFromSession(product, session);
677         }
678
679         /**
680          * Checks whether the given product is choosen, request overules session.
681          *
682          * @param product Product instance
683          * @param request Request instance
684          * @param session Session instance
685          * @return Whether the product is choosen
686          */
687         @Override
688         public boolean isProductChoosen (final Product product, final HttpServletRequest request, final HttpSession session) {
689                 // Trace message
690                 this.getLogger().trace(MessageFormat.format("product={0},request={1},session={2} - CALLED!", product, request, session)); //NOI18N
691
692                 // Is product and session set?
693                 if (product == null) {
694                         // Not set
695                         throw new NullPointerException("product is null"); //NOI18N
696                 } else if (request == null) {
697                         // Not set
698                         throw new NullPointerException("request is null"); //NOI18N
699                 } else if (session == null) {
700                         // Not set
701                         throw new NullPointerException("session is null"); //NOI18N
702                 }
703
704                 // Get choosen
705                 this.getLogger().debug(MessageFormat.format("Calling handleChooseFromRequestSession({0},{1},{2}) ...", product.getName(), request, session)); //NOI18N
706                 String choosen = this.handleChooseFromRequestSession(product, request, session);
707                 this.getLogger().debug(MessageFormat.format("product={0},choosen={1}", product.getName(), choosen)); //NOI18N
708
709                 // Must not be null
710                 assert(choosen instanceof String): "choosen is null"; //NOI18N
711
712                 // Is it not choosen?
713                 if (choosen.isEmpty()) {
714                         // Not choosen
715                         return false;
716                 }
717
718                 // Get amount
719                 String amount = this.handleAmountFromRequestSession(product, request, session);
720
721                 // Must not be null
722                 assert(amount instanceof String): "amount is not set"; //NOI18N
723
724                 // Trace message
725                 this.getLogger().trace(MessageFormat.format("amount={0} - EXIT!", amount)); //NOI18N
726
727                 // Must not be empty and not 0
728                 return (!amount.isEmpty() && !"0".equals(amount)); //NOI18N
729         }
730
731         /**
732          * Marks given product as choosen in session
733          *
734          * @param product Product to mark as ordered
735          * @param session Session instance
736          */
737         @Override
738         public void markProductAsChoosen (final Product product, final HttpSession session) {
739                 // Trace message
740                 this.getLogger().trace(MessageFormat.format("product={0},session={1} - CALLED!", product, session)); //NOI18N
741
742                 // Is product and session set?
743                 if (product == null) {
744                         // Not set
745                         throw new NullPointerException("product is null"); //NOI18N
746                 } else if (session == null) {
747                         // Not set
748                         throw new NullPointerException("session is null"); //NOI18N
749                 }
750
751                 // Mark it as ordered by setting flag
752                 this.getLogger().debug(MessageFormat.format("Marking product={0} as choosen.", product.getName())); //NOI18N
753                 this.setValueInSession(product, session, HTTP_PARAM_CHOOSE, "1"); //NOI18N
754
755                 // Trace message
756                 this.getLogger().trace("EXIT!"); //NOI18N
757         }
758
759         /**
760          * Marks given product as ordered in session
761          *
762          * @param product Product to mark as ordered
763          * @param session Session instance
764          */
765         @Override
766         public void markProductAsOrdered (final Product product, final HttpSession session) {
767                 // Trace message
768                 this.getLogger().trace(MessageFormat.format("product={0},session={1} - CALLED!", product, session)); //NOI18N
769
770                 // Is product and session set?
771                 if (product == null) {
772                         // Not set
773                         throw new NullPointerException("product is null"); //NOI18N
774                 } else if (session == null) {
775                         // Not set
776                         throw new NullPointerException("session is null"); //NOI18N
777                 }
778
779                 // Mark it as ordered by setting flag
780                 this.getLogger().debug(MessageFormat.format("Marking product={0} as ordered.", product.getName())); //NOI18N
781                 this.setValueInSession(product, session, SESSION_ORDERED, "true"); //NOI18N
782
783                 // Trace message
784                 this.getLogger().trace("EXIT!"); //NOI18N
785         }
786
787         /**
788          * Somewhat setter in session
789          *
790          * @param session Session instance
791          * @param key Session key to set
792          * @param value Value to set
793          */
794         @Override
795         public void setValueInSession (final HttpSession session, final String key, final Object value) {
796                 // Trace message
797                 this.getLogger().trace(MessageFormat.format("session={0},key={1},value={2} - CALLED!", session, key, value)); //NOI18N
798
799                 synchronized(session) {
800                         // Set it synced
801                         session.setAttribute(key, value);
802                 }
803
804                 // Trace message
805                 this.getLogger().trace("EXIT!"); //NOI18N
806         }
807
808         /**
809          * Unmarks given product as choosen in session
810          *
811          * @param product Product to unmark as choosen
812          * @param session Session instance
813          */
814         @Override
815         public void unmarkProductAsChoosen (final Product product, final HttpSession session) {
816                 // Trace message
817                 this.getLogger().trace(MessageFormat.format("product={0},session={1} - CALLED!", product, session)); //NOI18N
818
819                 // Is product and session set?
820                 if (product == null) {
821                         // Not set
822                         throw new NullPointerException("product is null"); //NOI18N
823                 } else if (session == null) {
824                         // Not set
825                         throw new NullPointerException("session is null"); //NOI18N
826                 }
827
828                 // Mark it as ordered by setting flag
829                 this.getLogger().debug(MessageFormat.format("Unmarking product={0} as choosen.", product.getName())); //NOI18N
830                 this.clearSessionAttribute(product, session, HTTP_PARAM_CHOOSE);
831
832                 // Trace message
833                 this.getLogger().trace("EXIT!"); //NOI18N
834         }
835
836         /**
837          * Unmarks given product as ordered in session
838          *
839          * @param product Product to unmark as ordered
840          * @param session Session instance
841          */
842         @Override
843         public void unmarkProductAsOrdered (final Product product, final HttpSession session) {
844                 // Trace message
845                 this.getLogger().trace(MessageFormat.format("product={0},session={1} - CALLED!", product, session)); //NOI18N
846
847                 // Is product and session set?
848                 if (product == null) {
849                         // Not set
850                         throw new NullPointerException("product is null"); //NOI18N
851                 } else if (session == null) {
852                         // Not set
853                         throw new NullPointerException("session is null"); //NOI18N
854                 }
855
856                 // Mark it as ordered by setting flag
857                 this.getLogger().debug(MessageFormat.format("Unmarking product={0} as ordered.", product.getName())); //NOI18N
858                 this.clearSessionAttribute(product, session, SESSION_ORDERED);
859
860                 // Trace message
861                 this.getLogger().trace("EXIT!"); //NOI18N
862         }
863
864         /**
865          * Adds given product to list or throws an exception if name is already found
866          *
867          * @param product Product instance to add
868          */
869         private void addProduct (final Product product) {
870                 // Trace message
871                 this.getLogger().trace(MessageFormat.format("product={0} - CALLED!", product)); //NOI18N
872
873                 // Get all data from it
874                 String name = product.getName();
875
876                 // Is the name already used?
877                 if (this.isProductNameUsed(name)) {
878                         // Something went wrong
879                         throw new IllegalArgumentException(MessageFormat.format("product {0} is already used.", name)); //NOI18N
880                 }
881
882                 // Debug message
883                 this.getLogger().debug(MessageFormat.format("Adding product={0} ...", product)); //NOI18N
884
885                 // Add it
886                 this.products.put(product.getName(), product);
887
888                 // Trace message
889                 this.getLogger().trace("EXIT!"); //NOI18N
890         }
891
892         /**
893          * Clears given parameter for product in session
894          *
895          * @param product Product instance
896          * @param session Session instance
897          * @param parameter Parameter to clear
898          */
899         private void clearSessionAttribute (final Product product, final HttpSession session, final String parameter) {
900                 // Trace message
901                 this.getLogger().trace(MessageFormat.format("produce={0},parameter={1},session={2} - CALLED!", product, parameter, session)); //NOI18N
902
903                 // Clear in session
904                 this.getLogger().debug(MessageFormat.format("Clearing product={0},parameter={1} ...", product.getName(), parameter)); //NOI18N
905                 this.setValueInSession(product, session, parameter, null);
906
907                 // Trace message
908                 this.getLogger().trace("EXIT!"); //NOI18N
909         }
910
911         /**
912          * Fills products list
913          * @todo Very hard-coded stuff ...
914          */
915         private void fillProductsList () throws UnsupportedDatabaseBackendException, SQLException, IOException, BadTokenException {
916                 // Trace message
917                 this.getLogger().trace("CALLED!"); //NOI18N
918
919                 // Get a product frontend
920                 ProductFrontend frontend = new PizzaProductDatabaseFrontend();
921
922                 // Get iterator
923                 Iterator<Product> iterator = frontend.getProducts();
924
925                 // Get all products
926                 while (iterator.hasNext()) {
927                         // Get it
928                         Product product = iterator.next();
929
930                         // Add it
931                         this.addProduct(product);
932                 }
933
934                 // Trace message
935                 this.getLogger().trace("EXIT!"); //NOI18N
936         }
937
938         /**
939          * Some getter for value from session
940          *
941          * @param product Product instance
942          * @param session Session instance
943          * @param attribute Attribute to get value from
944          * @return Value from session
945          */
946         private Object getValueFromSession (final Product product, final HttpSession session, final String attribute) {
947                 // Trace message
948                 this.getLogger().trace(MessageFormat.format("product={0},session={1},attribute={2} - CALLED!", product, session, attribute)); //NOI18N
949
950                 // Init variable
951                 Object value = this.getValueFromSession(session, String.format(HTTP_PARAM_MASK, attribute, product.getName()));
952                 
953                 this.getLogger().debug(MessageFormat.format("product={0},attribute={1},value={2}", product.getName(), attribute, value)); //NOI18N
954
955                 // Trace message
956                 this.getLogger().trace(MessageFormat.format("value={0} - EXIT!", value)); //NOI18N
957
958                 // Return it
959                 return value;
960         }
961
962         /**
963          * Some getter for value from session
964          *
965          * @param session Session instance
966          * @param key Key to get value from
967          * @return Value from session
968          */
969         private Object getValueFromSession (final HttpSession session, final String key) {
970                 // Trace message
971                 this.getLogger().trace(MessageFormat.format("session={0},key={1} - CALLED!", session, key)); //NOI18N
972
973                 // Init value
974                 Object value = null;
975
976                 // Get it synchronized from session
977                 synchronized (session) {
978                         value = session.getAttribute(key);
979                 }
980
981                 // Trace message
982                 this.getLogger().trace(MessageFormat.format("value={0} - EXIT!", value)); //NOI18N
983
984                 // Return it
985                 return value;
986         }
987
988         /**
989          * Handler for choosen (checkbox) from request or session
990          *
991          * @param product Product instance
992          * @param request Request instance
993          * @param session Session instance
994          * @return Amount as string
995          */
996         private String handleChooseFromRequestSession(final Product product, final HttpServletRequest request, final HttpSession session) {
997                 // Trace message
998                 this.getLogger().trace(MessageFormat.format("product={0},request={1},session={2} - CALLED!", product, request, session)); //NOI18N
999
1000                 // Is product and session set?
1001                 if (product == null) {
1002                         // Not set
1003                         throw new NullPointerException("product is null"); //NOI18N
1004                 } else if (request == null) {
1005                         // Not set
1006                         throw new NullPointerException("request is null"); //NOI18N
1007                 } else if (session == null) {
1008                         // Not set
1009                         throw new NullPointerException("session is null"); //NOI18N
1010                 }
1011
1012                 // Init variabke
1013                 Object object;
1014
1015                 // Check request method
1016                 if (!"POST".equals(request.getMethod())) { //NOI18N
1017                         // Not POST, so get from session
1018                         this.getLogger().trace(MessageFormat.format("Calling this.getChooseFromSession({0},{1}) ... - EXIT!", product.getName(), session));
1019                         return this.getChooseFromSession(product, session);
1020                 } else if (this.isProductOrdered(product, session)) {
1021                         // Product is ordered
1022                         this.getLogger().trace(MessageFormat.format("Calling this.getChooseFromSession({0},{1}) ... - EXIT!", product.getName(), session));
1023                         return this.getChooseFromSession(product, session);
1024                 } else if (!this.getChooseFromSession(product, session).isEmpty()) {
1025                         // Found in session
1026                         this.getLogger().trace(MessageFormat.format("Calling this.getChooseFromSession({0},{1}) ... - EXIT!", product.getName(), session));
1027                         return this.getChooseFromSession(product, session);
1028                 }
1029
1030                 // Get reqzest element
1031                 object = request.getParameter(String.format(HTTP_PARAM_MASK, HTTP_PARAM_CHOOSE, product.getName()));
1032                 this.getLogger().debug(MessageFormat.format("product={0},object={1}", product.getName(), object)); //NOI18N
1033
1034                 // Is it null?
1035                 if (object == null) {
1036                         // Unset session
1037                         this.getLogger().debug(MessageFormat.format("Unsetting session for product={0} ...", product.getName())); //NOI18N
1038                         this.clearSessionAttribute(product, session, HTTP_PARAM_CHOOSE);
1039                         this.clearSessionAttribute(product, session, HTTP_PARAM_AMOUNT);
1040
1041                         // Return empty string
1042                         return ""; //NOI18N
1043                 }
1044
1045                 // Then set it in session
1046                 this.setValueInSession(product, session, HTTP_PARAM_CHOOSE, object);
1047
1048                 // Cast to string and return it
1049                 this.getLogger().debug(MessageFormat.format("product={0} - Returning {1} ...", product.getName(), object)); //NOI18N
1050                 return (String) object;
1051         }
1052
1053         /**
1054          * Checks whether given product is already used
1055          *
1056          * @param name Name of product
1057          * @return Whether the given product's name is already used
1058          */
1059         private boolean isProductNameUsed(final String name) {
1060                 // Trace message
1061                 this.getLogger().trace(MessageFormat.format("name={0} - CALLED!", name)); //NOI18N
1062
1063                 // Is it found?
1064                 return this.products.containsKey(name);
1065         }
1066
1067         /**
1068          * Checks if the product ordered?
1069          *
1070          * @param product
1071          * @param session
1072          * @return
1073          */
1074         private boolean isProductOrdered(final Product product, final HttpSession session) {
1075                 // Trace message
1076                 this.getLogger().trace(MessageFormat.format("product={0},session={1} - CALLED!", product, session)); //NOI18N
1077
1078                 // Get session
1079                 Object isOrdered = this.getValueFromSession(product, session, SESSION_ORDERED);
1080                 this.getLogger().debug(MessageFormat.format("product={0},isOrdered={1}", product.getName(), isOrdered)); //NOI18N
1081
1082                 // Return result
1083                 return ("true".equals(isOrdered)); //NOI18N
1084         }
1085
1086         /**
1087          * Somewhat setter in session
1088          *
1089          * @param product Product instance
1090          * @param session Session instance
1091          * @param keyPart Key part to include in final key
1092          * @param value Value to set
1093          */
1094         private void setValueInSession (final Product product, final HttpSession session, final String keyPart, final Object value) {
1095                 // Trace message
1096                 this.getLogger().trace(MessageFormat.format("product={0},session={1},keyPart={2},value={3} - CALLED!", product, session, keyPart, value)); //NOI18N
1097
1098                 // Set it synced
1099                 this.getLogger().debug(MessageFormat.format("Setting value={0} for product={1},keyPart={2}", value, product.getName(), keyPart)); //NOI18N
1100                 this.setValueInSession(session, String.format(HTTP_PARAM_MASK, keyPart, product.getName()), value);
1101
1102                 // Trace message
1103                 this.getLogger().trace("EXIT!"); //NOI18N
1104         }
1105         
1106         /**
1107          * Application starter
1108          */
1109         private void start () {
1110                 // Init bundle
1111                 this.initBundle();
1112
1113                 try {
1114                         // Init properties
1115                         this.initProperties();
1116
1117                         // Fill products list
1118                         this.fillProductsList();
1119                 } catch (final IOException | UnsupportedDatabaseBackendException | SQLException | BadTokenException ex) {
1120                         // Abort here
1121                         this.abortProgramWithException(ex);
1122                 }
1123
1124                 // "Walk" over all products
1125                 for (final Product product : this.getProducts()) {
1126                         // Output data
1127                         this.getLogger().debug(MessageFormat.format("Product {0}, {1}: {2}", product.getName(), product.getTitle(), product.getPrice())); //NOI18N
1128                 }
1129
1130                 // Generate fake Customer instance
1131                 Customer customer = new PizzaServiceCustomer();
1132
1133                 /*
1134                  * Need a least a gender ... :( See, that is why I don't like default
1135                  * constructors, you can easily miss something important and bam! You
1136                  * get an NPE. The fix here is, to have construtors (or factories) which
1137                  * requires all required instances that needs to be set to get a
1138                  * consitent object back.
1139                  */
1140
1141                 // Gender is MALE now
1142                 customer.setGender(Gender.MALE);
1143
1144                 // Init iterator
1145                 Iterator<Map.Entry<Field, Object>> it = null;
1146
1147                 try {
1148                         // Get iterator on all its fields
1149                         it = customer.iterator();
1150                 } catch (final NoSuchMethodException | IllegalAccessException | InvocationTargetException ex) {
1151                         this.abortProgramWithException(ex);
1152                 }
1153
1154                 // Output it
1155                 while ((it instanceof Iterator) && (it.hasNext())) {
1156                         Map.Entry<Field, Object> entry = it.next();
1157                         this.getLogger().debug(MessageFormat.format("entry {0}={1}", entry.getKey(), entry.getValue())); //NOI18N
1158                 }
1159         }
1160 }