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