]> 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          * @deprecated Old lost code
171          */
172         @Deprecated
173         private 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 HTML code 'disabled="disabled"' for e.g. submit buttons
248          *
249          * @param request Request instance
250          * @param session Session instance
251          * @return Whether the product is choosen
252          */
253         @Override
254         public String getDisabledHtmlFromSession (final HttpServletRequest request, final HttpSession session) throws ServletException {
255                 // Trace message
256                 this.getLogger().trace(MessageFormat.format("request={0},session={1} - CALLED!", request, session)); //NOI18N
257
258                 // Is product and session set?
259                 if (null == request) {
260                         // Not set
261                         throw new NullPointerException("request is null"); //NOI18N
262                 } else if (null == session) {
263                         // Not set
264                         throw new NullPointerException("session is null"); //NOI18N
265                 }
266
267                 // Get "enabled" from request scope
268                 Boolean enabled = Boolean.parseBoolean((String) request.getAttribute("enabled")); //NOI18N
269
270                 // Debug message
271                 this.getLogger().debug(MessageFormat.format("enabled={0}", enabled)); //NOI18N
272
273                 // Is something selected?
274                 if ((enabled) || (this.calculateTotalAmount(request, session) > 0)) {
275                         // Trace message
276                         this.getLogger().trace("Returning empty string - EXIT!"); //NOI18N
277
278                         // Something has been choosen
279                         return ""; //NOI18N
280                 } else {
281                         // Trace message
282                         this.getLogger().trace("Returning disabled=\"disabled\" - EXIT!"); //NOI18N
283
284                         // Nothing choosen yet
285                         return "disabled=\"disabled\""; //NOI18N
286                 }
287         }
288
289         /**
290          * Checks if given Product instance is available and returns a printable
291          * (human-readable) string.
292          * 
293          * @param product Product instance to check
294          * @return Human-readable version of product availability
295          */
296         @Override
297         public String getPrintableProduktAvailability (final Product product) {
298                 // Trace message
299                 this.getLogger().trace(MessageFormat.format("product={0} - CALLED!", product)); //NOI18N
300
301                 // Is it null?
302                 if (null == product) {
303                         // Should not be null
304                         throw new NullPointerException("product is null"); //NOI18N
305                 }
306
307                 // Get availability
308                 if (product.getAvailable() == true) {
309                         // Is available
310                         return "Ja";
311                 } else {
312                         // Not, not for public
313                         return "Nein";
314                 }
315         }
316
317         /**
318          * Some "getter" for a an array of only available products
319          *
320          * @return All products
321          */
322         @Override
323         public Iterator<Product> getAvailableProducts () throws ServletException {
324                 // categoryFrontend must be set
325                 if (null == this.productFrontend) {
326                         // Abort here
327                         throw new NullPointerException("productFrontend is null");
328                 }
329
330                 try {
331                         // Ask frontend for a list of products
332                         return this.productFrontend.getAvailableProducts();
333                 } catch (final IOException | BadTokenException | SQLException | CorruptedDatabaseFileException | NoSuchMethodException | IllegalAccessException | InvocationTargetException ex) {
334                         throw new ServletException(ex);
335                 }
336         }
337
338         /**
339          * Some "getter" for a an array of all products
340          *
341          * @return All products
342          */
343         @Override
344         public Iterator<Product> getAllProducts () throws ServletException {
345                 // Trace message
346                 this.getLogger().trace("CALLED!");
347
348                 // categoryFrontend must be set
349                 if (null == this.productFrontend) {
350                         // Abort here
351                         throw new NullPointerException("productFrontend is null");
352                 }
353
354                 try {
355                         // Ask frontend for a list of products
356                         return this.productFrontend.getAllProducts();
357                 } catch (final IOException | BadTokenException | SQLException | CorruptedDatabaseFileException | NoSuchMethodException | IllegalAccessException | InvocationTargetException ex) {
358                         throw new ServletException(ex);
359                 }
360         }
361
362         /**
363          * Some "getter" for a an array of all categories
364          *
365          * @return All categories
366          */
367         @Override
368         public Iterator<Category> getAllCategories () throws ServletException {
369                 // Trace message
370                 this.getLogger().trace("CALLED!");
371
372                 // categoryFrontend must be set
373                 if (null == this.categoryFrontend) {
374                         // Abort here
375                         throw new NullPointerException("categoryFrontend is null");
376                 }
377
378                 try {
379                         // Ask frontend for a list of categories
380                         return this.categoryFrontend.getAllCategories();
381                 } catch (final IOException | BadTokenException | SQLException | CorruptedDatabaseFileException | NoSuchMethodException | IllegalAccessException | InvocationTargetException ex) {
382                         throw new ServletException(ex);
383                 }
384         }
385
386         /**
387          * Checks whether the given product is choosen, request overules session.
388          *
389          * @param product Product instance
390          * @param request Request instance
391          * @param session Session instance
392          * @return Whether the product is choosen
393          */
394         @Override
395         @Deprecated
396         public boolean isProductChoosen (final Product product, final HttpServletRequest request, final HttpSession session) {
397                 throw new UnsupportedOperationException("This method is deprecated and shall not be called");
398         }
399
400         /**
401          * Somewhat setter in session
402          *
403          * @param session Session instance
404          * @param key Session key to set
405          * @param value Value to set
406          */
407         @Override
408         public void setValueInSession (final HttpSession session, final String key, final Object value) {
409                 // Trace message
410                 this.getLogger().trace(MessageFormat.format("session={0},key={1},value={2} - CALLED!", session, key, value)); //NOI18N
411
412                 synchronized(session) {
413                         // Set it synced
414                         session.setAttribute(key, value);
415                 }
416
417                 // Trace message
418                 this.getLogger().trace("EXIT!"); //NOI18N
419         }
420
421         /**
422          * Clears given parameter for product in session
423          *
424          * @param product Product instance
425          * @param session Session instance
426          * @param parameter Parameter to clear
427          */
428         private void clearSessionAttribute (final Product product, final HttpSession session, final String parameter) {
429                 // Trace message
430                 this.getLogger().trace(MessageFormat.format("produce={0},parameter={1},session={2} - CALLED!", product, parameter, session)); //NOI18N
431
432                 // Clear in session
433                 this.getLogger().debug(MessageFormat.format("Clearing product={0},parameter={1} ...", product.getItemId(), parameter)); //NOI18N
434                 this.setValueInSession(product, session, parameter, null);
435
436                 // Trace message
437                 this.getLogger().trace("EXIT!"); //NOI18N
438         }
439
440         /**
441          * Some getter for value from session
442          *
443          * @param product Product instance
444          * @param session Session instance
445          * @param attribute Attribute to get value from
446          * @return Value from session
447          */
448         private Object getValueFromSession (final Product product, final HttpSession session, final String attribute) {
449                 // Trace message
450                 this.getLogger().trace(MessageFormat.format("product={0},session={1},attribute={2} - CALLED!", product, session, attribute)); //NOI18N
451
452                 // Init variable
453                 Object value = this.getValueFromSession(session, String.format(HTTP_PARAM_MASK, attribute, product.getItemId()));
454                 
455                 this.getLogger().debug(MessageFormat.format("product={0},attribute={1},value={2}", product.getItemId(), attribute, value)); //NOI18N
456
457                 // Trace message
458                 this.getLogger().trace(MessageFormat.format("value={0} - EXIT!", value)); //NOI18N
459
460                 // Return it
461                 return value;
462         }
463
464         /**
465          * Some getter for value from session
466          *
467          * @param session Session instance
468          * @param key Key to get value from
469          * @return Value from session
470          */
471         private Object getValueFromSession (final HttpSession session, final String key) {
472                 // Trace message
473                 this.getLogger().trace(MessageFormat.format("session={0},key={1} - CALLED!", session, key)); //NOI18N
474
475                 // Init value
476                 Object value;
477
478                 // Get it synchronized from session
479                 synchronized (session) {
480                         value = session.getAttribute(key);
481                 }
482
483                 // Trace message
484                 this.getLogger().trace(MessageFormat.format("value={0} - EXIT!", value)); //NOI18N
485
486                 // Return it
487                 return value;
488         }
489
490         /**
491          * Initializes database frontends.
492          */
493         private void initDatabaseFrontends () throws UnsupportedDatabaseBackendException, SQLException {
494                 // Trace message
495                 this.getLogger().trace("CALLED!"); //NOI18N
496
497                 // Product frontend
498                 this.productFrontend = new ProductDatabaseFrontend();
499
500                 // Category frontend
501                 this.categoryFrontend = new CategoryDatabaseFrontend();
502
503                 // Trace message
504                 this.getLogger().trace("EXIT!"); //NOI18N
505         }
506
507         /**
508          * Checks whether given category title is already used
509          *
510          * @param title Title of category to check
511          * @return Whether it has been found
512          */
513         private boolean isCategoryTitleUsed(final String title) throws IOException, SQLException, BadTokenException, CorruptedDatabaseFileException, NoSuchMethodException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
514                 // categoryFrontend must be set
515                 if (null == this.categoryFrontend) {
516                         // Abort here
517                         throw new NullPointerException("categoryFrontend is null");
518                 }
519
520                 // Delegate to frontend
521                 return this.categoryFrontend.isCategoryTitleUsed(title);
522         }
523
524         /**
525          * Checks if given product title is already used
526          * @param title Product title to check
527          * @return Whether the product title has already been used
528          */
529         private boolean isProductTitleUsed (final String title) throws IOException, SQLException, BadTokenException, CorruptedDatabaseFileException, NoSuchMethodException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
530                 // categoryFrontend must be set
531                 if (null == this.productFrontend) {
532                         // Abort here
533                         throw new NullPointerException("productFrontend is null");
534                 }
535
536                 // Delegate to frontend
537                 return this.productFrontend.isProductTitleUsed(title);
538         }
539
540         /**
541          * Checks if the product ordered?
542          *
543          * @param product Product instance
544          * @param session HttpSession instance
545          * @return Whether the product has been ordered
546          */
547         private boolean isProductOrdered (final Product product, final HttpSession session) {
548                 // Trace message
549                 this.getLogger().trace(MessageFormat.format("product={0},session={1} - CALLED!", product, session)); //NOI18N
550
551                 // Get session
552                 Object isOrdered = this.getValueFromSession(product, session, SESSION_ORDERED);
553                 this.getLogger().debug(MessageFormat.format("product={0},isOrdered={1}", product.getItemId(), isOrdered)); //NOI18N
554
555                 // Return result
556                 return ("true".equals(isOrdered)); //NOI18N
557         }
558
559         /**
560          * Somewhat setter in session
561          *
562          * @param product Product instance
563          * @param session Session instance
564          * @param keyPart Key part to include in final key
565          * @param value Value to set
566          */
567         private void setValueInSession (final Product product, final HttpSession session, final String keyPart, final Object value) {
568                 // Trace message
569                 this.getLogger().trace(MessageFormat.format("product={0},session={1},keyPart={2},value={3} - CALLED!", product, session, keyPart, value)); //NOI18N
570
571                 // Set it synced
572                 this.getLogger().debug(MessageFormat.format("Setting value={0} for product={1},keyPart={2}", value, product.getItemId(), keyPart)); //NOI18N
573                 this.setValueInSession(session, String.format(HTTP_PARAM_MASK, keyPart, product.getItemId()), value);
574
575                 // Trace message
576                 this.getLogger().trace("EXIT!"); //NOI18N
577         }
578
579         /**
580          * Adds given category data from request to database
581          *
582          * @param request Request instance
583          */
584         @Override
585         public void doAdminAddCategory (final HttpServletRequest request) throws ServletException, CategoryTitleAlreadyUsedException {
586                 // Trace message
587                 this.getLogger().trace(MessageFormat.format("request={0} - CALLED!", request)); //NOI18N
588
589                 // request must not be null
590                 if (null == request) {
591                         // Is null
592                         throw new NullPointerException("request is null"); //NOI18N
593                 }
594
595                 // Get all fields
596                 String title = request.getParameter(CategoryFrontend.COLUMN_TITLE);
597                 String parent = request.getParameter(CategoryFrontend.COLUMN_PARENT);
598
599                 // Debug message
600                 this.getLogger().debug(MessageFormat.format("title={0},parent={1}", title, parent)); //NOI18N
601
602                 // Init variables for casting
603                 Integer id = 0;
604
605                 // Check all fields
606                 if (null == title) {
607                         // "title" not set
608                         throw new IllegalArgumentException(MessageFormat.format("{0} is not set.", CategoryFrontend.COLUMN_TITLE)); //NOI18N
609                 } else if (title.isEmpty()) {
610                         // Is left empty
611                         throw new IllegalArgumentException(MessageFormat.format("{0} is empty.", CategoryFrontend.COLUMN_TITLE)); //NOI18N
612                 } else if ((parent != null) && (!parent.isEmpty())) {
613                         // "parent" is set, so check it
614                         try {
615                                 id = Integer.parseInt(parent);
616                         } catch (final NumberFormatException e) {
617                                 // Not valid number
618                                 throw new IllegalArgumentException(e);
619                         }
620                 }
621
622                 try {
623                         // Try to check if title is used already
624                         if (this.isCategoryTitleUsed(title)) {
625                                 // Title already used
626                                 throw new CategoryTitleAlreadyUsedException(request);
627                         }
628                 } catch (final IOException | SQLException | BadTokenException | CorruptedDatabaseFileException | NoSuchMethodException | IllegalAccessException | InvocationTargetException ex) {
629                         throw new ServletException(ex);
630                 }
631
632                 try {
633                         // The category is not found, so add it to database
634                         this.categoryFrontend.addCategory(title, id);
635                 } catch (final SQLException | IOException ex) {
636                         // Continue to throw it
637                         throw new ServletException(ex);
638                 }
639
640                 // Trace message
641                 this.getLogger().trace("EXIT!"); //NOI18N
642         }
643
644         /**
645          * Adds given product data from request to database
646          *
647          * @param request Request instance
648          */
649         @Override
650         public void doAdminAddProduct (final HttpServletRequest request) throws ServletException, ProductTitleAlreadyUsedException {
651                 // Trace message
652                 this.getLogger().trace(MessageFormat.format("request={0} - CALLED!", request)); //NOI18N
653
654                 // request must not be null
655                 if (null == request) {
656                         // Is null
657                         throw new NullPointerException("request is null"); //NOI18N
658                 }
659
660                 // Get title, price and category id
661                 String title = request.getParameter(ProductFrontend.COLUMN_TITLE);
662                 String price = request.getParameter(ProductFrontend.COLUMN_PRICE);
663                 String category = request.getParameter(ProductFrontend.COLUMN_CATEGORY);
664                 String available = request.getParameter(ProductFrontend.COLUMN_AVAILABLE);
665
666                 // Debug message
667                 this.getLogger().debug(MessageFormat.format("title={0},price={1},category={2},available={3}", title, price, category, available)); //NOI18N
668
669                 // Variables for converting
670                 Long id = null;
671                 Float p = null;
672
673                 // Check all fields
674                 if (null == title) {
675                         // "title" not set
676                         throw new IllegalArgumentException(MessageFormat.format("{0} is not set.", ProductFrontend.COLUMN_TITLE)); //NOI18N
677                 } else if (title.isEmpty()) {
678                         // Is left empty
679                         throw new IllegalArgumentException(MessageFormat.format("{0} is empty.", ProductFrontend.COLUMN_TITLE)); //NOI18N
680                 } else if (null == price) {
681                         // "price" not set
682                         throw new IllegalArgumentException(MessageFormat.format("{0} is not set.", ProductFrontend.COLUMN_PRICE)); //NOI18N
683                 } else if (price.isEmpty()) {
684                         // Is left empty
685                         throw new IllegalArgumentException(MessageFormat.format("{0} is empty.", ProductFrontend.COLUMN_PRICE)); //NOI18N
686                 } else if (null == category) {
687                         // "title" not set
688                         throw new IllegalArgumentException(MessageFormat.format("{0} is not set.", ProductFrontend.COLUMN_CATEGORY)); //NOI18N
689                 } else if (category.isEmpty()) {
690                         // Is left empty
691                         throw new IllegalArgumentException(MessageFormat.format("{0} is empty.", ProductFrontend.COLUMN_CATEGORY)); //NOI18N
692                 } else if (null == available) {
693                         // "title" not set
694                         throw new IllegalArgumentException(MessageFormat.format("{0} is not set.", ProductFrontend.COLUMN_AVAILABLE)); //NOI18N
695                 } else if (available.isEmpty()) {
696                         // Is left empty
697                         throw new IllegalArgumentException(MessageFormat.format("{0} is empty.", ProductFrontend.COLUMN_AVAILABLE)); //NOI18N
698                 } else if ((!"true".equals(available)) && (!"false".equals(available))) { //NOI18N
699                         // Invalid value
700                         throw new IllegalArgumentException(MessageFormat.format("{0} is invalid: {1}", ProductFrontend.COLUMN_AVAILABLE, available)); //NOI18N
701                 }
702
703                 // Parse numbers
704                 try {
705                         id = Long.parseLong(category);
706                         p = Float.parseFloat(price);
707                 } catch (final NumberFormatException e) {
708                         // Not valid number
709                         throw new IllegalArgumentException(e);
710                 }
711
712                 // Parse boolean
713                 Boolean a = Boolean.parseBoolean(available);
714
715                 // Test on product title
716                 try {
717                         // Try to check if title is used already
718                         if (this.isProductTitleUsed(title)) {
719                                 // Title already used
720                                 throw new ProductTitleAlreadyUsedException(request);
721                         }
722                 } catch (final IOException | SQLException | BadTokenException | CorruptedDatabaseFileException | NoSuchMethodException | IllegalAccessException | InvocationTargetException ex) {
723                         throw new ServletException(ex);
724                 }
725
726                 try {
727                         // The product is not found, so add it to database
728                         this.productFrontend.addProduct(title, p, id, a);
729                 } catch (final SQLException | IOException ex) {
730                         // Continue to throw it
731                         throw new ServletException(ex);
732                 }
733
734                 // Trace message
735                 this.getLogger().trace("EXIT!"); //NOI18N
736         }
737
738         /**
739          * Generates link HTML code for given category's parent id, if set. This
740          * link then points to products.jsp?category_id=x
741          *
742          * @param category Category instance
743          * @return HTML code
744          */
745         @Override
746         public String generateLinkForParent (final Category category) {
747                 // Trace message
748                 this.getLogger().trace(MessageFormat.format("category={0} - CALLED!", category)); //NOI18N
749
750                 // category must not be null
751                 if (null == category) {
752                         // Is null
753                         throw new NullPointerException("category is null"); //NOI18N
754                 }
755
756                 // Get parent id
757                 Long parent = category.getParent();
758
759                 // Is the id set?
760                 if (parent > 0) {
761                         // Product HTML code for link
762                         throw new UnsupportedOperationException(MessageFormat.format("parent={0} - Unfinished!", parent)); //NOI18N
763                 }
764
765                 // No parent set
766                 return "Keine";
767         }
768
769         @Override
770         public String getPrintableProduktCategory (final Product product) throws ServletException {
771                 // Trace message
772                 this.getLogger().trace(MessageFormat.format("product={0} - CALLED!", product)); //NOI18N
773
774                 // product must not be null
775                 if (null == product) {
776                         // Abort here
777                         throw new NullPointerException("product is null"); //NOI18N
778                 }
779
780                 // Declare category
781                 Category category;
782
783                 try {
784                         // Get Category instance from product over the frontend
785                         category = this.categoryFrontend.getCategory(product);
786                 } catch (final IOException | SQLException | BadTokenException | CorruptedDatabaseFileException | NoSuchMethodException | IllegalAccessException | IllegalArgumentException | InvocationTargetException ex) {
787                         throw new ServletException(ex);
788                 }
789
790                 // Debug message
791                 this.getLogger().debug(MessageFormat.format("category={0}", category)); //NOI18N
792
793                 String title = null;
794                 try {
795                         // Now get title from it and return it
796                         title = category.getDecodedTitle();
797                 } catch (final UnsupportedEncodingException ex) {
798                         // Continue to throw as cause
799                         throw new ServletException(ex);
800                 }
801
802                 // Trace message
803                 this.getLogger().trace(MessageFormat.format("title={0} - EXIT!", title)); //NOI18N
804
805                 // Return it
806                 return title;
807         }
808
809         /**
810          * Checks if product's title is already used.
811          * 
812          * @param request Request instance
813          * @return Whether the product title is already used
814          * @throws java.io.IOException If any IO error occurs
815          * @throws org.mxchange.jcore.exceptions.BadTokenException If a bad token was found in a file-based database backend's file ... ;-)
816          * @throws java.sql.SQLException If any SQL error occurs
817          * @throws org.mxchange.jcore.exceptions.CorruptedDatabaseFileException If the database file is damaged
818          * @throws java.lang.NoSuchMethodException If a method was not found
819          * @throws java.lang.IllegalAccessException If the method cannot be accessed
820          * @throws java.lang.reflect.InvocationTargetException Any other problems?
821          */
822         private boolean isProductTitleUsed (final HttpServletRequest request) throws IOException, SQLException, BadTokenException, CorruptedDatabaseFileException, NoSuchMethodException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
823                 // Trace message
824                 this.getLogger().trace(MessageFormat.format("request={0} - CALLED!", request)); //NOI18N
825
826                 // Init title
827                 String title = request.getParameter(ProductFrontend.COLUMN_TITLE);
828
829                 // request must not be null and "title" must be found and non-empty
830                 if (null == request) {
831                         // Abort here
832                         throw new NullPointerException("request is null"); //NOI18N
833                 } else if (null == title) {
834                         // title is not set
835                         throw new IllegalArgumentException(MessageFormat.format("{0} is not set.", ProductFrontend.COLUMN_TITLE)); //NOI18N
836                 } else if (title.isEmpty()) {
837                         // Is left empty
838                         throw new IllegalArgumentException(MessageFormat.format("{0} is empty.", ProductFrontend.COLUMN_TITLE)); //NOI18N
839                 }
840
841                 // Default is not used
842                 boolean isUsed = this.isProductTitleUsed(title);
843
844                 // Trace message
845                 this.getLogger().trace(MessageFormat.format("isUsed={0} - EXIT!", isUsed)); //NOI18N
846
847                 // Return it
848                 return isUsed;
849         }
850
851         /**
852          * Handles admin form requests
853          * @param request Request instance
854          * @param response Response instance
855          * @throws ServletException If something unexpected happened
856          */
857         @Override
858         public void doAdminHandleProductForms (final HttpServletRequest request, final HttpServletResponse response) throws ServletException {
859                 // Trace message
860                 this.getLogger().trace(MessageFormat.format("request={0},response={1} - CALLED!", request, response)); //NOI18N
861
862                 // request and response must both be set
863                 if (null == request) {
864                         // request is null
865                         throw new NullPointerException("request is null"); //NOI18N
866                 } else if (null == response) {
867                         // response is null
868                         throw new NullPointerException("response is null"); //NOI18N
869                 }
870
871                 // Try this operations
872                 try {
873                         // Is it post?
874                         if ("POST".equals(request.getMethod())) { //NOI18N
875                                 // Is "add/edit/delete" set?
876                                 if (request.getParameter("add") != null) { //NOI18N
877                                         // Is it already added?
878                                         if (this.isProductTitleUsed(request)) {
879                                                 // Debug message
880                                                 this.getLogger().debug("Already used, redirecting ..."); //NOI18N
881
882                                                 // Already added, so redirect here, else a ServletException will be thrown
883                                                 response.sendRedirect(String.format("%s/admin/product.jsp?already=1", request.getContextPath())); //NOI18N
884                                         } else {
885                                                 // Add new product
886                                                 this.doAdminAddProduct(request);
887                                         }
888                                 } else if (request.getParameter("edit") != null) { //NOI18N
889                                         // @TODO
890                                 } else if (request.getParameter("delete") != null) { //NOI18N
891                                         // @TODO
892                                 }
893
894                                 // Redirect to proper URL
895                                 // @TODO Commented out for developing:
896                                 //response.sendRedirect(request.getContextPath() + "/finished.jsp");
897                         }
898                 } catch (final IOException | SQLException | BadTokenException | CorruptedDatabaseFileException | ProductTitleAlreadyUsedException | NoSuchMethodException | IllegalAccessException | InvocationTargetException | IllegalArgumentException ex) {
899                         // Throw it as cause
900                         throw new ServletException(ex);
901                 }
902
903                 // Trace message
904                 this.getLogger().trace("EXIT!"); //NOI18N
905         }
906
907         /**
908          * Handles admin form requests
909          * @param request Request instance
910          * @param response Response instance
911          * @throws ServletException If something unexpected happened
912          */
913         @Override
914         public void doAdminHandleCategoryForms (final HttpServletRequest request, final HttpServletResponse response) throws ServletException {
915                 // Trace message
916                 this.getLogger().trace(MessageFormat.format("request={0},response={1} - CALLED!", request, response)); //NOI18N
917
918                 // request and response must both be set
919                 if (null == request) {
920                         // request is null
921                         throw new NullPointerException("request is null"); //NOI18N
922                 } else if (null == response) {
923                         // response is null
924                         throw new NullPointerException("response is null"); //NOI18N
925                 }
926
927                 // Try this operations
928                 try {
929                         // Is it post?
930                         if ("POST".equals(request.getMethod())) { //NOI18N
931                                 // Is "add/edit/delete" set?
932                                 if (request.getParameter("add") != null) { //NOI18N
933                                         // Is the category title already used?
934                                         if (this.isCategoryTitleUsed(request)) {
935                                                 // Debug message
936                                                 this.getLogger().debug("Already used, redirecting ..."); //NOI18N
937
938                                                 // Already added, so redirect here, else a ServletException will be thrown
939                                                 response.sendRedirect(String.format("%s/admin/category.jsp?already=1", request.getContextPath())); //NOI18N
940                                         } else {
941                                                 // Add new category
942                                                 this.doAdminAddCategory(request);
943                                         }
944                                 } else if (request.getParameter("edit") != null) { //NOI18N
945                                         // @TODO
946                                 } else if (request.getParameter("delete") != null) { //NOI18N
947                                         // @TODO
948                                 }
949
950                                 // Redirect to proper URL
951                                 // @TODO Commented out for developing:
952                                 //response.sendRedirect(request.getContextPath() + "/finished.jsp");
953                         }
954                 } catch (final IOException | SQLException | BadTokenException | CorruptedDatabaseFileException | CategoryTitleAlreadyUsedException | NoSuchMethodException | IllegalAccessException | InvocationTargetException | IllegalArgumentException ex) {
955                         // Throw it as cause
956                         throw new ServletException(ex);
957                 }
958
959                 // Trace message
960                 this.getLogger().trace("EXIT!"); //NOI18N
961         }
962
963         /**
964          * Checks if category's title is already used.
965          * 
966          * @param request Request instance
967          * @return Whether the product title is already used
968          * @throws java.io.IOException If any IO error occurs
969          * @throws org.mxchange.jcore.exceptions.BadTokenException If a bad token was found in a file-based database backend's file ... ;-)
970          * @throws java.sql.SQLException If any SQL error occurs
971          * @throws org.mxchange.jcore.exceptions.CorruptedDatabaseFileException If the database file is damaged
972          * @throws java.lang.NoSuchMethodException If a method was not found
973          * @throws java.lang.IllegalAccessException If the method cannot be accessed
974          * @throws java.lang.reflect.InvocationTargetException Any other problems?
975          */
976         private boolean isCategoryTitleUsed (final HttpServletRequest request) throws IOException, SQLException, BadTokenException, CorruptedDatabaseFileException, NoSuchMethodException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
977                 // Trace message
978                 this.getLogger().trace(MessageFormat.format("request={0} - CALLED!", request)); //NOI18N
979
980                 // Init title
981                 String title = request.getParameter(CategoryFrontend.COLUMN_TITLE);
982
983                 // request must not be null and "title" must be found and non-empty
984                 if (null == request) {
985                         // Abort here
986                         throw new NullPointerException("request is null"); //NOI18N
987                 } else if (null == title) {
988                         // title is not set
989                         throw new IllegalArgumentException(MessageFormat.format("{0} is not set.", CategoryFrontend.COLUMN_TITLE)); //NOI18N
990                 } else if (title.isEmpty()) {
991                         // Is left empty
992                         throw new IllegalArgumentException(MessageFormat.format("{0} is empty.", CategoryFrontend.COLUMN_TITLE)); //NOI18N
993                 }
994
995                 // Default is not used
996                 boolean isUsed = this.isCategoryTitleUsed(title);
997
998                 // Trace message
999                 this.getLogger().trace(MessageFormat.format("isUsed={0} - EXIT!", isUsed)); //NOI18N
1000
1001                 // Return it
1002                 return isUsed;
1003         }
1004
1005         @Override
1006         public Product getProduct (final AddableBasketItem item) throws ServletException {
1007                 // Trace message
1008                 this.getLogger().trace("item=" + item + " - CALLED!");
1009
1010                 // item should not be null
1011                 if (null == item) {
1012                         // Abort here
1013                         throw new NullPointerException("item is null");
1014                 } else if (null == this.productFrontend) {
1015                         // Abort here
1016                         throw new NullPointerException("productFrontend is null");
1017                 }
1018
1019                 // Init product instance
1020                 Product product = null;
1021
1022                 try {
1023                         // Call frontend
1024                         product = this.productFrontend.getProduct(item);
1025                 } catch (final SQLException | IOException | BadTokenException | CorruptedDatabaseFileException | NoSuchMethodException | IllegalAccessException | IllegalArgumentException | InvocationTargetException ex) {
1026                         // Continue to throw
1027                         throw new ServletException(ex);
1028                 }
1029
1030                 // Trace message
1031                 this.getLogger().trace("product=" + product + " - EXIT!");
1032
1033                 // Return it
1034                 return product;
1035         }
1036 }