OrderDAOImpl.java
package org.example.customerdao;
import java.sql.Connection;
import java.sql.Date;
import java.sql.PreparedStatement;
/*
* This is free and unencumbered software released into the public domain.
* Anyone is free to copy, modify, publish, use, compile, sell, or distribute this software,
* either in source code form or as a compiled binary, for any purpose, commercial or
* non-commercial, and by any means.
*
* In jurisdictions that recognize copyright laws, the author or authors of this
* software dedicate any and all copyright interest in the software to the public domain.
* We make this dedication for the benefit of the public at large and to the detriment of
* our heirs and successors. We intend this dedication to be an overt act of relinquishment in
* perpetuity of all present and future rights to this software under copyright law.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
* PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES
* OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
* For more information, please refer to: https://unlicense.org/
*/
import java.sql.ResultSet;
import java.sql.SQLException;
import java.time.LocalDate;
import java.util.ArrayList;
import java.util.List;
import javax.sql.DataSource;
import org.apache.commons.dbutils.DbUtils;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.example.customer.Customer;
import org.example.customer.Order;
import org.example.customer.OrderItem;
import org.example.customer.utility.CustomerEntity;
import org.example.customerdao.utility.ErrorFormatter;
import org.example.websecurity.UserCredentials;
/**
* This is the OrderDAO Implementation for the Customer DAO component of the
* Customer Web Application. This will be the primary Order database exposure
* for the Customer Web Layer.
*
* @author Jonathan Earl
* @since 1.0
*
*/
public class OrderDAOImpl
implements OrderDAO
{
private static final Logger LOG = LogManager.getLogger();
private DataSource myReadOnlyDS = null;
private DataSource myReadWriteDS = null;
private static final String FIND_ALL_SQL = "Select * from Orders";
private static final String FIND_BY_ID_SQL = "Select * from Orders where ID = ?";
private static final String FIND_ORDER_ITEM_BY_ID_SQL = "Select * from Order_Item where ORDER_ID = ?";
private static final String FIND_BY_CUSTOMER_SQL = "Select * from Orders where CUSTOMER_ID = ?";
private static final String ADD_ORDER_SQL = "Insert into Orders(ORDER_DATE,CUSTOMER_ID,TOTAL_AMOUNT,ORDER_NUMBER)"
+ " VALUES(?,?,?,?)";
private static final String ADD_ORDER_ITEM_SQL = "Insert into Order_Item(ORDER_ID,PRODUCT_ID,UNIT_PRICE,QUANTITY)"
+ " VALUES(?,?,?,?)";
private static final String UPDATE_SQL = "Update Orders set ORDER_DATE = ?, CUSTOMER_ID = ?, "
+ "TOTAL_AMOUNT = ?, ORDER_NUMBER = ?" + " WHERE ID = ?";
private static final String DELETE_ORDER_SQL = "Delete from Orders where id = ?";
private static final String DELETE_ORDER_ITEM_SQL = "Delete from Order_Item where ORDER_ID = ?";
/**
* {@inheritDoc}
*/
@Override
public void setReadOnlyDS(final DataSource readOnlyDS)
{
LOG.debug("Setting the ReadOnly DataSource");
this.myReadOnlyDS = readOnlyDS;
}
/**
* {@inheritDoc}
*/
@Override
public void setReadWriteDS(final DataSource readWriteDS)
{
LOG.debug("Setting the ReadWrite DataSource");
this.myReadWriteDS = readWriteDS;
}
/**
* {@inheritDoc}
*/
@Override
public List<Order> findAllOrders(final UserCredentials credentials)
{
LOG.debug("findAllOrders");
if (credentials == null || !credentials.hasRole("worker"))
{
LOG.error("findAllOrders - Permission refused");
throw new IllegalArgumentException("Permission refused for this operation");
}
PreparedStatement findAll = null;
Connection conn = null;
ResultSet results = null;
List<Order> data = new ArrayList<Order>();
try
{
conn = myReadOnlyDS.getConnection();
findAll = conn.prepareStatement(FIND_ALL_SQL);
results = findAll.executeQuery();
while (results.next())
{
Order order = buildOrder(results);
List<OrderItem> items = findAllOrderItems(credentials, order);
order.setOrderItems(items);
data.add(order);
}
}
catch (SQLException sqle)
{
LOG.error("Error finding all Orders");
LOG.error(ErrorFormatter.extractError(sqle));
throw new IllegalArgumentException(sqle);
}
finally
{
DbUtils.closeQuietly(conn, findAll, results);
}
return data;
}
/**
* {@inheritDoc}
*/
@Override
public List<OrderItem> findAllOrderItems(final UserCredentials credentials, final Order order)
{
LOG.debug("findAllOrderItems");
if (credentials == null || !credentials.hasRole("worker"))
{
LOG.error("findAllOrderItems - Permission refused");
throw new IllegalArgumentException("Permission refused for this operation");
}
if (order == null)
{
LOG.error("findAllOrderItems - Order required");
throw new IllegalArgumentException("Order required");
}
PreparedStatement findAll = null;
Connection conn = null;
ResultSet results = null;
List<OrderItem> data = new ArrayList<OrderItem>();
try
{
conn = myReadOnlyDS.getConnection();
findAll = conn.prepareStatement(FIND_ORDER_ITEM_BY_ID_SQL);
findAll.setInt(1, order.getId());
results = findAll.executeQuery();
while (results.next())
{
data.add(buildOrderItem(results));
}
}
catch (SQLException sqle)
{
LOG.error("Error finding all OderItems");
LOG.error(ErrorFormatter.extractError(sqle));
throw new IllegalArgumentException(sqle);
}
finally
{
DbUtils.closeQuietly(conn, findAll, results);
}
return data;
}
/**
* {@inheritDoc}
*/
@Override
public Order findOrderById(final UserCredentials credentials, final int id)
{
LOG.debug("findOrderById");
if (credentials == null || !credentials.hasRole("worker"))
{
LOG.error("findOrderById - Permission refused");
throw new IllegalArgumentException("Permission refused for this operation");
}
PreparedStatement findById = null;
Connection conn = null;
ResultSet results = null;
Order order = null;
try
{
conn = myReadOnlyDS.getConnection();
findById = conn.prepareStatement(FIND_BY_ID_SQL);
findById.setInt(1, id);
results = findById.executeQuery();
if (results.next())
{
order = buildOrder(results);
List<OrderItem> items = findAllOrderItems(credentials, order);
order.setOrderItems(items);
}
}
catch (SQLException sqle)
{
LOG.error("Error finding Product by id");
LOG.error(ErrorFormatter.extractError(sqle));
throw new IllegalArgumentException(sqle);
}
finally
{
DbUtils.closeQuietly(conn, findById, results);
}
return order;
}
/**
* {@inheritDoc}
*/
@Override
public List<Order> findOrdersByCustomer(final UserCredentials credentials, final Customer customer)
{
LOG.debug("findOrdersByCustomer");
if (credentials == null || !credentials.hasRole("worker"))
{
LOG.error("findOrdersByCustomer - Permission refused");
throw new IllegalArgumentException("Permission refused for this operation");
}
if (customer == null)
{
LOG.error("findOrdersByCustomer - Customer required");
throw new IllegalArgumentException("Customer required");
}
PreparedStatement findAll = null;
Connection conn = null;
ResultSet results = null;
List<Order> data = new ArrayList<Order>();
try
{
conn = myReadOnlyDS.getConnection();
findAll = conn.prepareStatement(FIND_BY_CUSTOMER_SQL);
findAll.setInt(1, customer.getId());
results = findAll.executeQuery();
while (results.next())
{
Order order = buildOrder(results);
List<OrderItem> items = findAllOrderItems(credentials, order);
order.setOrderItems(items);
data.add(order);
}
}
catch (SQLException sqle)
{
LOG.error("Error finding all Orders by Customer");
LOG.error(ErrorFormatter.extractError(sqle));
throw new IllegalArgumentException(sqle);
}
finally
{
DbUtils.closeQuietly(conn, findAll, results);
}
return data;
}
/**
* {@inheritDoc}
*/
@Override
public int addOrder(final UserCredentials credentials, final Order order)
{
LOG.debug("addOrder");
if (credentials == null || !credentials.hasRole("worker"))
{
LOG.error("addOrder - Permission refused");
throw new IllegalArgumentException("Permission refused for this operation");
}
if (order == null)
{
LOG.error("addOrder - null Order was provided");
throw new IllegalArgumentException("A Order must be provided");
}
PreparedStatement addOrder = null;
Connection conn = null;
ResultSet results = null;
int generatedOrderId = 0;
try
{
conn = myReadWriteDS.getConnection();
addOrder = conn.prepareStatement(ADD_ORDER_SQL, PreparedStatement.RETURN_GENERATED_KEYS);
LocalDate orderDate = order.getOrderDate();
int customerId = order.getCustomerId();
double totalAmount = order.getTotalAmount();
String orderNumber = order.getOrderNumber();
addOrder.setDate(1, Date.valueOf(orderDate));
addOrder.setInt(2, customerId);
addOrder.setDouble(3, totalAmount);
addOrder.setString(4, orderNumber);
addOrder.executeUpdate();
results = addOrder.getGeneratedKeys();
if (results.next())
{
generatedOrderId = results.getInt(1);
}
}
catch (SQLException sqle)
{
LOG.error("Error adding Product");
LOG.error(ErrorFormatter.extractError(sqle));
throw new IllegalArgumentException(sqle);
}
finally
{
DbUtils.closeQuietly(results);
DbUtils.closeQuietly(addOrder);
}
PreparedStatement addOrderItem = null;
try
{
addOrderItem = conn.prepareStatement(ADD_ORDER_ITEM_SQL);
List<OrderItem> items = order.getOrderItems();
for (OrderItem current : items)
{
int orderId = generatedOrderId;
int productId = current.getProductId();
double unitPrice = current.getUnitPrice();
int quantity = current.getQuantity();
addOrderItem.setInt(1, orderId);
addOrderItem.setInt(2, productId);
addOrderItem.setDouble(3, unitPrice);
addOrderItem.setInt(4, quantity);
addOrderItem.executeUpdate();
}
}
catch (SQLException sqle)
{
LOG.error("Error adding Product");
LOG.error(ErrorFormatter.extractError(sqle));
throw new IllegalArgumentException(sqle);
}
finally
{
DbUtils.closeQuietly(addOrderItem);
DbUtils.closeQuietly(conn);
}
return generatedOrderId;
}
/**
* {@inheritDoc}
*/
@Override
public void updateOrder(final UserCredentials credentials, final Order order)
{
LOG.debug("updateOrder");
if (credentials == null || !credentials.hasRole("manager"))
{
LOG.error("updateProduct - Permission refused");
throw new IllegalArgumentException("Permission refused for this operation");
}
if (order == null)
{
LOG.error("updateOrder - null Order was provided");
throw new IllegalArgumentException("A Order must be provided");
}
LOG.debug("Looking up Order");
Order temp = findOrderById(credentials, order.getId());
if (temp == null)
{
LOG.error("updateOrder - Order not found");
throw new IllegalArgumentException("Order not found");
}
PreparedStatement updateOrder = null;
PreparedStatement addOrderItem = null;
PreparedStatement deleteOrderItem = null;
Connection conn = null;
try
{
conn = myReadWriteDS.getConnection();
updateOrder = conn.prepareStatement(UPDATE_SQL);
addOrderItem = conn.prepareStatement(ADD_ORDER_ITEM_SQL);
deleteOrderItem = conn.prepareStatement(DELETE_ORDER_ITEM_SQL);
int id = order.getId();
LocalDate orderDate = order.getOrderDate();
int customerId = order.getCustomerId();
double totalAmount = order.getTotalAmount();
String orderNumber = order.getOrderNumber();
updateOrder.setDate(1, Date.valueOf(orderDate));
updateOrder.setInt(2, customerId);
updateOrder.setDouble(3, totalAmount);
updateOrder.setString(4, orderNumber);
updateOrder.setInt(5, id);
updateOrder.executeUpdate();
deleteOrderItem.setInt(1, id);
deleteOrderItem.executeUpdate();
List<OrderItem> items = order.getOrderItems();
for (OrderItem current : items)
{
int orderId = id;
int productId = current.getProductId();
double unitPrice = current.getUnitPrice();
int quantity = current.getQuantity();
addOrderItem.setInt(1, orderId);
addOrderItem.setInt(2, productId);
addOrderItem.setDouble(3, unitPrice);
addOrderItem.setInt(4, quantity);
addOrderItem.executeUpdate();
}
}
catch (SQLException sqle)
{
LOG.error("Error updating Product");
LOG.error(ErrorFormatter.extractError(sqle));
throw new IllegalArgumentException(sqle);
}
finally
{
DbUtils.closeQuietly(updateOrder);
DbUtils.closeQuietly(deleteOrderItem);
DbUtils.closeQuietly(addOrderItem);
DbUtils.closeQuietly(conn);
}
}
/**
* {@inheritDoc}
*/
@Override
public void deleteEntity(final UserCredentials credentials, final CustomerEntity entity)
{
LOG.debug("deleteOrder");
if (entity == null)
{
LOG.error("deleteOrder - null Order was provided");
throw new IllegalArgumentException("An Order must be provided");
}
if (!(entity instanceof Order))
{
LOG.error("deleteOrder - invalid CustomerEntity was provided");
throw new IllegalArgumentException("An Order must be provided");
}
deleteEntity(credentials, entity.getId());
}
/**
* {@inheritDoc}
*/
@Override
public void deleteEntity(final UserCredentials credentials, final int id)
{
LOG.debug("deleteOrder");
if (credentials == null || !credentials.hasRole("manager"))
{
LOG.error("deleteOrder - Permission refused");
throw new IllegalArgumentException("Permission refused for this operation");
}
PreparedStatement deleteOrderItems = null;
PreparedStatement deleteOrder = null;
Connection conn = null;
try
{
conn = myReadWriteDS.getConnection();
deleteOrderItems = conn.prepareStatement(DELETE_ORDER_ITEM_SQL);
deleteOrder = conn.prepareStatement(DELETE_ORDER_SQL);
deleteOrderItems.setInt(1, id);
deleteOrderItems.executeUpdate();
deleteOrder.setInt(1, id);
deleteOrder.executeUpdate();
}
catch (SQLException sqle)
{
LOG.error("Error updating Product");
LOG.error(ErrorFormatter.extractError(sqle));
throw new IllegalArgumentException(sqle);
}
finally
{
DbUtils.closeQuietly(deleteOrderItems);
DbUtils.closeQuietly(deleteOrder);
DbUtils.closeQuietly(conn);
}
}
/**
* {@inheritDoc}
* <P>
* Order are deleteable.
*/
@Override
public boolean isDeleteable(final UserCredentials credentials, final int id)
{
LOG.debug("isDeleteable");
if (credentials == null || !credentials.hasRole("manager"))
{
LOG.error("isDeleteable - Permission refused");
throw new IllegalArgumentException("Permission refused for this operation");
}
return true;
}
/**
* {@inheritDoc}
* <P>
* Order are deleteable.
*/
@Override
public boolean isDeleteable(final UserCredentials credentials, final CustomerEntity entity)
{
LOG.debug("isDeleteable");
if (credentials == null || !credentials.hasRole("manager"))
{
LOG.error("isDeleteable - Permission refused");
throw new IllegalArgumentException("Permission refused for this operation");
}
if (entity == null)
{
LOG.error("isDeleteable - null Order was provided");
throw new IllegalArgumentException("An Order must be provided");
}
if (!(entity instanceof Order))
{
LOG.error("deleteOrder - invalid CustomerEntity was provided");
throw new IllegalArgumentException("An Order must be provided");
}
return true;
}
private Order buildOrder(final ResultSet results) throws SQLException
{
Order current = new Order();
current.setId(results.getInt("ID"));
current.setOrderDate(results.getDate("ORDER_DATE").toLocalDate());
// java.sql.Date sqlDate = java.sql.Date.valueOf( localDate )
current.setCustomerId(results.getInt("CUSTOMER_ID"));
current.setTotalAmount(results.getDouble("TOTAL_AMOUNT"));
current.setOrderNumber(results.getString("ORDER_NUMBER"));
LOG.trace("Found Order: " + current.toString());
return current;
}
private OrderItem buildOrderItem(final ResultSet results) throws SQLException
{
OrderItem current = new OrderItem();
current.setId(results.getInt("ID"));
current.setOrderId(results.getInt("ORDER_ID"));
current.setProductId(results.getInt("PRODUCT_ID"));
current.setUnitPrice(results.getDouble("UNIT_PRICE"));
current.setQuantity(results.getInt("QUANTITY"));
LOG.trace("Found Order: " + current.toString());
return current;
}
}