You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
-->
-<Configuration status="WARN">
+<Configuration status="INFO">
<Appenders>
<Console name="STDOUT" target="SYSTEM_OUT">
<PatternLayout pattern="%d %-5p [%t] %C{2} (%F:%L) - %m%n"/>
</Appenders>
<Loggers>
<Root level="trace">
- <AppenderRef ref="STDERR" level="WARNING"/>
<AppenderRef ref="STDOUT" level="TRACE"/>
</Root>
</Loggers>
*/
public String getPrintableProduktAvailability (final Product product);
+ /**
+ * Returns a printable (human-readable) string of product's category
+ *
+ * @param product Product instance to check
+ * @return Human-readable version of product availability
+ * @throws javax.servlet.ServletException If something unexpected happened
+ */
+ public String getPrintableProduktCategory (final Product product) throws ServletException;
+
/**
* Marks all choosen products as ordered
*
*/
public void doAdminAddProduct (final HttpServletRequest request) throws ServletException, ProductTitleAlreadyUsedException;
+ /**
+ * Checks if product's title is already used.
+ *
+ * @param request Request instance
+ * @return Whether the product's title has already been used
+ * @throws javax.servlet.ServletException If something unexpected happened
+ */
+ public boolean isProductTitleUsed (final HttpServletRequest request) throws ServletException;
+
/**
* Generates link HTML code for given category's parent id, if set. This
* link then points to products.jsp?category_id=x
*/
package org.mxchange.pizzaapplication.application;
-import org.mxchange.pizzaapplication.exceptions.CategoryTitleAlreadyUsedException;
import java.io.IOException;
+import java.io.UnsupportedEncodingException;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.sql.SQLException;
import java.text.MessageFormat;
import java.util.Iterator;
import java.util.Map;
+import java.util.logging.Level;
+import java.util.logging.Logger;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import org.mxchange.pizzaapplication.database.frontend.product.PizzaProductDatabaseFrontend;
import org.mxchange.pizzaapplication.database.frontend.product.ProductFrontend;
import org.mxchange.pizzaapplication.database.product.PizzaProductDatabaseConstants;
+import org.mxchange.pizzaapplication.exceptions.CategoryTitleAlreadyUsedException;
import org.mxchange.pizzaapplication.exceptions.ProductTitleAlreadyUsedException;
import org.mxchange.pizzaapplication.product.Product;
// No parent set
return "Keine";
}
+
+ @Override
+ public String getPrintableProduktCategory (final Product product) throws ServletException {
+ // Trace message
+ this.getLogger().trace("product=" + product + " - CALLED!");
+
+ // product must not be null
+ if (product == null) {
+ // Abort here
+ throw new NullPointerException("product is null");
+ }
+
+ // Declare category
+ Category category;
+
+ try {
+ // Get Category instance from product over the frontend
+ category = this.categoryFrontend.getCategory(product);
+ } catch (final IOException | SQLException | BadTokenException | CorruptedDatabaseFileException | NoSuchMethodException | IllegalAccessException | IllegalArgumentException | InvocationTargetException ex) {
+ throw new ServletException(ex);
+ }
+
+ // Debug message
+ this.getLogger().debug("category=" + category);
+
+ String title = null;
+ try {
+ // Now get title from it and return it
+ title = category.decodedTitle();
+ } catch (final UnsupportedEncodingException ex) {
+ // Continue to throw as cause
+ throw new ServletException(ex);
+ }
+
+ // Trace message
+ this.getLogger().trace("title=" + title + " - EXIT!");
+
+ // Return it
+ return title;
+ }
+
+ @Override
+ public boolean isProductTitleUsed (final HttpServletRequest request) throws ServletException {
+ // Trace message
+ this.getLogger().trace("request=" + request + " - CALLED!");
+
+ // Init title
+ String title = request.getParameter(PizzaProductDatabaseConstants.COLUMN_TITLE);
+
+ // request must not be null and "title" must be found and non-empty
+ if (request == null) {
+ // Abort here
+ throw new NullPointerException("request is null");
+ } else if (title == null) {
+ // title is not set
+ throw new IllegalArgumentException(MessageFormat.format("{0} is not set.", PizzaProductDatabaseConstants.COLUMN_TITLE)); //NOI18N
+ } else if (title.isEmpty()) {
+ // Is left empty
+ throw new IllegalArgumentException(MessageFormat.format("{0} is empty.", PizzaProductDatabaseConstants.COLUMN_TITLE)); //NOI18N
+ }
+
+ // Default is not used
+ boolean isUsed = false;
+
+ try {
+ // So that all is tested, try to find the product
+ isUsed = this.isProductTitleUsed(title);
+ } catch (final IOException | SQLException | BadTokenException | CorruptedDatabaseFileException | NoSuchMethodException | IllegalAccessException | IllegalArgumentException | InvocationTargetException ex) {
+ // Continue to throw all as cause
+ throw new ServletException(ex);
+ }
+
+ // Trace message
+ this.getLogger().trace("isUsed=" + isUsed + " - EXIT!");
+
+ // Return it
+ return isUsed;
+ }
}
import org.mxchange.jcore.exceptions.BadTokenException;
import org.mxchange.jcore.exceptions.CorruptedDatabaseFileException;
import org.mxchange.pizzaapplication.category.Category;
+import org.mxchange.pizzaapplication.product.Product;
/**
* An interface for product database frontends
* @throws java.lang.reflect.InvocationTargetException Any other problems?
*/
public boolean isCategoryTitleUsed (final String title) throws IOException, SQLException, BadTokenException, CorruptedDatabaseFileException, NoSuchMethodException, IllegalAccessException, IllegalArgumentException, InvocationTargetException;
+
+ /**
+ * Gets a Category instance for given Product instance.
+ *
+ * @param product Product instance
+ * @return A category instance
+ * @throws java.io.IOException If any IO error occurs
+ * @throws org.mxchange.jcore.exceptions.BadTokenException If a bad token was found in a file-based database backend's file ... ;-)
+ * @throws java.sql.SQLException If any SQL error occurs
+ * @throws org.mxchange.jcore.exceptions.CorruptedDatabaseFileException If the database file is damaged
+ * @throws java.lang.NoSuchMethodException If a method was not found
+ * @throws java.lang.IllegalAccessException If the method cannot be accessed
+ * @throws java.lang.reflect.InvocationTargetException Any other problems?
+ */
+ public Category getCategory (final Product product) throws IOException, SQLException, BadTokenException, CorruptedDatabaseFileException, NoSuchMethodException, IllegalAccessException, IllegalArgumentException, InvocationTargetException;
}
import java.util.Iterator;
import java.util.Map;
import org.mxchange.jcore.criteria.searchable.SearchCriteria;
-import org.mxchange.jcore.criteria.searchable.SearchableCritera;
+import org.mxchange.jcore.criteria.searchable.SearchableCriteria;
import org.mxchange.jcore.database.frontend.BaseDatabaseFrontend;
import org.mxchange.jcore.database.result.DatabaseResult;
import org.mxchange.jcore.database.result.Result;
import org.mxchange.pizzaapplication.category.Category;
import org.mxchange.pizzaapplication.category.product.ProductCategory;
import org.mxchange.pizzaapplication.database.category.PizzaCategoryDatabaseConstants;
+import org.mxchange.pizzaapplication.product.Product;
/**
* Stores and retrieves Contact instances
this.getLogger().trace("CALLED!"); //NOI18N
// Instance search criteria
- SearchableCritera critera = new SearchCriteria();
+ SearchableCriteria critera = new SearchCriteria();
// Run the query
Result<? extends Storeable> result = this.getBackend().doSelectByCriteria(critera);
this.getLogger().trace(MessageFormat.format("title={0} - CALLED!", title));
// Get search criteria
- SearchableCritera criteria = new SearchCriteria();
+ SearchableCriteria criteria = new SearchCriteria();
// Add criteria
criteria.addCriteria(PizzaCategoryDatabaseConstants.COLUMN_TITLE, title);
Result<? extends Storeable> result = this.getBackend().doSelectByCriteria(criteria);
// Debug log
- this.getLogger().debug(MessageFormat.format("result({0}={1}", result, result.size()));
+ this.getLogger().debug(MessageFormat.format("result({0})={1}", result, result.size()));
// Now check size of the result
boolean isFound = (result.size() == 1);
// Return column id
return PizzaCategoryDatabaseConstants.COLUMN_ID;
}
+
+ @Override
+ public Category getCategory (final Product product) throws IOException, BadTokenException, CorruptedDatabaseFileException, SQLException, NoSuchMethodException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
+ // Trace message
+ this.getLogger().trace("product=" + product + " - CALLED!");
+
+ // product must not be null
+ if (product == null) {
+ // Abort here
+ throw new NullPointerException("product is null");
+ }
+
+ // Get category id from it
+ Long id = product.getCategory();
+
+ // Debug message
+ this.getLogger().debug("id=" + id);
+
+ // It should be >0 here
+ assert(id > 0) : "id=" + id + " must be larger zero";
+
+ // Then construct a search instance
+ SearchableCriteria criteria = new SearchCriteria();
+
+ // Add id to it
+ criteria.addCriteria(PizzaCategoryDatabaseConstants.COLUMN_ID, id);
+
+ // Only one entry is find
+ criteria.setLimit(1);
+
+ // Run it on backend
+ Result<? extends Storeable> result = this.getBackend().doSelectByCriteria(criteria);
+
+ // Debug log
+ this.getLogger().debug(MessageFormat.format("result({0})={1}", result, result.size()));
+
+ // Init category instance
+ Category category = null;
+
+ // Is there one entry?
+ if (result.hasNext()) {
+ // Read result from it
+ Storeable storeable = result.next();
+
+ // Debug message
+ this.getLogger().debug("storeable=" + storeable);
+
+ // Is it instance of Category?
+ if (storeable instanceof Category) {
+ // Then cast it
+ category = (Category) storeable;
+ }
+ }
+
+ // Trace message
+ this.getLogger().trace("category=" + category + " - EXIT!");
+
+ // Return it
+ return category;
+ }
}
import java.util.Iterator;
import java.util.Map;
import org.mxchange.jcore.criteria.searchable.SearchCriteria;
-import org.mxchange.jcore.criteria.searchable.SearchableCritera;
+import org.mxchange.jcore.criteria.searchable.SearchableCriteria;
import org.mxchange.jcore.database.frontend.BaseDatabaseFrontend;
import org.mxchange.jcore.database.result.DatabaseResult;
import org.mxchange.jcore.database.result.Result;
this.getLogger().trace("CALLED!"); //NOI18N
// Instance search criteria
- SearchableCritera critera = new SearchCriteria();
+ SearchableCriteria critera = new SearchCriteria();
// Add criteria
critera.addCriteria(PizzaProductDatabaseConstants.COLUMN_AVAILABLE, true);
this.getLogger().trace("CALLED!"); //NOI18N
// Instance search criteria
- SearchableCritera critera = new SearchCriteria();
+ SearchableCriteria critera = new SearchCriteria();
// Run the query
Result<? extends Storeable> result = this.getBackend().doSelectByCriteria(critera);
this.getLogger().trace(MessageFormat.format("title={0} - CALLED!", title));
// Get search criteria
- SearchableCritera criteria = new SearchCriteria();
+ SearchableCriteria criteria = new SearchCriteria();
// Add criteria
criteria.addCriteria(PizzaProductDatabaseConstants.COLUMN_TITLE, title);
return 0;
} else if (this.getId() > product.getId()) {
// This id is larger than compared to
- return -1;
+ return 1;
}
// The other id is larger
- return 1;
+ return -1;
}
@Override
<th class="table_header_column">
Einzelpreis:
</th>
+ <th class="table_header_column">
+ Kategorie:
+ </th>
<th class="table_header_column">
Verfügbarkeit:
</th>
<c:forEach var="product" items="<%=app.getAllProducts()%>">
<tr>
<td>
- ${product.getId()}
+ ${product.getId()}:
+ <input type="checkbox" name="product[${product.getId()}]" value="1" />
</td>
<td>
${product.getTitle()}
<td>
${product.getPrice()}
</td>
+ <td>
+ ${app.getPrintableProduktCategory(product)}
+ </td>
<td>
${app.getPrintableProduktAvailability(product)}
</td>
</tr>
</c:forEach>
<tr>
- <td colspan="4" class="table_footer">
+ <td colspan="5" class="table_footer">
<input type="reset" value="Formular zurücksetzen" />
<input type="submit" name="edit" value="Ändern" />
<input type="submit" name="delete" value="Löschen" />
if ("POST".equals(request.getMethod())) { //NOI18N
// Is "add/edit/delete" set?
if (request.getParameter("add") != null) { //NOI18N
- // Add new product
- app.doAdminAddProduct(request);
+ // Is it already added?
+ if (app.isProductTitleUsed(request)) {
+ // Debug message
+ app.getLogger().debug("Already used, redirecting ...");
+
+ // Already added, so redirect here, else a ServletException will be thrown
+ response.sendRedirect(request.getContextPath() + "/admin/product.jsp?already=1");
+ } else {
+ // Add new product
+ app.doAdminAddProduct(request);
+ }
} else if (request.getParameter("edit") != null) { //NOI18N
// @TODO
} else if (request.getParameter("delete") != null) { //NOI18N