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