]> git.mxchange.org Git - pizzaservice-war.git/blob - src/java/org/mxchange/pizzaapplication/application/PizzaServiceApplication.java
Temporary added call of initBundle()
[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          * Some getter for printable value from session or an empty string for null.
461          *
462          * @param session Session instance
463          * @param key Key to get
464          * @return Value from key, empty string for null
465          */
466         @Override
467         public Object getPrintableValeFromSession (final HttpSession session, final String key) {
468                 // Trace message
469                 this.getLogger().trace(MessageFormat.format("session={0},key={1} - CALLED", session, key)); //NOI18N
470
471                 // Are both parameter not null?
472                 if (session == null) {
473                         // Abort here
474                         throw new NullPointerException("session is null"); //NOI18N
475                 } else  if (key == null) {
476                         // Abort here
477                         throw new NullPointerException("key is null"); //NOI18N
478                 }
479
480                 // Now get it
481                 Object value = this.getValueFromSession(session, key);
482
483                 // Debug message
484                 this.getLogger().debug(MessageFormat.format("value={0}", value)); //NOI18N
485
486                 // Trace message
487                 this.getLogger().trace(MessageFormat.format("Calling this.convertNullToEmpty({0}) ... - EXIT!", value)); //NOI18N
488
489                 // Return actual value
490                 return this.convertNullToEmpty(value);
491         }
492
493         /**
494          * Some "getter" for a an array of all products
495          *
496          * @return Unmarked products
497          */
498         @Override
499         public Product[] getProducts () {
500                 return this.products.values().toArray(new Product[this.products.size()]);
501         }
502
503         /**
504          * Some "getter" for total price of position from request or session.
505          * Single price and amount is multiplyed.
506          *
507          * @param product Product instance
508          * @param request Request instance
509          * @param session Session instance
510          * @return Amount as string
511          */
512         @Override
513         public float getTotalPositionPriceFromRequestSession (final Product product, final HttpServletRequest request, final HttpSession session) {
514                 // Trace message
515                 this.getLogger().trace(MessageFormat.format("product={0},request={1},session={2} - CALLED!", product, request, session)); //NOI18N
516
517                 // Is product and session set?
518                 if (product == null) {
519                         // Not set
520                         throw new NullPointerException("product is null"); //NOI18N
521                 } else if (request == null) {
522                         // Not set
523                         throw new NullPointerException("request is null"); //NOI18N
524                 } else if (session == null) {
525                         // Not set
526                         throw new NullPointerException("session is null"); //NOI18N
527                 }
528
529                 // Get choosen
530                 this.getLogger().debug(MessageFormat.format("Calling handleChooseFromRequestSession({0},{1},{2}) ...", product.getName(), request, session)); //NOI18N
531                 String choosen = this.handleChooseFromRequestSession(product, request, session);
532                 this.getLogger().debug(MessageFormat.format("product={0},choosen={1}", product.getName(), choosen)); //NOI18N
533
534                 // Must not be null
535                 assert(choosen instanceof String): "choosen is null"; //NOI18N
536
537                 // Is it set?
538                 if (choosen.isEmpty()) {
539                         // Is empty
540                         this.getLogger().debug(MessageFormat.format("product={0},choosen={1} - returning zero ...", product.getName(), choosen)); //NOI18N
541                         return 0.00f;
542                 }
543
544                 // Get amount
545                 String amount = this.handleAmountFromRequestSession(product, request, session);
546                 this.getLogger().debug(MessageFormat.format("product={0},amount={1}", product.getName(), amount)); //NOI18N
547
548                 // Must not be null
549                 assert(amount instanceof String): "amount is null"; //NOI18N
550
551                 // Is it empty?
552                 if (amount.isEmpty() || "0".equals(amount)) { //NOI18N
553                         // Is empty
554                         this.getLogger().debug(MessageFormat.format("product={0},amount={1} - returning zero ...", product.getName(), amount)); //NOI18N
555                         return 0.00f;
556                 }
557
558                 // Init variable
559                 Integer value = null;
560
561                 // Try it
562                 try {
563                         // Get amount as integer
564                         value = Integer.valueOf(amount);
565                 } catch (final NumberFormatException e) {
566                         // Bat input
567                         throw new IllegalArgumentException(e);
568                 }
569
570                 // Calculate price
571                 float price = (product.getPrice() * value);
572
573                 // Trace message
574                 this.getLogger().trace(MessageFormat.format("product={0},price={1} - EXIT!", product.getName(), price)); //NOI18N
575
576                 // Then multiply it with price
577                 return price;
578         }
579
580         /**
581          * Gets an array of products from product iterator and unmarks them as ordered
582          *
583          * @param session HttpSession instance
584          * @return Unmarked products
585          */
586         @Override
587         public Product[] getUnmarkedProducts (final HttpSession session) {
588                 // Init array
589                 Product[] array = this.getProducts();
590
591                 // Unmark are all as ordered
592                 for (final Product product : array) {
593                         this.unmarkProductAsOrdered(product, session);
594                 }
595
596                 // Return finished array
597                 return array;
598         }
599
600         /**
601          * Handler for amount from request or session
602          *
603          * @param product Product instance
604          * @param request Request instance
605          * @param session Session instance
606          * @return Amount as string
607          */
608         @Override
609         public String handleAmountFromRequestSession (final Product product, final HttpServletRequest request, final HttpSession session) {
610                 // Trace message
611                 this.getLogger().trace(MessageFormat.format("product={0},request={1},session={2} - CALLED!", product, request, session)); //NOI18N
612
613                 // Is product and session set?
614                 if (product == null) {
615                         // Not set
616                         throw new NullPointerException("product is null"); //NOI18N
617                 } else if (request == null) {
618                         // Not set
619                         throw new NullPointerException("request is null"); //NOI18N
620                 } else if (session == null) {
621                         // Not set
622                         throw new NullPointerException("session is null"); //NOI18N
623                 }
624
625                 // Init variabke
626                 Object object;
627
628                 // Check request method
629                 if (!"POST".equals(request.getMethod())) { //NOI18N
630                         // Not POST, so get from session
631                         return this.getAmountFromSession(product, session);
632                 } else if (this.handleChooseFromRequestSession(product, request, session).isEmpty()) {
633                         // Not choosen
634                         this.clearSessionAttribute(product, session, HTTP_PARAM_AMOUNT);
635                         this.getLogger().debug(MessageFormat.format("Unsetting for product={0} in session, returning zero ...", product.getName())); //NOI18N
636                         return "0"; //NOI18N
637                 }
638
639                 // Get attribute from request
640                 object = request.getParameter(String.format(HTTP_PARAM_MASK, HTTP_PARAM_AMOUNT, product.getName()));
641
642                 // Is it set?
643                 if (object instanceof String) {
644                         // Try to parse it to integer
645                         try {
646                                 Integer value = Integer.valueOf((String) object);
647                         } catch (final NumberFormatException ex) {
648                                 // Not valid input
649                                 this.getLogger().warn(ex);
650                                 return "0"; //NOI18N
651                         }
652
653                         // Then set it in session
654                         this.setValueInSession(product, session, HTTP_PARAM_AMOUNT, object);
655
656                         // And return it
657                         return (String) object;
658                 }
659
660                 // Trace message
661                 this.getLogger().trace("Calling getAmountFromSession() ..."); //NOI18N
662
663                 // Get attribute from session
664                 return this.getAmountFromSession(product, session);
665         }
666
667         /**
668          * Checks whether the given product is choosen, request overules session.
669          *
670          * @param product Product instance
671          * @param request Request instance
672          * @param session Session instance
673          * @return Whether the product is choosen
674          */
675         @Override
676         public boolean isProductChoosen (final Product product, final HttpServletRequest request, final HttpSession session) {
677                 // Trace message
678                 this.getLogger().trace(MessageFormat.format("product={0},request={1},session={2} - CALLED!", product, request, session)); //NOI18N
679
680                 // Is product and session set?
681                 if (product == null) {
682                         // Not set
683                         throw new NullPointerException("product is null"); //NOI18N
684                 } else if (request == null) {
685                         // Not set
686                         throw new NullPointerException("request is null"); //NOI18N
687                 } else if (session == null) {
688                         // Not set
689                         throw new NullPointerException("session is null"); //NOI18N
690                 }
691
692                 // Get choosen
693                 this.getLogger().debug(MessageFormat.format("Calling handleChooseFromRequestSession({0},{1},{2}) ...", product.getName(), request, session)); //NOI18N
694                 String choosen = this.handleChooseFromRequestSession(product, request, session);
695                 this.getLogger().debug(MessageFormat.format("product={0},choosen={1}", product.getName(), choosen)); //NOI18N
696
697                 // Must not be null
698                 assert(choosen instanceof String): "choosen is null"; //NOI18N
699
700                 // Is it not choosen?
701                 if (choosen.isEmpty()) {
702                         // Not choosen
703                         return false;
704                 }
705
706                 // Get amount
707                 String amount = this.handleAmountFromRequestSession(product, request, session);
708
709                 // Must not be null
710                 assert(amount instanceof String): "amount is not set"; //NOI18N
711
712                 // Trace message
713                 this.getLogger().trace(MessageFormat.format("amount={0} - EXIT!", amount)); //NOI18N
714
715                 // Must not be empty and not 0
716                 return (!amount.isEmpty() && !"0".equals(amount)); //NOI18N
717         }
718
719         /**
720          * Marks given product as choosen in session
721          *
722          * @param product Product to mark as ordered
723          * @param session Session instance
724          */
725         @Override
726         public void markProductAsChoosen (final Product product, final HttpSession session) {
727                 // Trace message
728                 this.getLogger().trace(MessageFormat.format("product={0},session={1} - CALLED!", product, session)); //NOI18N
729
730                 // Is product and session set?
731                 if (product == null) {
732                         // Not set
733                         throw new NullPointerException("product is null"); //NOI18N
734                 } else if (session == null) {
735                         // Not set
736                         throw new NullPointerException("session is null"); //NOI18N
737                 }
738
739                 // Mark it as ordered by setting flag
740                 this.getLogger().debug(MessageFormat.format("Marking product={0} as choosen.", product.getName())); //NOI18N
741                 this.setValueInSession(product, session, HTTP_PARAM_CHOOSE, "1"); //NOI18N
742
743                 // Trace message
744                 this.getLogger().trace("EXIT!"); //NOI18N
745         }
746
747         /**
748          * Marks given product as ordered in session
749          *
750          * @param product Product to mark as ordered
751          * @param session Session instance
752          */
753         @Override
754         public void markProductAsOrdered (final Product product, final HttpSession session) {
755                 // Trace message
756                 this.getLogger().trace(MessageFormat.format("product={0},session={1} - CALLED!", product, session)); //NOI18N
757
758                 // Is product and session set?
759                 if (product == null) {
760                         // Not set
761                         throw new NullPointerException("product is null"); //NOI18N
762                 } else if (session == null) {
763                         // Not set
764                         throw new NullPointerException("session is null"); //NOI18N
765                 }
766
767                 // Mark it as ordered by setting flag
768                 this.getLogger().debug(MessageFormat.format("Marking product={0} as ordered.", product.getName())); //NOI18N
769                 this.setValueInSession(product, session, SESSION_ORDERED, "true"); //NOI18N
770
771                 // Trace message
772                 this.getLogger().trace("EXIT!"); //NOI18N
773         }
774
775         /**
776          * Somewhat setter in session
777          *
778          * @param session Session instance
779          * @param key Session key to set
780          * @param value Value to set
781          */
782         @Override
783         public void setValueInSession (final HttpSession session, final String key, final Object value) {
784                 // Trace message
785                 this.getLogger().trace(MessageFormat.format("session={0},key={1},value={2} - CALLED!", session, key, value)); //NOI18N
786
787                 synchronized(session) {
788                         // Set it synced
789                         session.setAttribute(key, value);
790                 }
791
792                 // Trace message
793                 this.getLogger().trace("EXIT!"); //NOI18N
794         }
795
796         /**
797          * Unmarks given product as choosen in session
798          *
799          * @param product Product to unmark as choosen
800          * @param session Session instance
801          */
802         @Override
803         public void unmarkProductAsChoosen (final Product product, final HttpSession session) {
804                 // Trace message
805                 this.getLogger().trace(MessageFormat.format("product={0},session={1} - CALLED!", product, session)); //NOI18N
806
807                 // Is product and session set?
808                 if (product == null) {
809                         // Not set
810                         throw new NullPointerException("product is null"); //NOI18N
811                 } else if (session == null) {
812                         // Not set
813                         throw new NullPointerException("session is null"); //NOI18N
814                 }
815
816                 // Mark it as ordered by setting flag
817                 this.getLogger().debug(MessageFormat.format("Unmarking product={0} as choosen.", product.getName())); //NOI18N
818                 this.clearSessionAttribute(product, session, HTTP_PARAM_CHOOSE);
819
820                 // Trace message
821                 this.getLogger().trace("EXIT!"); //NOI18N
822         }
823
824         /**
825          * Unmarks given product as ordered in session
826          *
827          * @param product Product to unmark as ordered
828          * @param session Session instance
829          */
830         @Override
831         public void unmarkProductAsOrdered (final Product product, final HttpSession session) {
832                 // Trace message
833                 this.getLogger().trace(MessageFormat.format("product={0},session={1} - CALLED!", product, session)); //NOI18N
834
835                 // Is product and session set?
836                 if (product == null) {
837                         // Not set
838                         throw new NullPointerException("product is null"); //NOI18N
839                 } else if (session == null) {
840                         // Not set
841                         throw new NullPointerException("session is null"); //NOI18N
842                 }
843
844                 // Mark it as ordered by setting flag
845                 this.getLogger().debug(MessageFormat.format("Unmarking product={0} as ordered.", product.getName())); //NOI18N
846                 this.clearSessionAttribute(product, session, SESSION_ORDERED);
847
848                 // Trace message
849                 this.getLogger().trace("EXIT!"); //NOI18N
850         }
851
852         /**
853          * Adds given product to list or throws an exception if name is already found
854          *
855          * @param product Product instance to add
856          */
857         private void addProduct (final Product product) {
858                 // Trace message
859                 this.getLogger().trace(MessageFormat.format("product={0} - CALLED!", product)); //NOI18N
860
861                 // Get all data from it
862                 String name = product.getName();
863
864                 // Is the name already used?
865                 if (this.isProductNameUsed(name)) {
866                         // Something went wrong
867                         throw new IllegalArgumentException(MessageFormat.format("product {0} is already used.", name)); //NOI18N
868                 }
869
870                 // Debug message
871                 this.getLogger().debug(MessageFormat.format("Adding product={0} ...", product)); //NOI18N
872
873                 // Add it
874                 this.products.put(product.getName(), product);
875
876                 // Trace message
877                 this.getLogger().trace("EXIT!"); //NOI18N
878         }
879
880         /**
881          * Clears given parameter for product in session
882          *
883          * @param product Product instance
884          * @param session Session instance
885          * @param parameter Parameter to clear
886          */
887         private void clearSessionAttribute (final Product product, final HttpSession session, final String parameter) {
888                 // Trace message
889                 this.getLogger().trace(MessageFormat.format("produce={0},parameter={1},session={2} - CALLED!", product, parameter, session)); //NOI18N
890
891                 // Clear in session
892                 this.getLogger().debug(MessageFormat.format("Clearing product={0},parameter={1} ...", product.getName(), parameter)); //NOI18N
893                 this.setValueInSession(product, session, parameter, null);
894
895                 // Trace message
896                 this.getLogger().trace("EXIT!"); //NOI18N
897         }
898
899         /**
900          * Fills products list
901          * @todo Very hard-coded stuff ...
902          */
903         private void fillProductsList () throws UnsupportedDatabaseBackendException, SQLException, IOException, BadTokenException {
904                 // Trace message
905                 this.getLogger().trace("CALLED!"); //NOI18N
906
907                 // Get a product frontend
908                 ProductFrontend frontend = new PizzaProductDatabaseFrontend();
909
910                 // Get iterator
911                 Iterator<Product> iterator = frontend.getProducts();
912
913                 // Get all products
914                 while (iterator.hasNext()) {
915                         // Get it
916                         Product product = iterator.next();
917
918                         // Add it
919                         this.addProduct(product);
920                 }
921
922                 // Trace message
923                 this.getLogger().trace("EXIT!"); //NOI18N
924         }
925
926         /**
927          * Some getter for value from session
928          *
929          * @param product Product instance
930          * @param session Session instance
931          * @param attribute Attribute to get value from
932          * @return Value from session
933          */
934         private Object getValueFromSession (final Product product, final HttpSession session, final String attribute) {
935                 // Trace message
936                 this.getLogger().trace(MessageFormat.format("product={0},session={1},attribute={2} - CALLED!", product, session, attribute)); //NOI18N
937
938                 // Init variable
939                 Object value = this.getValueFromSession(session, String.format(HTTP_PARAM_MASK, attribute, product.getName()));
940                 
941                 this.getLogger().debug(MessageFormat.format("product={0},attribute={1},value={2}", product.getName(), attribute, value)); //NOI18N
942
943                 // Trace message
944                 this.getLogger().trace(MessageFormat.format("value={0} - EXIT!", value)); //NOI18N
945
946                 // Return it
947                 return value;
948         }
949
950         /**
951          * Some getter for value from session
952          *
953          * @param session Session instance
954          * @param key Key to get value from
955          * @return Value from session
956          */
957         private Object getValueFromSession (final HttpSession session, final String key) {
958                 // Trace message
959                 this.getLogger().trace(MessageFormat.format("session={0},key={1} - CALLED!", session, key)); //NOI18N
960
961                 // Init value
962                 Object value = null;
963
964                 // Get it synchronized from session
965                 synchronized (session) {
966                         value = session.getAttribute(key);
967                 }
968
969                 // Trace message
970                 this.getLogger().trace(MessageFormat.format("value={0} - EXIT!", value)); //NOI18N
971
972                 // Return it
973                 return value;
974         }
975
976         /**
977          * Handler for choosen (checkbox) from request or session
978          *
979          * @param product Product instance
980          * @param request Request instance
981          * @param session Session instance
982          * @return Amount as string
983          */
984         private String handleChooseFromRequestSession(final Product product, final HttpServletRequest request, final HttpSession session) {
985                 // Trace message
986                 this.getLogger().trace(MessageFormat.format("product={0},request={1},session={2} - CALLED!", product, request, session)); //NOI18N
987
988                 // Is product and session set?
989                 if (product == null) {
990                         // Not set
991                         throw new NullPointerException("product is null"); //NOI18N
992                 } else if (request == null) {
993                         // Not set
994                         throw new NullPointerException("request is null"); //NOI18N
995                 } else if (session == null) {
996                         // Not set
997                         throw new NullPointerException("session is null"); //NOI18N
998                 }
999
1000                 // Init variabke
1001                 Object object;
1002
1003                 // Check request method
1004                 if (!"POST".equals(request.getMethod())) { //NOI18N
1005                         // Not POST, so get from session
1006                         this.getLogger().trace(MessageFormat.format("Calling this.getChooseFromSession({0},{1}) ... - EXIT!", product.getName(), session));
1007                         return this.getChooseFromSession(product, session);
1008                 } else if (this.isProductOrdered(product, session)) {
1009                         // Product is ordered
1010                         this.getLogger().trace(MessageFormat.format("Calling this.getChooseFromSession({0},{1}) ... - EXIT!", product.getName(), session));
1011                         return this.getChooseFromSession(product, session);
1012                 } else if (!this.getChooseFromSession(product, session).isEmpty()) {
1013                         // Found in session
1014                         this.getLogger().trace(MessageFormat.format("Calling this.getChooseFromSession({0},{1}) ... - EXIT!", product.getName(), session));
1015                         return this.getChooseFromSession(product, session);
1016                 }
1017
1018                 // Get reqzest element
1019                 object = request.getParameter(String.format(HTTP_PARAM_MASK, HTTP_PARAM_CHOOSE, product.getName()));
1020                 this.getLogger().debug(MessageFormat.format("product={0},object={1}", product.getName(), object)); //NOI18N
1021
1022                 // Is it null?
1023                 if (object == null) {
1024                         // Unset session
1025                         this.getLogger().debug(MessageFormat.format("Unsetting session for product={0} ...", product.getName())); //NOI18N
1026                         this.clearSessionAttribute(product, session, HTTP_PARAM_CHOOSE);
1027                         this.clearSessionAttribute(product, session, HTTP_PARAM_AMOUNT);
1028
1029                         // Return empty string
1030                         return ""; //NOI18N
1031                 }
1032
1033                 // Then set it in session
1034                 this.setValueInSession(product, session, HTTP_PARAM_CHOOSE, object);
1035
1036                 // Cast to string and return it
1037                 this.getLogger().debug(MessageFormat.format("product={0} - Returning {1} ...", product.getName(), object)); //NOI18N
1038                 return (String) object;
1039         }
1040
1041         /**
1042          * Checks whether given product is already used
1043          *
1044          * @param name Name of product
1045          * @return Whether the given product's name is already used
1046          */
1047         private boolean isProductNameUsed(final String name) {
1048                 // Trace message
1049                 this.getLogger().trace(MessageFormat.format("name={0} - CALLED!", name)); //NOI18N
1050
1051                 // Is it found?
1052                 return this.products.containsKey(name);
1053         }
1054
1055         /**
1056          * Checks if the product ordered?
1057          *
1058          * @param product
1059          * @param session
1060          * @return
1061          */
1062         private boolean isProductOrdered(final Product product, final HttpSession session) {
1063                 // Trace message
1064                 this.getLogger().trace(MessageFormat.format("product={0},session={1} - CALLED!", product, session)); //NOI18N
1065
1066                 // Get session
1067                 Object isOrdered = this.getValueFromSession(product, session, SESSION_ORDERED);
1068                 this.getLogger().debug(MessageFormat.format("product={0},isOrdered={1}", product.getName(), isOrdered)); //NOI18N
1069
1070                 // Return result
1071                 return ("true".equals(isOrdered)); //NOI18N
1072         }
1073
1074         /**
1075          * Somewhat setter in session
1076          *
1077          * @param product Product instance
1078          * @param session Session instance
1079          * @param keyPart Key part to include in final key
1080          * @param value Value to set
1081          */
1082         private void setValueInSession (final Product product, final HttpSession session, final String keyPart, final Object value) {
1083                 // Trace message
1084                 this.getLogger().trace(MessageFormat.format("product={0},session={1},keyPart={2},value={3} - CALLED!", product, session, keyPart, value)); //NOI18N
1085
1086                 // Set it synced
1087                 this.getLogger().debug(MessageFormat.format("Setting value={0} for product={1},keyPart={2}", value, product.getName(), keyPart)); //NOI18N
1088                 this.setValueInSession(session, String.format(HTTP_PARAM_MASK, keyPart, product.getName()), value);
1089
1090                 // Trace message
1091                 this.getLogger().trace("EXIT!"); //NOI18N
1092         }
1093         
1094         /**
1095          * Application starter
1096          */
1097         private void start () {
1098                 // Init bundle
1099                 this.initBundle();
1100
1101                 try {
1102                         // Init properties
1103                         this.initProperties();
1104
1105                         // Fill products list
1106                         this.fillProductsList();
1107                 } catch (final IOException | UnsupportedDatabaseBackendException | SQLException | BadTokenException ex) {
1108                         // Abort here
1109                         this.abortProgramWithException(ex);
1110                 }
1111
1112                 // "Walk" over all products
1113                 for (final Product product : this.getProducts()) {
1114                         // Output data
1115                         this.getLogger().debug(MessageFormat.format("Product {0}, {1}: {2}", product.getName(), product.getTitle(), product.getPrice())); //NOI18N
1116                 }
1117
1118                 // Generate fake Customer instance
1119                 Customer customer = new PizzaServiceCustomer();
1120
1121                 /*
1122                  * Need a least a gender ... :( See, that is why I don't like default
1123                  * constructors, you can easily miss something important and bam! You
1124                  * get an NPE. The fix here is, to have construtors (or factories) which
1125                  * requires all required instances that needs to be set to get a
1126                  * consitent object back.
1127                  */
1128
1129                 // Gender is MALE now
1130                 customer.setGender(Gender.MALE);
1131
1132                 // Init iterator
1133                 Iterator<Map.Entry<Field, Object>> it = null;
1134
1135                 try {
1136                         // Get iterator on all its fields
1137                         it = customer.iterator();
1138                 } catch (final NoSuchMethodException | IllegalAccessException | InvocationTargetException ex) {
1139                         this.abortProgramWithException(ex);
1140                 }
1141
1142                 // Output it
1143                 while ((it instanceof Iterator) && (it.hasNext())) {
1144                         Map.Entry<Field, Object> entry = it.next();
1145                         this.getLogger().debug(MessageFormat.format("entry {0}={1}", entry.getKey(), entry.getValue())); //NOI18N
1146                 }
1147         }
1148 }