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