]> git.mxchange.org Git - pizzaservice-war.git/blob - src/java/org/mxchange/pizzaapplication/application/PizzaServiceApplication.java
Decentralized jcore.
[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.io.UnsupportedEncodingException;
21 import java.lang.reflect.Field;
22 import java.lang.reflect.InvocationTargetException;
23 import java.sql.SQLException;
24 import java.text.MessageFormat;
25 import java.util.Iterator;
26 import java.util.Map;
27 import javax.servlet.ServletContext;
28 import javax.servlet.ServletException;
29 import javax.servlet.http.HttpServletRequest;
30 import javax.servlet.http.HttpServletResponse;
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.CorruptedDatabaseFileException;
35 import org.mxchange.jcore.exceptions.UnsupportedDatabaseBackendException;
36 import org.mxchange.pizzaapplication.BasePizzaServiceSystem;
37 import org.mxchange.pizzaapplication.category.Category;
38 import org.mxchange.pizzaapplication.customer.Customer;
39 import org.mxchange.pizzaapplication.customer.PizzaServiceCustomer;
40 import org.mxchange.pizzaapplication.database.category.PizzaCategoryDatabaseConstants;
41 import org.mxchange.pizzaapplication.database.frontend.category.CategoryFrontend;
42 import org.mxchange.pizzaapplication.database.frontend.category.PizzaCategoryDatabaseFrontend;
43 import org.mxchange.pizzaapplication.database.frontend.product.PizzaProductDatabaseFrontend;
44 import org.mxchange.pizzaapplication.database.frontend.product.ProductFrontend;
45 import org.mxchange.pizzaapplication.database.product.PizzaProductDatabaseConstants;
46 import org.mxchange.pizzaapplication.exceptions.CategoryTitleAlreadyUsedException;
47 import org.mxchange.pizzaapplication.exceptions.ProductTitleAlreadyUsedException;
48 import org.mxchange.pizzaapplication.product.Product;
49
50 /**
51  * Main application class
52  *
53  * @author Roland Haeder
54  */
55 public class PizzaServiceApplication extends BasePizzaServiceSystem implements PizzaApplication {
56         /**
57          * Main title
58          */
59         public static final String MAIN_TITLE = "Pizza-Service";
60
61         /**
62          * Frontend for products
63          */
64         private ProductFrontend productFrontend;
65
66         /**
67          * Frontend for categories
68          */
69         private CategoryFrontend categoryFrontend;
70
71         /**
72          * Some singleton getter for this instance. If the instance is not set in
73          * given application, it will be created.
74          *
75          * @param context Servlet context
76          * @return This instance
77          * @throws javax.servlet.ServletException If object is not set correctly
78          */
79         public static final PizzaApplication getInstance (final ServletContext context) throws ServletException {
80                 // Check application instance
81                 if (context == null) {
82                         // Not set
83                         throw new NullPointerException("application is null"); //NOI18N
84                 }
85
86                 // Init instance
87                 PizzaApplication instance = null;
88
89                 // Get instance from servlet application (aka. "application scope")
90                 Object object = context.getAttribute("app"); //NOI18N
91
92                 // Is it set?
93                 if (object instanceof PizzaApplication) {
94                         // Instance is set, so casting should work
95                         instance = (PizzaApplication) object;
96                 } else if (object instanceof Object) {
97                         // Not correct instance
98                         throw new ServletException("app is not set correctly"); //NOI18N
99                 } else {
100                         try {
101                                 // "service" is null, so initialize it
102                                 instance = new PizzaServiceApplication(context);
103                         } catch (final UnsupportedDatabaseBackendException | SQLException | IOException | BadTokenException ex) {
104                                 throw new ServletException(ex);
105                         }
106
107                         // And set it here
108                         context.setAttribute("app", instance); //NOI18N
109                 }
110
111                 // Trace message
112                 instance.getLogger().trace(MessageFormat.format("instance={0} - EXIT!", instance)); //NOI18N
113
114                 // Return it
115                 return instance;
116         }
117
118         /**
119          * For debugging purpose
120          *
121          * @param args Arguments
122          */
123         public static void main (String[] args) {
124                 // Get instance and start it
125                 new PizzaServiceApplication().start();
126         }
127
128         /**
129          * Constructor with servet configuration
130          *
131          * @param context Servlet context
132          */
133         private PizzaServiceApplication (final ServletContext context) throws UnsupportedDatabaseBackendException, SQLException, IOException, BadTokenException {
134                 // Temporary initialize default bundle
135                 // @TODO The JSF may have better internatialization support
136                 this.initBundle();
137
138                 // Initialize properties from config
139                 this.initProperties(context);
140
141                 // Init database frontends
142                 this.initDatabaseFrontends();
143         }
144
145         /**
146          * Default constructor
147          */
148         private PizzaServiceApplication () {
149         }
150
151         /**
152          * Calculates total amount of all choosen products
153          *
154          * @param request Request instance
155          * @param session Session instance
156          * @return Total amount of all choosen products
157          */
158         @Override
159         public int calculateTotalAmount (final HttpServletRequest request, final HttpSession session) throws ServletException {
160                 // Trace message
161                 this.getLogger().trace(MessageFormat.format("request={0},session={1} - CALLED!", request, session)); //NOI18N
162
163                 // Is product and session set?
164                 if (request == null) {
165                         // Not set
166                         throw new NullPointerException("request is null"); //NOI18N
167                 } else if (session == null) {
168                         // Not set
169                         throw new NullPointerException("session is null"); //NOI18N
170                 }
171
172                 // Init/declare total price and iterator
173                 int totalAmount = 0;
174                 Iterator<Product> iterator = this.getAvailableProducts();
175
176                 // "Walk" over all products
177                 while (iterator.hasNext()) {
178                         // Get next product
179                         Product product = iterator.next();
180
181                         // Is this choosen?
182                         if (this.isProductChoosen(product, request, session)) {
183                                 // Then add ordered amount
184                                 this.getLogger().debug(MessageFormat.format("Counting {0} ...", product.getId())); //NOI18N
185
186                                 // Getting amount
187                                 String amount = this.getAmountFromSession(product, session);
188
189                                 // Add it up
190                                 this.getLogger().debug(MessageFormat.format("amount={0}", amount)); //NOI18N
191                                 totalAmount += Integer.valueOf(amount);
192                         }
193                         this.getLogger().debug(MessageFormat.format("product={0},totalAmount={1}", product.getId(), totalAmount)); //NOI18N
194                 }
195
196                 // Trace message
197                 this.getLogger().trace(MessageFormat.format("totalAmount={0} - EXIT!", totalAmount)); //NOI18N
198
199                 // Return total price
200                 return totalAmount;
201         }
202
203         /**
204          * Calculates total price of all choosen products
205          *
206          * @param request Request instance
207          * @param session Session instance
208          * @return Total price of all choosen products
209          */
210         @Override
211         public float calculateTotalPrice (final HttpServletRequest request, final HttpSession session) throws ServletException {
212                 // Trace message
213                 this.getLogger().trace(MessageFormat.format("request={0},session={1} - CALLED!", request, session)); //NOI18N
214
215                 // Is product and session set?
216                 if (request == null) {
217                         // Not set
218                         throw new NullPointerException("request is null"); //NOI18N
219                 } else if (session == null) {
220                         // Not set
221                         throw new NullPointerException("session is null"); //NOI18N
222                 }
223
224                 // Init total price
225                 float totalPrice = 0.00f;
226
227                 // Get iterator
228                 Iterator<Product> iterator = this.getAvailableProducts();
229
230                 // "Walk" over all products
231                 while (iterator.hasNext()) {
232                         // Get next product
233                         Product product = iterator.next();
234
235                         // Is this choosen?
236                         if (this.isProductChoosen(product, request, session)) {
237                                 // Then add product's total price
238                                 this.getLogger().debug(MessageFormat.format("Calling getTotalPositionPriceFromRequestSession({0},request,session) ...", product.getId())); //NOI18N
239                                 totalPrice += this.getTotalPositionPriceFromRequestSession(product, request, session);
240                         }
241                         this.getLogger().debug(MessageFormat.format("product={0},totalPrice={1}", product.getId(), totalPrice)); //NOI18N
242                 }
243
244                 // Trace message
245                 this.getLogger().trace(MessageFormat.format(" totalPrice={0} - EXIT!", totalPrice)); //NOI18N
246
247                 // Return total price
248                 return totalPrice;
249         }
250
251         @Override
252         public void doBootstrap () {
253                 throw new UnsupportedOperationException("Not supported yet."); //NOI18N
254         }
255
256         @Override
257         public void doMainLoop () {
258                 throw new UnsupportedOperationException("Not supported yet."); //NOI18N
259         }
260
261         @Override
262         public void doShutdown () {
263                 throw new UnsupportedOperationException("Not supported yet."); //NOI18N
264         }
265
266         /**
267          * Some "getter" for amount from session
268          *
269          * @param product Product instance
270          * @param session Session instance
271          * @return Amount as string
272          */
273         @Override
274         public String getAmountFromSession (final Product product, final HttpSession session) {
275                 // Trace message
276                 this.getLogger().trace(MessageFormat.format("product={0},session={1} - CALLED!", product, session)); //NOI18N
277
278                 // Is product and session set?
279                 if (product == null) {
280                         // Not set
281                         throw new NullPointerException("product is null"); //NOI18N
282                 } else if (session == null) {
283                         // Not set
284                         throw new NullPointerException("session is null"); //NOI18N
285                 }
286
287                 // Get attribute
288                 Object object = this.getValueFromSession(product, session, HTTP_PARAM_AMOUNT);
289
290                 // Is the object null?
291                 if (object == null) {
292                         // Trace message
293                         this.getLogger().trace("Returning 0 - EXIT!"); //NOI18N
294
295                         // Not found
296                         return "0"; //NOI18N
297                 }
298
299                 // Trace message
300                 this.getLogger().trace(MessageFormat.format("object={0} - EXIT!", object)); //NOI18N
301
302                 // Cast to string and return it
303                 return (String) object;
304         }
305
306         /**
307          * Some "getter" for HTML code 'checked="checked"' if the product is choosen
308          * 
309          * @param product Product instance
310          * @param request Request instance
311          * @param session Session instance
312          * @return Whether the product is choosen
313          */
314         @Override
315         public String getCheckedHtmlFromProduct (final Product product, final HttpServletRequest request, final HttpSession session) {
316                 // Trace message
317                 this.getLogger().trace(MessageFormat.format("product={0},request={1},session={2} - CALLED!", product, request, session)); //NOI18N
318
319                 // Is product and session set?
320                 if (product == null) {
321                         // Not set
322                         throw new NullPointerException("product is null"); //NOI18N
323                 } else if (request == null) {
324                         // Not set
325                         throw new NullPointerException("request is null"); //NOI18N
326                 } else if (session == null) {
327                         // Not set
328                         throw new NullPointerException("session is null"); //NOI18N
329                 }
330
331                 // First let's check if the product is choosen
332                 if (this.isProductChoosen(product, request, session)) {
333                         // Trace message
334                         this.getLogger().trace("Returning checked=\"checked\" - EXIT!"); //NOI18N
335
336                         // Is choosen
337                         return "checked=\"checked\""; //NOI18N
338                 } else {
339                         // Trace message
340                         this.getLogger().trace("Returning empty string - EXIT!"); //NOI18N
341
342                         // Not choosen
343                         return ""; //NOI18N
344                 }
345         }
346
347         /**
348          * Some "getter" for choose from session
349          * 
350          * @param product Product instance
351          * @param session Session instance
352          * @return Choose as string
353          */
354         @Override
355         public String getChooseFromSession (final Product product, final HttpSession session) {
356                 // Trace message
357                 this.getLogger().trace(MessageFormat.format("product={0},session={1} - CALLED!", product, session)); //NOI18N
358
359                 // Is product and session set?
360                 if (product == null) {
361                         // Not set
362                         throw new NullPointerException("product is null"); //NOI18N
363                 } else if (session == null) {
364                         // Not set
365                         throw new NullPointerException("session is null"); //NOI18N
366                 }
367
368                 // Get attribute
369                 Object object = this.getValueFromSession(product, session, HTTP_PARAM_CHOOSE);
370
371                 // Is the object null?
372                 if (object == null) {
373                         // Not found
374                         this.getLogger().debug(MessageFormat.format("Returning empty string for product={0} ...", product.getId())); //NOI18N
375                         return ""; //NOI18N
376                 }
377
378                 // Trace message
379                 this.getLogger().trace(MessageFormat.format("object={0} - CALLED!", object)); //NOI18N
380
381                 // Cast to string and return it
382                 return (String) object;
383         }
384
385         /**
386          * Some "getter" for HTML code 'disabled="disabled"' for e.g. submit buttons
387          *
388          * @param request Request instance
389          * @param session Session instance
390          * @return Whether the product is choosen
391          */
392         @Override
393         public String getDisabledHtmlFromSession (final HttpServletRequest request, final HttpSession session) throws ServletException {
394                 // Trace message
395                 this.getLogger().trace(MessageFormat.format("request={0},session={1} - CALLED!", request, session)); //NOI18N
396
397                 // Is product and session set?
398                 if (request == null) {
399                         // Not set
400                         throw new NullPointerException("request is null"); //NOI18N
401                 } else if (session == null) {
402                         // Not set
403                         throw new NullPointerException("session is null"); //NOI18N
404                 }
405
406                 // Get "enabled" from request scope
407                 Boolean enabled = Boolean.parseBoolean((String) request.getAttribute("enabled")); //NOI18N
408
409                 // Debug message
410                 this.getLogger().debug(MessageFormat.format("enabled={0}", enabled)); //NOI18N
411
412                 // Is something selected?
413                 if ((enabled) || (this.calculateTotalAmount(request, session) > 0)) {
414                         // Trace message
415                         this.getLogger().trace("Returning empty string - EXIT!"); //NOI18N
416
417                         // Something has been choosen
418                         return ""; //NOI18N
419                 } else {
420                         // Trace message
421                         this.getLogger().trace("Returning disabled=\"disabled\" - EXIT!"); //NOI18N
422
423                         // Nothing choosen yet
424                         return "disabled=\"disabled\""; //NOI18N
425                 }
426         }
427
428         /**
429          * Some "getter" for choosen (checkbox) from session
430          *
431          * @param product Product instance
432          * @param request Request instance
433          * @param session Session instance
434          * @return Amount as string
435          */
436         @Override
437         public String getPrintableChoosenFromRequestSession (final Product product, final HttpServletRequest request, final HttpSession session) {
438                 // Trace message
439                 this.getLogger().trace(MessageFormat.format("product={0},request={1},session={2} - CALLED!", product, request, session)); //NOI18N
440
441                 // Is product and session set?
442                 if (product == null) {
443                         // Not set
444                         throw new NullPointerException("product is null"); //NOI18N
445                 } else if (request == null) {
446                         // Not set
447                         throw new NullPointerException("request is null"); //NOI18N
448                 } else if (session == null) {
449                         // Not set
450                         throw new NullPointerException("session is null"); //NOI18N
451                 }
452
453                 // Get element
454                 this.getLogger().debug(MessageFormat.format("Calling handleChooseFromRequestSession({0},{1},{2}) ...", product.getId(), request, session)); //NOI18N
455                 String choosen = this.handleChooseFromRequestSession(product, request, session);
456                 this.getLogger().debug(MessageFormat.format("product={0},choosen={1}", product.getId(), choosen)); //NOI18N
457
458                 // Must not be null
459                 assert(choosen instanceof String): "choosen is null"; //NOI18N
460
461                 // Is it empty?
462                 if (choosen.isEmpty()) {
463                         // Not choosen
464                         return "Nein";
465                 }
466
467                 // Get amount
468                 String amount = this.handleAmountFromRequestSession(product, request, session);
469                 this.getLogger().debug(MessageFormat.format("product={0},amount={1}", product.getId(), amount)); //NOI18N
470
471                 // Must not be null
472                 assert(amount instanceof String): "amount is null"; //NOI18N
473
474                 // Is it empty?
475                 if (amount.isEmpty() || "0".equals(amount)) { //NOI18N
476                         // Choosen, but no amount
477                         return "Nein";
478                 } else {
479                         // Is choosen
480                         return "Ja";
481                 }
482         }
483
484         /**
485          * Checks if given Product instance is available and returns a printable
486          * (human-readable) string.
487          * 
488          * @param product Product instance to check
489          * @return Human-readable version of product availability
490          */
491         @Override
492         public String getPrintableProduktAvailability (final Product product) {
493                 // Trace message
494                 this.getLogger().trace(MessageFormat.format("product={0} - CALLED!", product)); //NOI18N
495
496                 // Is it null?
497                 if (product == null) {
498                         // Should not be null
499                         throw new NullPointerException("product is null"); //NOI18N
500                 }
501
502                 // Get availability
503                 if (product.getAvailable() == true) {
504                         // Is available
505                         return "Ja";
506                 } else {
507                         // Not, not for public
508                         return "Nein";
509                 }
510         }
511
512         /**
513          * Some getter for printable value from session or an empty string for null.
514          *
515          * @param session Session instance
516          * @param key Key to get
517          * @return Value from key, empty string for null
518          */
519         @Override
520         public Object getPrintableValeFromSession (final HttpSession session, final String key) {
521                 // Trace message
522                 this.getLogger().trace(MessageFormat.format("session={0},key={1} - CALLED", session, key)); //NOI18N
523
524                 // Are both parameter not null?
525                 if (session == null) {
526                         // Abort here
527                         throw new NullPointerException("session is null"); //NOI18N
528                 } else  if (key == null) {
529                         // Abort here
530                         throw new NullPointerException("key is null"); //NOI18N
531                 }
532
533                 // Now get it
534                 Object value = this.getValueFromSession(session, key);
535
536                 // Debug message
537                 this.getLogger().debug(MessageFormat.format("value={0}", value)); //NOI18N
538
539                 // Trace message
540                 this.getLogger().trace(MessageFormat.format("Calling this.convertNullToEmpty({0}) ... - EXIT!", value)); //NOI18N
541
542                 // Return actual value
543                 return this.convertNullToEmpty(value);
544         }
545
546         /**
547          * Some "getter" for a an array of only available products
548          *
549          * @return All products
550          */
551         @Override
552         public Iterator<Product> getAvailableProducts () throws ServletException {
553                 try {
554                         // Ask frontend for a list of products
555                         return this.productFrontend.getAvailableProducts();
556                 } catch (final IOException | BadTokenException | SQLException | CorruptedDatabaseFileException | NoSuchMethodException | IllegalAccessException | InvocationTargetException ex) {
557                         throw new ServletException(ex);
558                 }
559         }
560
561         /**
562          * Some "getter" for a an array of all products
563          *
564          * @return All products
565          */
566         @Override
567         public Iterator<Product> getAllProducts () throws ServletException {
568                 try {
569                         // Ask frontend for a list of products
570                         return this.productFrontend.getAllProducts();
571                 } catch (final IOException | BadTokenException | SQLException | CorruptedDatabaseFileException | NoSuchMethodException | IllegalAccessException | InvocationTargetException ex) {
572                         throw new ServletException(ex);
573                 }
574         }
575
576         /**
577          * Some "getter" for a an array of all categories
578          *
579          * @return All categories
580          */
581         @Override
582         public Iterator<Category> getCategories () throws ServletException {
583                 try {
584                         // Ask frontend for a list of categories
585                         return this.categoryFrontend.getCategories();
586                 } catch (final IOException | BadTokenException | SQLException | CorruptedDatabaseFileException | NoSuchMethodException | IllegalAccessException | InvocationTargetException ex) {
587                         throw new ServletException(ex);
588                 }
589         }
590
591         /**
592          * Some "getter" for total price of position from request or session.
593          * Single price and amount is multiplyed.
594          *
595          * @param product Product instance
596          * @param request Request instance
597          * @param session Session instance
598          * @return Amount as string
599          */
600         @Override
601         public float getTotalPositionPriceFromRequestSession (final Product product, final HttpServletRequest request, final HttpSession session) {
602                 // Trace message
603                 this.getLogger().trace(MessageFormat.format("product={0},request={1},session={2} - CALLED!", product, request, session)); //NOI18N
604
605                 // Is product and session set?
606                 if (product == null) {
607                         // Not set
608                         throw new NullPointerException("product is null"); //NOI18N
609                 } else if (request == null) {
610                         // Not set
611                         throw new NullPointerException("request is null"); //NOI18N
612                 } else if (session == null) {
613                         // Not set
614                         throw new NullPointerException("session is null"); //NOI18N
615                 }
616
617                 // Get choosen
618                 this.getLogger().debug(MessageFormat.format("Calling handleChooseFromRequestSession({0},{1},{2}) ...", product.getId(), request, session)); //NOI18N
619                 String choosen = this.handleChooseFromRequestSession(product, request, session);
620                 this.getLogger().debug(MessageFormat.format("product={0},choosen={1}", product.getId(), choosen)); //NOI18N
621
622                 // Must not be null
623                 assert(choosen instanceof String): "choosen is null"; //NOI18N
624
625                 // Is it set?
626                 if (choosen.isEmpty()) {
627                         // Is empty
628                         this.getLogger().debug(MessageFormat.format("product={0},choosen={1} - returning zero ...", product.getId(), choosen)); //NOI18N
629                         return 0.00f;
630                 }
631
632                 // Get amount
633                 String amount = this.handleAmountFromRequestSession(product, request, session);
634                 this.getLogger().debug(MessageFormat.format("product={0},amount={1}", product.getId(), amount)); //NOI18N
635
636                 // Must not be null
637                 assert(amount instanceof String): "amount is null"; //NOI18N
638
639                 // Is it empty?
640                 if (amount.isEmpty() || "0".equals(amount)) { //NOI18N
641                         // Is empty
642                         this.getLogger().debug(MessageFormat.format("product={0},amount={1} - returning zero ...", product.getId(), amount)); //NOI18N
643                         return 0.00f;
644                 }
645
646                 // Init variable
647                 Integer value = null;
648
649                 // Try it
650                 try {
651                         // Get amount as integer
652                         value = Integer.valueOf(amount);
653                 } catch (final NumberFormatException e) {
654                         // Bat input
655                         throw new IllegalArgumentException(e);
656                 }
657
658                 // Calculate price
659                 float price = (product.getPrice() * value);
660
661                 // Trace message
662                 this.getLogger().trace(MessageFormat.format("product={0},price={1} - EXIT!", product.getId(), price)); //NOI18N
663
664                 // Then multiply it with price
665                 return price;
666         }
667
668         /**
669          * Handler for amount from request or session
670          *
671          * @param product Product instance
672          * @param request Request instance
673          * @param session Session instance
674          * @return Amount as string
675          */
676         @Override
677         public String handleAmountFromRequestSession (final Product product, final HttpServletRequest request, final HttpSession session) {
678                 // Trace message
679                 this.getLogger().trace(MessageFormat.format("product={0},request={1},session={2} - CALLED!", product, request, session)); //NOI18N
680
681                 // Is product and session set?
682                 if (product == null) {
683                         // Not set
684                         throw new NullPointerException("product is null"); //NOI18N
685                 } else if (request == null) {
686                         // Not set
687                         throw new NullPointerException("request is null"); //NOI18N
688                 } else if (session == null) {
689                         // Not set
690                         throw new NullPointerException("session is null"); //NOI18N
691                 }
692
693                 // Init variabke
694                 Object object;
695
696                 // Check request method
697                 if (!"POST".equals(request.getMethod())) { //NOI18N
698                         // Not POST, so get from session
699                         return this.getAmountFromSession(product, session);
700                 } else if (this.handleChooseFromRequestSession(product, request, session).isEmpty()) {
701                         // Not choosen
702                         this.clearSessionAttribute(product, session, HTTP_PARAM_AMOUNT);
703                         this.getLogger().debug(MessageFormat.format("Unsetting for product={0} in session, returning zero ...", product.getId())); //NOI18N
704                         return "0"; //NOI18N
705                 }
706
707                 // Get attribute from request
708                 object = request.getParameter(String.format(HTTP_PARAM_MASK, HTTP_PARAM_AMOUNT, product.getId()));
709
710                 // Is it set?
711                 if (object instanceof String) {
712                         // Try to parse it to integer
713                         try {
714                                 Integer value = Integer.valueOf((String) object);
715                         } catch (final NumberFormatException ex) {
716                                 // Not valid input
717                                 this.getLogger().warn(ex);
718                                 return "0"; //NOI18N
719                         }
720
721                         // Then set it in session
722                         this.setValueInSession(product, session, HTTP_PARAM_AMOUNT, object);
723
724                         // And return it
725                         return (String) object;
726                 }
727
728                 // Trace message
729                 this.getLogger().trace("Calling getAmountFromSession() ..."); //NOI18N
730
731                 // Get attribute from session
732                 return this.getAmountFromSession(product, session);
733         }
734
735         /**
736          * Checks whether the given product is choosen, request overules session.
737          *
738          * @param product Product instance
739          * @param request Request instance
740          * @param session Session instance
741          * @return Whether the product is choosen
742          */
743         @Override
744         public boolean isProductChoosen (final Product product, final HttpServletRequest request, final HttpSession session) {
745                 // Trace message
746                 this.getLogger().trace(MessageFormat.format("product={0},request={1},session={2} - CALLED!", product, request, session)); //NOI18N
747
748                 // Is product and session set?
749                 if (product == null) {
750                         // Not set
751                         throw new NullPointerException("product is null"); //NOI18N
752                 } else if (request == null) {
753                         // Not set
754                         throw new NullPointerException("request is null"); //NOI18N
755                 } else if (session == null) {
756                         // Not set
757                         throw new NullPointerException("session is null"); //NOI18N
758                 }
759
760                 // Get choosen
761                 this.getLogger().debug(MessageFormat.format("Calling handleChooseFromRequestSession({0},{1},{2}) ...", product.getId(), request, session)); //NOI18N
762                 String choosen = this.handleChooseFromRequestSession(product, request, session);
763                 this.getLogger().debug(MessageFormat.format("product={0},choosen={1}", product.getId(), choosen)); //NOI18N
764
765                 // Must not be null
766                 assert(choosen instanceof String): "choosen is null"; //NOI18N
767
768                 // Is it not choosen?
769                 if (choosen.isEmpty()) {
770                         // Not choosen
771                         return false;
772                 }
773
774                 // Get amount
775                 String amount = this.handleAmountFromRequestSession(product, request, session);
776
777                 // Must not be null
778                 assert(amount instanceof String): "amount is not set"; //NOI18N
779
780                 // Trace message
781                 this.getLogger().trace(MessageFormat.format("amount={0} - EXIT!", amount)); //NOI18N
782
783                 // Must not be empty and not 0
784                 return (!amount.isEmpty() && !"0".equals(amount)); //NOI18N
785         }
786
787         /**
788          * Marks all choosen products as ordered
789          *
790          * @param request Request instance
791          * @param session Session instance
792          */
793         @Override
794         public void markAllChoosenProductsAsOrdered (final HttpServletRequest request, final HttpSession session) throws ServletException {
795                 // Trace message
796                 this.getLogger().trace(MessageFormat.format("request={0},session={1} - CALLED!", request, session)); //NOI18N
797
798                 // Init iterator
799                 Iterator<Product> iterator = this.getAvailableProducts();
800
801                 // "Walk" over all products
802                 while (iterator.hasNext()) {
803                         // Get next product
804                         Product product = iterator.next();
805
806                         // Debug message
807                         this.getLogger().debug(MessageFormat.format("product={0}", product)); //NOI18N
808
809                         // Is it choosen?
810                         if (this.isProductChoosen(product, request, session)) {
811                                 // Mark product as ordered
812                                 this.markProductAsOrdered(product, session);
813                         }
814                 }
815
816                 // Trace message
817                 this.getLogger().trace("EXIT!"); //NOI18N
818         }
819
820         /**
821          * Marks given product as choosen in session
822          *
823          * @param product Product to mark as ordered
824          * @param session Session instance
825          */
826         @Override
827         public void markProductAsChoosen (final Product product, final HttpSession session) {
828                 // Trace message
829                 this.getLogger().trace(MessageFormat.format("product={0},session={1} - CALLED!", product, session)); //NOI18N
830
831                 // Is product and session set?
832                 if (product == null) {
833                         // Not set
834                         throw new NullPointerException("product is null"); //NOI18N
835                 } else if (session == null) {
836                         // Not set
837                         throw new NullPointerException("session is null"); //NOI18N
838                 }
839
840                 // Mark it as ordered by setting flag
841                 this.getLogger().debug(MessageFormat.format("Marking product={0} as choosen.", product.getId())); //NOI18N
842                 this.setValueInSession(product, session, HTTP_PARAM_CHOOSE, "1"); //NOI18N
843
844                 // Trace message
845                 this.getLogger().trace("EXIT!"); //NOI18N
846         }
847
848         /**
849          * Marks given product as ordered in session
850          *
851          * @param product Product to mark as ordered
852          * @param session Session instance
853          */
854         @Override
855         public void markProductAsOrdered (final Product product, final HttpSession session) {
856                 // Trace message
857                 this.getLogger().trace(MessageFormat.format("product={0},session={1} - CALLED!", product, session)); //NOI18N
858
859                 // Is product and session set?
860                 if (product == null) {
861                         // Not set
862                         throw new NullPointerException("product is null"); //NOI18N
863                 } else if (session == null) {
864                         // Not set
865                         throw new NullPointerException("session is null"); //NOI18N
866                 }
867
868                 // Mark it as ordered by setting flag
869                 this.getLogger().debug(MessageFormat.format("Marking product={0} as ordered.", product.getId())); //NOI18N
870                 this.setValueInSession(product, session, SESSION_ORDERED, "true"); //NOI18N
871
872                 // Trace message
873                 this.getLogger().trace("EXIT!"); //NOI18N
874         }
875
876         /**
877          * Somewhat setter in session
878          *
879          * @param session Session instance
880          * @param key Session key to set
881          * @param value Value to set
882          */
883         @Override
884         public void setValueInSession (final HttpSession session, final String key, final Object value) {
885                 // Trace message
886                 this.getLogger().trace(MessageFormat.format("session={0},key={1},value={2} - CALLED!", session, key, value)); //NOI18N
887
888                 synchronized(session) {
889                         // Set it synced
890                         session.setAttribute(key, value);
891                 }
892
893                 // Trace message
894                 this.getLogger().trace("EXIT!"); //NOI18N
895         }
896
897         /**
898          * Unmarks given product as choosen in session
899          *
900          * @param product Product to unmark as choosen
901          * @param session Session instance
902          */
903         @Override
904         public void unmarkProductAsChoosen (final Product product, final HttpSession session) {
905                 // Trace message
906                 this.getLogger().trace(MessageFormat.format("product={0},session={1} - CALLED!", product, session)); //NOI18N
907
908                 // Is product and session set?
909                 if (product == null) {
910                         // Not set
911                         throw new NullPointerException("product is null"); //NOI18N
912                 } else if (session == null) {
913                         // Not set
914                         throw new NullPointerException("session is null"); //NOI18N
915                 }
916
917                 // Mark it as ordered by setting flag
918                 this.getLogger().debug(MessageFormat.format("Unmarking product={0} as choosen.", product.getId())); //NOI18N
919                 this.clearSessionAttribute(product, session, HTTP_PARAM_CHOOSE);
920
921                 // Trace message
922                 this.getLogger().trace("EXIT!"); //NOI18N
923         }
924
925         /**
926          * Unmarks given product as ordered in session
927          *
928          * @param product Product to unmark as ordered
929          * @param session Session instance
930          */
931         @Override
932         public void unmarkProductAsOrdered (final Product product, final HttpSession session) {
933                 // Trace message
934                 this.getLogger().trace(MessageFormat.format("product={0},session={1} - CALLED!", product, session)); //NOI18N
935
936                 // Is product and session set?
937                 if (product == null) {
938                         // Not set
939                         throw new NullPointerException("product is null"); //NOI18N
940                 } else if (session == null) {
941                         // Not set
942                         throw new NullPointerException("session is null"); //NOI18N
943                 }
944
945                 // Mark it as ordered by setting flag
946                 this.getLogger().debug(MessageFormat.format("Unmarking product={0} as ordered.", product.getId())); //NOI18N
947                 this.clearSessionAttribute(product, session, SESSION_ORDERED);
948
949                 // Trace message
950                 this.getLogger().trace("EXIT!"); //NOI18N
951         }
952
953         /**
954          * Clears given parameter for product in session
955          *
956          * @param product Product instance
957          * @param session Session instance
958          * @param parameter Parameter to clear
959          */
960         private void clearSessionAttribute (final Product product, final HttpSession session, final String parameter) {
961                 // Trace message
962                 this.getLogger().trace(MessageFormat.format("produce={0},parameter={1},session={2} - CALLED!", product, parameter, session)); //NOI18N
963
964                 // Clear in session
965                 this.getLogger().debug(MessageFormat.format("Clearing product={0},parameter={1} ...", product.getId(), parameter)); //NOI18N
966                 this.setValueInSession(product, session, parameter, null);
967
968                 // Trace message
969                 this.getLogger().trace("EXIT!"); //NOI18N
970         }
971
972         /**
973          * Some getter for value from session
974          *
975          * @param product Product instance
976          * @param session Session instance
977          * @param attribute Attribute to get value from
978          * @return Value from session
979          */
980         private Object getValueFromSession (final Product product, final HttpSession session, final String attribute) {
981                 // Trace message
982                 this.getLogger().trace(MessageFormat.format("product={0},session={1},attribute={2} - CALLED!", product, session, attribute)); //NOI18N
983
984                 // Init variable
985                 Object value = this.getValueFromSession(session, String.format(HTTP_PARAM_MASK, attribute, product.getId()));
986                 
987                 this.getLogger().debug(MessageFormat.format("product={0},attribute={1},value={2}", product.getId(), attribute, value)); //NOI18N
988
989                 // Trace message
990                 this.getLogger().trace(MessageFormat.format("value={0} - EXIT!", value)); //NOI18N
991
992                 // Return it
993                 return value;
994         }
995
996         /**
997          * Some getter for value from session
998          *
999          * @param session Session instance
1000          * @param key Key to get value from
1001          * @return Value from session
1002          */
1003         private Object getValueFromSession (final HttpSession session, final String key) {
1004                 // Trace message
1005                 this.getLogger().trace(MessageFormat.format("session={0},key={1} - CALLED!", session, key)); //NOI18N
1006
1007                 // Init value
1008                 Object value;
1009
1010                 // Get it synchronized from session
1011                 synchronized (session) {
1012                         value = session.getAttribute(key);
1013                 }
1014
1015                 // Trace message
1016                 this.getLogger().trace(MessageFormat.format("value={0} - EXIT!", value)); //NOI18N
1017
1018                 // Return it
1019                 return value;
1020         }
1021
1022         /**
1023          * Handler for choosen (checkbox) from request or session
1024          *
1025          * @param product Product instance
1026          * @param request Request instance
1027          * @param session Session instance
1028          * @return Amount as string
1029          */
1030         private String handleChooseFromRequestSession (final Product product, final HttpServletRequest request, final HttpSession session) {
1031                 // Trace message
1032                 this.getLogger().trace(MessageFormat.format("product={0},request={1},session={2} - CALLED!", product, request, session)); //NOI18N
1033
1034                 // Is product and session set?
1035                 if (product == null) {
1036                         // Not set
1037                         throw new NullPointerException("product is null"); //NOI18N
1038                 } else if (request == null) {
1039                         // Not set
1040                         throw new NullPointerException("request is null"); //NOI18N
1041                 } else if (session == null) {
1042                         // Not set
1043                         throw new NullPointerException("session is null"); //NOI18N
1044                 }
1045
1046                 // Init variabke
1047                 Object object;
1048
1049                 // Check request method
1050                 if (!"POST".equals(request.getMethod())) { //NOI18N
1051                         // Not POST, so get from session
1052                         this.getLogger().trace(MessageFormat.format("Calling this.getChooseFromSession({0},{1}) ... - EXIT!", product.getId(), session)); //NOI18N
1053                         return this.getChooseFromSession(product, session);
1054                 } else if (this.isProductOrdered(product, session)) {
1055                         // Product is ordered
1056                         this.getLogger().trace(MessageFormat.format("Calling this.getChooseFromSession({0},{1}) ... - EXIT!", product.getId(), session)); //NOI18N
1057                         return this.getChooseFromSession(product, session);
1058                 } else if (!this.getChooseFromSession(product, session).isEmpty()) {
1059                         // Found in session
1060                         this.getLogger().trace(MessageFormat.format("Calling this.getChooseFromSession({0},{1}) ... - EXIT!", product.getId(), session)); //NOI18N
1061                         return this.getChooseFromSession(product, session);
1062                 }
1063
1064                 // Get reqzest element
1065                 object = request.getParameter(String.format(HTTP_PARAM_MASK, HTTP_PARAM_CHOOSE, product.getId()));
1066                 this.getLogger().debug(MessageFormat.format("product={0},object={1}", product.getId(), object)); //NOI18N
1067
1068                 // Is it null?
1069                 if (object == null) {
1070                         // Unset session
1071                         this.getLogger().debug(MessageFormat.format("Unsetting session for product={0} ...", product.getId())); //NOI18N
1072                         this.clearSessionAttribute(product, session, HTTP_PARAM_CHOOSE);
1073                         this.clearSessionAttribute(product, session, HTTP_PARAM_AMOUNT);
1074
1075                         // Return empty string
1076                         return ""; //NOI18N
1077                 }
1078
1079                 // Then set it in session
1080                 this.setValueInSession(product, session, HTTP_PARAM_CHOOSE, object);
1081
1082                 // Cast to string and return it
1083                 this.getLogger().debug(MessageFormat.format("product={0} - Returning {1} ...", product.getId(), object)); //NOI18N
1084                 return (String) object;
1085         }
1086
1087         /**
1088          * Initializes database frontends.
1089          */
1090         private void initDatabaseFrontends () throws UnsupportedDatabaseBackendException, SQLException {
1091                 // Product frontend
1092                 this.productFrontend = new PizzaProductDatabaseFrontend();
1093
1094                 // Category frontend
1095                 this.categoryFrontend = new PizzaCategoryDatabaseFrontend();
1096         }
1097
1098         /**
1099          * Checks whether given category title is already used
1100          *
1101          * @param title Title of category to check
1102          * @return Whether it has been found
1103          */
1104         private boolean isCategoryTitleUsed(final String title) throws IOException, SQLException, BadTokenException, CorruptedDatabaseFileException, NoSuchMethodException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
1105                 // Delegate to frontend
1106                 return this.categoryFrontend.isCategoryTitleUsed(title);
1107         }
1108
1109         /**
1110          * Checks if given product title is already used
1111          * @param title Product title to check
1112          * @return Whether the product title has already been used
1113          */
1114         private boolean isProductTitleUsed (final String title) throws IOException, SQLException, BadTokenException, CorruptedDatabaseFileException, NoSuchMethodException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
1115                 // Delegate to frontend
1116                 return this.productFrontend.isProductTitleUsed(title);
1117         }
1118
1119         /**
1120          * Checks if the product ordered?
1121          *
1122          * @param product Product instance
1123          * @param session HttpSession instance
1124          * @return Whether the product has been ordered
1125          */
1126         private boolean isProductOrdered (final Product product, final HttpSession session) {
1127                 // Trace message
1128                 this.getLogger().trace(MessageFormat.format("product={0},session={1} - CALLED!", product, session)); //NOI18N
1129
1130                 // Get session
1131                 Object isOrdered = this.getValueFromSession(product, session, SESSION_ORDERED);
1132                 this.getLogger().debug(MessageFormat.format("product={0},isOrdered={1}", product.getId(), isOrdered)); //NOI18N
1133
1134                 // Return result
1135                 return ("true".equals(isOrdered)); //NOI18N
1136         }
1137
1138         /**
1139          * Somewhat setter in session
1140          *
1141          * @param product Product instance
1142          * @param session Session instance
1143          * @param keyPart Key part to include in final key
1144          * @param value Value to set
1145          */
1146         private void setValueInSession (final Product product, final HttpSession session, final String keyPart, final Object value) {
1147                 // Trace message
1148                 this.getLogger().trace(MessageFormat.format("product={0},session={1},keyPart={2},value={3} - CALLED!", product, session, keyPart, value)); //NOI18N
1149
1150                 // Set it synced
1151                 this.getLogger().debug(MessageFormat.format("Setting value={0} for product={1},keyPart={2}", value, product.getId(), keyPart)); //NOI18N
1152                 this.setValueInSession(session, String.format(HTTP_PARAM_MASK, keyPart, product.getId()), value);
1153
1154                 // Trace message
1155                 this.getLogger().trace("EXIT!"); //NOI18N
1156         }
1157         
1158         /**
1159          * Application starter
1160          */
1161         private void start() {
1162                 // Init bundle
1163                 this.initBundle();
1164
1165                 try {
1166                         // Init properties
1167                         this.initProperties();
1168                 } catch (final IOException ex) {
1169                         // Abort here
1170                         this.abortProgramWithException(ex);
1171                 }
1172
1173                 // Init instance
1174                 Iterator<Product> iterator = null;
1175
1176                 try {
1177                         // Get iterator
1178                         iterator = this.getAvailableProducts();
1179                 } catch (final ServletException ex) {
1180                         this.abortProgramWithException(ex);
1181                 }
1182
1183                 // "Walk" over all products
1184                 while ((iterator instanceof Iterator) && (iterator.hasNext())) {
1185                         // Get next product
1186                         Product product = iterator.next();
1187
1188                         // Output data
1189                         this.getLogger().debug(MessageFormat.format("Product {0}, {1}: {2}", product.getId(), product.getTitle(), product.getPrice())); //NOI18N
1190                 }
1191
1192                 // Generate fake Customer instance
1193                 Customer customer = new PizzaServiceCustomer();
1194
1195                 /*
1196                 * Need a least a gender ... :( See, that is why I don't like default
1197                 * constructors, you can easily miss something important and bam! You
1198                 * get an NPE. The fix here is, to have construtors (or factories) which
1199                 * requires all required instances that needs to be set to get a
1200                 * consitent object back.
1201                 */
1202                 
1203                 // Gender is MALE now
1204                 customer.setGender(Gender.MALE);
1205
1206                 // Init iterator
1207                 Iterator<Map.Entry<Field, Object>> it = null;
1208
1209                 try {
1210                         // Get iterator on all its fields
1211                         it = customer.iterator();
1212                 } catch (final NoSuchMethodException | IllegalAccessException | InvocationTargetException ex) {
1213                         this.abortProgramWithException(ex);
1214                 }
1215
1216                 // Output it
1217                 while ((it instanceof Iterator) && (it.hasNext())) {
1218                         Map.Entry<Field, Object> entry = it.next();
1219                         this.getLogger().debug(MessageFormat.format("entry {0}={1}", entry.getKey(), entry.getValue())); //NOI18N
1220                 }
1221         }
1222
1223         /**
1224          * Adds given category data from request to database
1225          *
1226          * @param request Request instance
1227          */
1228         @Override
1229         public void doAdminAddCategory (final HttpServletRequest request) throws ServletException, CategoryTitleAlreadyUsedException {
1230                 // Trace message
1231                 this.getLogger().trace(MessageFormat.format("request={0} - CALLED!", request)); //NOI18N
1232
1233                 // request must not be null
1234                 if (request == null) {
1235                         // Is null
1236                         throw new NullPointerException("request is null"); //NOI18N
1237                 }
1238
1239                 // Get all fields
1240                 String title = request.getParameter(PizzaCategoryDatabaseConstants.COLUMN_TITLE);
1241                 String parent = request.getParameter(PizzaCategoryDatabaseConstants.COLUMN_PARENT);
1242
1243                 // Debug message
1244                 this.getLogger().debug(MessageFormat.format("title={0},parent={1}", title, parent)); //NOI18N
1245
1246                 // Init variables for casting
1247                 Integer id = 0;
1248
1249                 // Check all fields
1250                 if (title == null) {
1251                         // "title" not set
1252                         throw new IllegalArgumentException(MessageFormat.format("{0} is not set.", PizzaCategoryDatabaseConstants.COLUMN_TITLE)); //NOI18N
1253                 } else if (title.isEmpty()) {
1254                         // Is left empty
1255                         throw new IllegalArgumentException(MessageFormat.format("{0} is empty.", PizzaCategoryDatabaseConstants.COLUMN_TITLE)); //NOI18N
1256                 } else if ((parent != null) && (!parent.isEmpty())) {
1257                         // "parent" is set, so check it
1258                         try {
1259                                 id = Integer.parseInt(parent);
1260                         } catch (final NumberFormatException e) {
1261                                 // Not valid number
1262                                 throw new IllegalArgumentException(e);
1263                         }
1264                 }
1265
1266                 try {
1267                         // Try to check if title is used already
1268                         if (this.isCategoryTitleUsed(title)) {
1269                                 // Title already used
1270                                 throw new CategoryTitleAlreadyUsedException(request);
1271                         }
1272                 } catch (final IOException | SQLException | BadTokenException | CorruptedDatabaseFileException | NoSuchMethodException | IllegalAccessException | InvocationTargetException ex) {
1273                         throw new ServletException(ex);
1274                 }
1275
1276                 try {
1277                         // The category is not found, so add it to database
1278                         this.categoryFrontend.addCategory(title, id);
1279                 } catch (final SQLException | IOException ex) {
1280                         // Continue to throw it
1281                         throw new ServletException(ex);
1282                 }
1283
1284                 // Trace message
1285                 this.getLogger().trace("EXIT!"); //NOI18N
1286         }
1287
1288         /**
1289          * Adds given product data from request to database
1290          *
1291          * @param request Request instance
1292          */
1293         @Override
1294         public void doAdminAddProduct (final HttpServletRequest request) throws ServletException, ProductTitleAlreadyUsedException {
1295                 // Trace message
1296                 this.getLogger().trace(MessageFormat.format("request={0} - CALLED!", request)); //NOI18N
1297
1298                 // request must not be null
1299                 if (request == null) {
1300                         // Is null
1301                         throw new NullPointerException("request is null"); //NOI18N
1302                 }
1303
1304                 // Get title, price and category id
1305                 String title = request.getParameter(PizzaProductDatabaseConstants.COLUMN_TITLE);
1306                 String price = request.getParameter(PizzaProductDatabaseConstants.COLUMN_PRICE);
1307                 String category = request.getParameter(PizzaProductDatabaseConstants.COLUMN_CATEGORY);
1308                 String available = request.getParameter(PizzaProductDatabaseConstants.COLUMN_AVAILABLE);
1309
1310                 // Debug message
1311                 this.getLogger().debug(MessageFormat.format("title={0},price={1},category={2},available={3}", title, price, category, available)); //NOI18N
1312
1313                 // Variables for converting
1314                 Long id = null;
1315                 Float p = null;
1316
1317                 // Check all fields
1318                 if (title == null) {
1319                         // "title" not set
1320                         throw new IllegalArgumentException(MessageFormat.format("{0} is not set.", PizzaProductDatabaseConstants.COLUMN_TITLE)); //NOI18N
1321                 } else if (title.isEmpty()) {
1322                         // Is left empty
1323                         throw new IllegalArgumentException(MessageFormat.format("{0} is empty.", PizzaProductDatabaseConstants.COLUMN_TITLE)); //NOI18N
1324                 } else if (price == null) {
1325                         // "price" not set
1326                         throw new IllegalArgumentException(MessageFormat.format("{0} is not set.", PizzaProductDatabaseConstants.COLUMN_PRICE)); //NOI18N
1327                 } else if (price.isEmpty()) {
1328                         // Is left empty
1329                         throw new IllegalArgumentException(MessageFormat.format("{0} is empty.", PizzaProductDatabaseConstants.COLUMN_PRICE)); //NOI18N
1330                 } else if (category == null) {
1331                         // "title" not set
1332                         throw new IllegalArgumentException(MessageFormat.format("{0} is not set.", PizzaProductDatabaseConstants.COLUMN_CATEGORY)); //NOI18N
1333                 } else if (category.isEmpty()) {
1334                         // Is left empty
1335                         throw new IllegalArgumentException(MessageFormat.format("{0} is empty.", PizzaProductDatabaseConstants.COLUMN_CATEGORY)); //NOI18N
1336                 } else if (available == null) {
1337                         // "title" not set
1338                         throw new IllegalArgumentException(MessageFormat.format("{0} is not set.", PizzaProductDatabaseConstants.COLUMN_AVAILABLE)); //NOI18N
1339                 } else if (available.isEmpty()) {
1340                         // Is left empty
1341                         throw new IllegalArgumentException(MessageFormat.format("{0} is empty.", PizzaProductDatabaseConstants.COLUMN_AVAILABLE)); //NOI18N
1342                 } else if ((!"true".equals(available)) && (!"false".equals(available))) { //NOI18N
1343                         // Invalid value
1344                         throw new IllegalArgumentException(MessageFormat.format("{0} is invalid: {1}", PizzaProductDatabaseConstants.COLUMN_AVAILABLE, available)); //NOI18N
1345                 }
1346
1347                 // Parse numbers
1348                 try {
1349                         id = Long.parseLong(category);
1350                         p = Float.parseFloat(price);
1351                 } catch (final NumberFormatException e) {
1352                         // Not valid number
1353                         throw new IllegalArgumentException(e);
1354                 }
1355
1356                 // Parse boolean
1357                 Boolean a = Boolean.parseBoolean(available);
1358
1359                 // Test on product title
1360                 try {
1361                         // Try to check if title is used already
1362                         if (this.isProductTitleUsed(title)) {
1363                                 // Title already used
1364                                 throw new ProductTitleAlreadyUsedException(request);
1365                         }
1366                 } catch (final IOException | SQLException | BadTokenException | CorruptedDatabaseFileException | NoSuchMethodException | IllegalAccessException | InvocationTargetException ex) {
1367                         throw new ServletException(ex);
1368                 }
1369
1370                 try {
1371                         // The product is not found, so add it to database
1372                         this.productFrontend.addProduct(title, p, id, a);
1373                 } catch (final SQLException | IOException ex) {
1374                         // Continue to throw it
1375                         throw new ServletException(ex);
1376                 }
1377
1378                 // Trace message
1379                 this.getLogger().trace("EXIT!"); //NOI18N
1380         }
1381
1382         /**
1383          * Generates link HTML code for given category's parent id, if set. This
1384          * link then points to products.jsp?category_id=x
1385          *
1386          * @param category Category instance
1387          * @return HTML code
1388          */
1389         @Override
1390         public String generateLinkForParent (final Category category) {
1391                 // Trace message
1392                 this.getLogger().trace(MessageFormat.format("category={0} - CALLED!", category)); //NOI18N
1393
1394                 // category must not be null
1395                 if (category == null) {
1396                         // Is null
1397                         throw new NullPointerException("category is null"); //NOI18N
1398                 }
1399
1400                 // Get parent id
1401                 Long parent = category.getParent();
1402
1403                 // Is the id set?
1404                 if (parent > 0) {
1405                         // Product HTML code for link
1406                         throw new UnsupportedOperationException(MessageFormat.format("parent={0} - Unfinished!", parent)); //NOI18N
1407                 }
1408
1409                 // No parent set
1410                 return "Keine";
1411         }
1412
1413         @Override
1414         public String getPrintableProduktCategory (final Product product) throws ServletException {
1415                 // Trace message
1416                 this.getLogger().trace(MessageFormat.format("product={0} - CALLED!", product)); //NOI18N
1417
1418                 // product must not be null
1419                 if (product == null) {
1420                         // Abort here
1421                         throw new NullPointerException("product is null"); //NOI18N
1422                 }
1423
1424                 // Declare category
1425                 Category category;
1426
1427                 try {
1428                         // Get Category instance from product over the frontend
1429                         category = this.categoryFrontend.getCategory(product);
1430                 } catch (final IOException | SQLException | BadTokenException | CorruptedDatabaseFileException | NoSuchMethodException | IllegalAccessException | IllegalArgumentException | InvocationTargetException ex) {
1431                         throw new ServletException(ex);
1432                 }
1433
1434                 // Debug message
1435                 this.getLogger().debug(MessageFormat.format("category={0}", category)); //NOI18N
1436
1437                 String title = null;
1438                 try {
1439                         // Now get title from it and return it
1440                         title = category.decodedTitle();
1441                 } catch (final UnsupportedEncodingException ex) {
1442                         // Continue to throw as cause
1443                         throw new ServletException(ex);
1444                 }
1445
1446                 // Trace message
1447                 this.getLogger().trace(MessageFormat.format("title={0} - EXIT!", title)); //NOI18N
1448
1449                 // Return it
1450                 return title;
1451         }
1452
1453         /**
1454          * Checks if product's title is already used.
1455          * 
1456          * @param request Request instance
1457          * @return Whether the product title is already used
1458          * @throws java.io.IOException If any IO error occurs
1459          * @throws org.mxchange.jcore.exceptions.BadTokenException If a bad token was found in a file-based database backend's file ... ;-)
1460          * @throws java.sql.SQLException If any SQL error occurs
1461          * @throws org.mxchange.jcore.exceptions.CorruptedDatabaseFileException If the database file is damaged
1462          * @throws java.lang.NoSuchMethodException If a method was not found
1463          * @throws java.lang.IllegalAccessException If the method cannot be accessed
1464          * @throws java.lang.reflect.InvocationTargetException Any other problems?
1465          */
1466         private boolean isProductTitleUsed (final HttpServletRequest request) throws IOException, SQLException, BadTokenException, CorruptedDatabaseFileException, NoSuchMethodException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
1467                 // Trace message
1468                 this.getLogger().trace(MessageFormat.format("request={0} - CALLED!", request)); //NOI18N
1469
1470                 // Init title
1471                 String title = request.getParameter(PizzaProductDatabaseConstants.COLUMN_TITLE);
1472
1473                 // request must not be null and "title" must be found and non-empty
1474                 if (request == null) {
1475                         // Abort here
1476                         throw new NullPointerException("request is null"); //NOI18N
1477                 } else if (title == null) {
1478                         // title is not set
1479                         throw new IllegalArgumentException(MessageFormat.format("{0} is not set.", PizzaProductDatabaseConstants.COLUMN_TITLE)); //NOI18N
1480                 } else if (title.isEmpty()) {
1481                         // Is left empty
1482                         throw new IllegalArgumentException(MessageFormat.format("{0} is empty.", PizzaProductDatabaseConstants.COLUMN_TITLE)); //NOI18N
1483                 }
1484
1485                 // Default is not used
1486                 boolean isUsed = this.isProductTitleUsed(title);
1487
1488                 // Trace message
1489                 this.getLogger().trace(MessageFormat.format("isUsed={0} - EXIT!", isUsed)); //NOI18N
1490
1491                 // Return it
1492                 return isUsed;
1493         }
1494
1495         /**
1496          * Handles admin form requests
1497          * @param request Request instance
1498          * @param response Response instance
1499          * @throws ServletException If something unexpected happened
1500          */
1501         @Override
1502         public void doAdminHandleProductForms (final HttpServletRequest request, final HttpServletResponse response) throws ServletException {
1503                 // Trace message
1504                 this.getLogger().trace(MessageFormat.format("request={0},response={1} - CALLED!", request, response)); //NOI18N
1505
1506                 // request and response must both be set
1507                 if (request == null) {
1508                         // request is null
1509                         throw new NullPointerException("request is null"); //NOI18N
1510                 } else if (response == null) {
1511                         // response is null
1512                         throw new NullPointerException("response is null"); //NOI18N
1513                 }
1514
1515                 // Try this operations
1516                 try {
1517                         // Is it post?
1518                         if ("POST".equals(request.getMethod())) { //NOI18N
1519                                 // Is "add/edit/delete" set?
1520                                 if (request.getParameter("add") != null) { //NOI18N
1521                                         // Is it already added?
1522                                         if (this.isProductTitleUsed(request)) {
1523                                                 // Debug message
1524                                                 this.getLogger().debug("Already used, redirecting ..."); //NOI18N
1525
1526                                                 // Already added, so redirect here, else a ServletException will be thrown
1527                                                 response.sendRedirect(String.format("%s/admin/product.jsp?already=1", request.getContextPath())); //NOI18N
1528                                         } else {
1529                                                 // Add new product
1530                                                 this.doAdminAddProduct(request);
1531                                         }
1532                                 } else if (request.getParameter("edit") != null) { //NOI18N
1533                                         // @TODO
1534                                 } else if (request.getParameter("delete") != null) { //NOI18N
1535                                         // @TODO
1536                                 }
1537
1538                                 // Redirect to proper URL
1539                                 // @TODO Commented out for developing:
1540                                 //response.sendRedirect(request.getContextPath() + "/finished.jsp");
1541                         }
1542                 } catch (final IOException | SQLException | BadTokenException | CorruptedDatabaseFileException | ProductTitleAlreadyUsedException | NoSuchMethodException | IllegalAccessException | InvocationTargetException | IllegalArgumentException ex) {
1543                         // Throw it as cause
1544                         throw new ServletException(ex);
1545                 }
1546
1547                 // Trace message
1548                 this.getLogger().trace("EXIT!"); //NOI18N
1549         }
1550
1551         /**
1552          * Handles admin form requests
1553          * @param request Request instance
1554          * @param response Response instance
1555          * @throws ServletException If something unexpected happened
1556          */
1557         @Override
1558         public void doAdminHandleCategoryForms (final HttpServletRequest request, final HttpServletResponse response) throws ServletException {
1559                 // Trace message
1560                 this.getLogger().trace(MessageFormat.format("request={0},response={1} - CALLED!", request, response)); //NOI18N
1561
1562                 // request and response must both be set
1563                 if (request == null) {
1564                         // request is null
1565                         throw new NullPointerException("request is null"); //NOI18N
1566                 } else if (response == null) {
1567                         // response is null
1568                         throw new NullPointerException("response is null"); //NOI18N
1569                 }
1570
1571                 // Try this operations
1572                 try {
1573                         // Is it post?
1574                         if ("POST".equals(request.getMethod())) { //NOI18N
1575                                 // Is "add/edit/delete" set?
1576                                 if (request.getParameter("add") != null) { //NOI18N
1577                                         // Is the category title already used?
1578                                         if (this.isCategoryTitleUsed(request)) {
1579                                                 // Debug message
1580                                                 this.getLogger().debug("Already used, redirecting ..."); //NOI18N
1581
1582                                                 // Already added, so redirect here, else a ServletException will be thrown
1583                                                 response.sendRedirect(String.format("%s/admin/category.jsp?already=1", request.getContextPath())); //NOI18N
1584                                         } else {
1585                                                 // Add new category
1586                                                 this.doAdminAddCategory(request);
1587                                         }
1588                                 } else if (request.getParameter("edit") != null) { //NOI18N
1589                                         // @TODO
1590                                 } else if (request.getParameter("delete") != null) { //NOI18N
1591                                         // @TODO
1592                                 }
1593
1594                                 // Redirect to proper URL
1595                                 // @TODO Commented out for developing:
1596                                 //response.sendRedirect(request.getContextPath() + "/finished.jsp");
1597                         }
1598                 } catch (final IOException | SQLException | BadTokenException | CorruptedDatabaseFileException | CategoryTitleAlreadyUsedException | NoSuchMethodException | IllegalAccessException | InvocationTargetException | IllegalArgumentException ex) {
1599                         // Throw it as cause
1600                         throw new ServletException(ex);
1601                 }
1602
1603                 // Trace message
1604                 this.getLogger().trace("EXIT!"); //NOI18N
1605         }
1606
1607         /**
1608          * Checks if category's title is already used.
1609          * 
1610          * @param request Request instance
1611          * @return Whether the product title is already used
1612          * @throws java.io.IOException If any IO error occurs
1613          * @throws org.mxchange.jcore.exceptions.BadTokenException If a bad token was found in a file-based database backend's file ... ;-)
1614          * @throws java.sql.SQLException If any SQL error occurs
1615          * @throws org.mxchange.jcore.exceptions.CorruptedDatabaseFileException If the database file is damaged
1616          * @throws java.lang.NoSuchMethodException If a method was not found
1617          * @throws java.lang.IllegalAccessException If the method cannot be accessed
1618          * @throws java.lang.reflect.InvocationTargetException Any other problems?
1619          */
1620         private boolean isCategoryTitleUsed (final HttpServletRequest request) throws IOException, SQLException, BadTokenException, CorruptedDatabaseFileException, NoSuchMethodException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
1621                 // Trace message
1622                 this.getLogger().trace(MessageFormat.format("request={0} - CALLED!", request)); //NOI18N
1623
1624                 // Init title
1625                 String title = request.getParameter(PizzaCategoryDatabaseConstants.COLUMN_TITLE);
1626
1627                 // request must not be null and "title" must be found and non-empty
1628                 if (request == null) {
1629                         // Abort here
1630                         throw new NullPointerException("request is null"); //NOI18N
1631                 } else if (title == null) {
1632                         // title is not set
1633                         throw new IllegalArgumentException(MessageFormat.format("{0} is not set.", PizzaCategoryDatabaseConstants.COLUMN_TITLE)); //NOI18N
1634                 } else if (title.isEmpty()) {
1635                         // Is left empty
1636                         throw new IllegalArgumentException(MessageFormat.format("{0} is empty.", PizzaCategoryDatabaseConstants.COLUMN_TITLE)); //NOI18N
1637                 }
1638
1639                 // Default is not used
1640                 boolean isUsed = this.isCategoryTitleUsed(title);
1641
1642                 // Trace message
1643                 this.getLogger().trace(MessageFormat.format("isUsed={0} - EXIT!", isUsed)); //NOI18N
1644
1645                 // Return it
1646                 return isUsed;
1647         }
1648 }