Workshop Introduction

 


I am only demonstrating the Product Maintenance here.  The following ‘common’ classes were provided:

·         MultiColumnList; This class extends Panel and is used to display the information in columns on the GUI.

·         DBConnection; Objects of this class encapsulate the details needed for connecting to a database.  The connect() method returns a connection object.

·         Deployment; This provides a central and standard place to get deployment information.

·         MessageBox; This class creates a modal message dialog box with a variable prompt.

·         ProductPropertiesPanel; Methods in this class allow access to the properties of the products displayed on the GUI.  It also sets up the panel for displaying the products.

 
Task 1

 

The objective of this task is to design, code, and test the transaction logic for the Product Maintenance program (Business Layer).  I was responsible for the following:

·         Determine the necessary SQL statements.

·         Determine and implement the logic for the transactions.

·         Determine and implement logic for dealing with exceptions.

·         Determine and implement any data validation requirements.

·         Package transaction results (including exceptions) into a standard object for return to    the caller of the transaction.

·         Develop a test plan for each transaction.

·         Test each transaction by writing a main that prints any outputs.  It does not need to be interactive; hard coding of inputs or on the command line is acceptable.

 

The ProductTransactionImpl Class

 

We were provided with the declaration of the ProductTransactionITF class, which lists the methods we must implement in this class.

 

 

 

 

package product;

import common.*;

import java.sql.*;

 

public class ProductTransactionImpl implements ProductTransactionITF

{

                private Connection mSQLcon;

                private Statement stmt;

                     

                public ProductTransactionImpl()

                {

                                connectDataBase();

                }

                     

                // Connect to database using driver and database from Deployment class

                public void connectDataBase()

                {

                                String driver = "sun.jdbc.odbc.JdbcOdbcDriver";

                                String url = "jdbc:odbc:" + Deployment.ODBCDataSourceName;             

                                connectDataBase(driver, url);

                }

                     

                // Connect to database using a specified driver and database URL

                public void connectDataBase(String driver, String url)

                {

                                try

                                {

                                                DBConnection dataConnection = new DBConnection(driver, url);

                                                mSQLcon = dataConnection.connect();

 

                                                // Use the connection to create the statement object

                                                stmt = mSQLcon.createStatement ();

                                } catch (Exception e)

                                {

                                                e.printStackTrace();

                                }

                }

 

                // Transaction to return all of the product information

                public synchronized Result getAllProducts()

                {

                                Result ans = new Result();

                               

                                try

                                {

                                                String query = "Select Distinct * from Products";

                                                ResultSet rs = stmt.executeQuery(query);

                                               

                                                while(rs.next())

                                                {

                                                                String queryResult[] = new String[5];

                                                                queryResult[0] = rs.getString("ProductID");

                                                                queryResult[1] = rs.getString("ProductDescription");

                                                                queryResult[2] = rs.getString("UnitPrice");

                                                                queryResult[3] = rs.getString("AvailableQuantity");

                                                                queryResult[4] = rs.getString("TaxCode");

                                                                ans.add(queryResult);

                                                }

                                } catch(Throwable e)

                                {

                                                e.printStackTrace();

                                                ans.clear();

                                                ans.add(e);

                                }

                               

                                return ans;

                }

               

               

// Transaction to return the information for one particular product

                public synchronized Result getProduct(String productID)

                {

                                Result ans = new Result();

                               

                                try

                                {              // ProductID must be numeric, an integer and >0

                                                if(Integer.parseInt(productID)<=0)

                                                                {

                                                                throw new Throwable("Product ID must be greater than 0.");

                                                }

                                                               

                                                String query = "Select Distinct * from Products where ProductID=" + productID;

                                                ResultSet rs = stmt.executeQuery(query);

                                                String queryResult[] = new String[5];

                                               

                                                while(rs.next())

                                                {

                                                                queryResult[0] = rs.getString("ProductID");

                                                                queryResult[1] = rs.getString("ProductDescription");

                                                                queryResult[2] = rs.getString("UnitPrice");

                                                                queryResult[3] = rs.getString("AvailableQuantity");

                                                                queryResult[4] = rs.getString("TaxCode");

                                                               

                                                                ans.add(queryResult);

                                               

                                                                System.out.println(queryResult[1]);

                                                }

                                }

                                catch(NumberFormatException nfe)

                                {

                                                MessageBox.displayMessageBox("Product ID must be an integer.");

                                                ans.clear();

                                                ans.add(nfe);

                                }

                                catch(Throwable e)

                                {

                                                e.printStackTrace();

                                                ans.clear();

                                                ans.add(e);

                                }

                               

                                return ans;

                }

               

                // Transaction to update a product's information

public synchronized Result updateProduct(String description, String price, String quantity, String taxCode, String productID)

                {

                                Result ans = new Result();

 

                                try

                                {             

// No empty strings among the arguments

if ((description.equals("")) || (price.equals("")) || (quantity.equals("")) || (taxCode.equals("")) ||

(productID.equals("")))

                                                {

                                                                throw new Throwable("No arguments can be empty.");                                                           

                                                }

                                               

                                                // Unit price must be numeric and positive

                                                if(Double.parseDouble(price)<0)                                             

                                                {

                                                                throw new Throwable("The unit price must be positive.");

                                                }

                                               

                                               

 

// Quantity must be 0 or a positive integer

                                                if(Integer.parseInt(quantity)<0)

                                                {

                                                                throw new Throwable("The quantity must be zero or greater.");

                                                }

 

                                                // Tax code must be 0-3 only

if (!(taxCode.equals("0")) && !(taxCode.equals("1")) && !(taxCode.equals("2")) &&

!(taxCode.equals("3")))

                                                {

                                                                throw new Throwable("Tax Code must be either 0,1,2 or 3.");

                                                }

 

                                                // ProductID must be an integer and >0

                                                if(Integer.parseInt(productID)<=0)

                                                {

                                                                throw new Throwable("Product ID must be greater than 0.");

                                                }

 

String updateRecord = "Update PRODUCTS Set " + " ProductDescription=" + "'" + description 

                                        + "'" + "," + " UnitPrice=" + price + "," + " AvailableQuantity=" +  quantity

    + ","  + " TaxCode=" + taxCode + " Where ProductID=" +  productID;

                                               

                                                int nRows = stmt.executeUpdate(updateRecord);

                                                System.out.println("On update product " + nRows + " rows were modified");

                                                ans.add(new Integer(nRows));

                                }

                                catch(NumberFormatException nfe)

                                {

                                                MessageBox.displayMessageBox("Incorrect Data Type.");

                                                ans.clear();

                                                ans.add(nfe);

                                }

                                catch(Throwable e)

                                {

                                                e.printStackTrace();

                                                ans.clear();

                                                ans.add(e);

                                }

               

                                return ans;

                }

 

                // Transaction to insert a new product into the database

                public synchronized Result insertProduct(String description, String price, String quantity, String taxCode)

                {

                                Result ans = new Result();

 

                                try

                                {              // No empty strings among the arguments

                                                if ((description.equals(""))||(price.equals(""))||(quantity.equals(""))||(taxCode.equals("")))

                                                {

                                                                throw new Throwable("No arguments can be empty.");                                                           

                                                }

                                               

                                                // Unit price must be numeric and positive

                                                if (Double.parseDouble(price)<0)                                            

                                                {

                                                                throw new Throwable("The unit price must be positive.");

                                                }

                                               

                                                // Quantity must be 0 or a positive integer

                                                if (Integer.parseInt(quantity)<0)

                                                {

                                                                throw new Throwable("The quantity must be zero or greater.");

                                                }

                                                               

                                                // Tax code must be 0-3 only

                                                if (!(taxCode.equals("0")) && !(taxCode.equals("1")) && !(taxCode.equals("2")) && 

                                                                                                                !(taxCode.equals("3")))

                                                {

                                                                throw new Throwable("Tax Code must be either 0,1,2 or 3.");

                                                }

                               

                                                String insertRecord = "Insert Into PRODUCTS (ProductDescription, UnitPrice, AvailableQuantity,

 TaxCode) " + "Values (" + "'" + description + "'" + "," + price + "," +

                                                                                 quantity + "," + taxCode + ")";

                                               

                                                int nRows = stmt.executeUpdate(insertRecord);

                                                System.out.println("On insert product " + nRows + " rows were modified");

                                                ans.add(new Integer(nRows));

                                }

                                catch(NumberFormatException nfe)

                                {

                                                MessageBox.displayMessageBox("Incorrect data type.");        

                                                ans.clear();

                                                ans.add(nfe);

                                }

                                catch(Throwable e)

                                {

                                                e.printStackTrace();

                                                ans.clear();

                                                ans.add(e);

                                }

                               

                                return ans;

                }

 

                // Transaction to delete a product from the database

                public synchronized Result deleteProduct(String productID)

                {

                                Result ans = new Result();

 

                                try

                                {

                                                // ProductID must be numeric, an integer and >0

                                                if (Integer.parseInt(productID)<=0)

                                                {

                                                                throw new Throwable("Product ID must be greater than 0.");

                                                }

 

                                                if (productID != null)

                                                {

                                                                String deleteRecord = " Delete From PRODUCTS where ProductID = " + productID;

                                                                int nRows = stmt.executeUpdate(deleteRecord);

                                                                System.out.println("On delete product " + nRows + " rows were modified");

                                                                ans.add(new Integer(nRows));

                                                }

                                }

                                catch(NumberFormatException nfe)

                                {

                                                MessageBox.displayMessageBox("Product ID must be an integer.");       

                                                ans.clear();

                                                ans.add(nfe);

                                }                             

                                catch(Throwable e)

                                {

                                                e.printStackTrace();

                                                ans.clear();

                                                ans.add(e);

                                }

                                return ans;

                }

}

 

 

Task 2

 

The objective of this task is to design, code, and test a Product Maintenance user-interface class (Presentation Layer).  This a graphical user interface for which we must also design a test plan.

The methods in this class communicate with the transaction logic only through the methods declared in ProductTransactionITF, and with any object whose class implements the same interface.  This is one of the keys to converting the application from a single-process single-user application into a distributed multi-user system, as illustrated below:

 

                         Presentation Layer     Interface      Business Layer

Product-

MaintenanceUI

 

 

 

 

TransactionImpl

 

 USER

 
 

 

 

 

 

 

 


The ProductMaintenanceUI Class

 

package product;

import common.*;

import java.awt.*;

import java.awt.event.*;

 

public class ProductMaintenanceUI extends Panel

{

                // Reference to interface for transactions

                private ProductTransactionITF productTran;

 

                // UI components

                private MultiColumnList productList;

                private ProductPropertiesPanel productProperties;

                private Panel navPanel;

                private Button leftButton;

                private Button rightButton;

                private Button deleteButton;

               

                  // Invokes getAllProducts and updates the GUI from the data in the Result object

                private void populateProducts()

                {

                                Result allProductsResult = productTran.getAllProducts();

                                if (allProductsResult.isResultSet())

                                {

                                                productList.clear();

                                                String prodRow[];

                               

                                                for (int count = 0; count < allProductsResult.size(); count++)

                                                {

                                                                prodRow = (String[]) allProductsResult.elementAt(count);

                                                                double db=Double.parseDouble(prodRow[2]);

                                                                prodRow[2]=round(db)+"";

                                                                productList.addItem(prodRow);

                                                }

                                }

                                else

                                                MessageBox.displayMessageBox(((Throwable)allProductsResult.firstElement()).getMessage());

                }

               

 

                 

// Invokes getProduct and updates the GUI from the data in the Result object

                private void populateProperties(String arr[])

                {

                                if (arr != null)

                                {

                                                Result selectedProductResult = productTran.getProduct(arr[0]);

                                                if (selectedProductResult.isResultSet())

                                                {

                                                                String prodRow[];

                               

                                                                for (int count = 0; count < selectedProductResult.size(); count++)

                                                                {

                                                                                prodRow = (String[]) selectedProductResult.elementAt(count);

                                                                                productProperties.setProductID(prodRow[0]);

                                                                                productProperties.setDescription(prodRow[1]);

                                                                                productProperties.setPrice(prodRow[2]);

                                                                                productProperties.setQuantity(prodRow[3]);

                                                                                productProperties.setTaxCode(prodRow[4]);

                                                                }

                                                }

                                                else

MessageBox.displayMessageBox(((Throwable)selectedProductResult.firstElement()).

     getMessage());

                                }

                }

               

                // Invokes updateProduct transaction and updates the GUI from the data in the Result object

                private void updateProduct()

                {

                                Result res = productTran.updateProduct(productProperties.getDescription(),

                                                                productProperties.getPrice(),productProperties.getQuantity(),

                                                                productProperties.getTaxCode(),             productProperties.getProductID());

                                if (res.isRowsAffected())

                                                populateProducts();

                                else

                                                MessageBox.displayMessageBox(((Throwable)res.firstElement()).getMessage());

                }

               

                // Invokes insertProduct transaction and updates the GUI from the data in the Result object

                private void insertProduct()

                {

                               

                                Result res = productTran.insertProduct(productProperties.getDescription(),

                                                                                productProperties.getPrice(),productProperties.getQuantity(),

                                                                                                                           productProperties.getTaxCode());

                                if (res.isRowsAffected())

                                                populateProducts();

                                else

                                                MessageBox.displayMessageBox(((Throwable)res.firstElement()).getMessage());

                }

               

                // Invokes deleteProduct transaction and updates the GUI from the data in the Result object

                private void deleteProduct()

                {

                                String s[] = productList.getSelectedItem();

                               

                                if (s != null)

                                {

                                                Result res = productTran.deleteProduct(s[0]);

                                                if (res.isRowsAffected())

                                                                populateProducts();

                                                else

                                                                MessageBox.displayMessageBox(((Throwable)res.firstElement()).getMessage());

                                }

                }

               

    

 

                // ActionListener for the Add/New buttom at the botton of the ProductMaintenanceUI panel

                class AddOKHandler implements ActionListener

                {

                                public void actionPerformed(ActionEvent e)

                                {

                                                if (e.getActionCommand() == "Add Product")

                                                {

                                                                remove(productList);

                                                                productProperties = new ProductPropertiesPanel();

                                                                add(productProperties, BorderLayout.CENTER);

                                                                leftButton.setLabel("OK");

                                                                rightButton.setLabel("Cancel");

                                                                deleteButton.setVisible(false);

                                                                validate();

                                                                productProperties.setProductID("New Product");

                                                }

else if (e.getActionCommand() == "OK")

{

                                                                try {

                                               

                                                // Data Validation

                                                if (productProperties.getDescription().equals("")||productProperties.getPrice().equals("")

                                                                ||productProperties.getQuantity().equals("")||productProperties.getTaxCode().equals(""))

                                                {             

                                                                throw new InvalidTransactionException("Each field must contain a value.");

                                                } else {

                                                                if (!(Double.parseDouble(productProperties.getPrice())>0))

                                                                {

                                                                                throw new InvalidTransactionException("UnitPrice must be positive.");

                                                                } else {    

                                                                                if (Integer.parseInt(productProperties.getQuantity())<0)

                                                                                {

                                                                                                throw new InvalidTransactionException("Cannot be negative.");

                                                                                }

                                                                }

                                                }

                                                                remove(productProperties);

                                                                add(productList, BorderLayout.CENTER);

                                                                leftButton.setLabel("Add Product");

                                                                rightButton.setLabel("Edit Product");

                                                                deleteButton.setVisible(true);

                                                                validate();

                                                               

                                                                if (productProperties.getProductID()== "New Product")

                                                                {

                                                                                insertProduct();

                                                                } else {

                                                                                updateProduct();

                                                                }

                                                }

                                                catch(InvalidTransactionException ite)

                                                {

                                                                MessageBox.displayMessageBox(ite.getMessage());

                                                }

                                                catch(NumberFormatException nfe)

                                                                {

                                                                                MessageBox.displayMessageBox("Quantity must be a whole number.");

                                                                }

                                                } else {

                                                                System.out.println("ERROR in AddOKHandler");   

                                                }

                                   

                                }

                }

 

     

      

 

                //ActionListener for the Edit button at the bottom of the ProductMaintenanceUI

                class EditCancelHandler implements ActionListener

                {

                                public void actionPerformed(ActionEvent e)

                                {

                                                if (e.getActionCommand() == "Edit Product")

                                                {

                                                                String arr[];

                                                                arr = productList.getSelectedItem();

 

                                                                if (arr != null)

                                                                {

                                                                                remove(productList);

                                                                                productProperties = new ProductPropertiesPanel();

                                                                                add(productProperties, BorderLayout.CENTER);

                                                                                leftButton.setLabel("OK");

                                                                                rightButton.setLabel("Cancel");

                                                                                deleteButton.setVisible(false);

                                                                                validate();

                                                                                populateProperties(arr);

                                                                }

                                                }

                                                else if (e.getActionCommand() == "Cancel")

                                                {

                                                                remove(productProperties);

                                                                add(productList, BorderLayout.CENTER);

                                                               

                                                                leftButton.setLabel("Add Product");

                                                                rightButton.setLabel("Edit Product");

                                                                deleteButton.setVisible(true);

                                                                validate();

                                                } else {

                                                                System.out.println("ERROR in EditCancelHandler");              

                                                }

                                }

                }

 

                // ActionListener for the Delete button at the bottom of the ProductMaintenanceUI

                class DeleteHandler implements ActionListener

                {

                                public void actionPerformed(ActionEvent e)

                                {

                                                deleteProduct();

                                }

                }

 

                // Build user interface.  Load class that implements the ProductTransactionITF.

                private ProductMaintenanceUI() throws Exception

                {

                                setLayout(new BorderLayout());

                                productList = new MultiColumnList();

           

productTran = (ProductTransactionITF)Class.forName (Deployment.productTransactionClassName)

.newInstance();

                                String headerList[] = { "ID", "Description", "Price", "Quantity", "Tax Code"};

                                int headerDim[] = { 10, 30, 15, 10, 10 };

                                productList.setHeaderDisplay(headerList);

                                productList.setHeaderDimensions(headerDim);

                               

                                navPanel = new Panel();

                                leftButton = new Button("Add Product");

                                rightButton = new Button("Edit Product");

                                deleteButton = new Button("Delete Product");

                                leftButton.addActionListener(new AddOKHandler());

                                rightButton.addActionListener(new EditCancelHandler());

                                deleteButton.addActionListener(new DeleteHandler());

                               

navPanel.add(leftButton);

                                navPanel.add(rightButton);

                                navPanel.add(deleteButton);

                                add(productList, BorderLayout.CENTER);

                                add(navPanel, BorderLayout.SOUTH);

                }

                               

                public static void main (String args[]) throws Exception

                {

                                // Process the command-line arguments and set up any overrides for default deployment parameters

                                if (args.length < 1)

                                {

                                                System.err.println("Usage, one of:");

                                                System.err.println("java ProductMaintenanceUI ODBCDataSourceName");

                                                System.err.println("java ProductMaintenanceUI ODBCDataSourceName

productTransactionClassName");

                                                System.err.println("java ProductMaintenanceUI ODBCDataSourceName

                productTransactionClassName host:port");

                                                System.exit(1);

                                }

                               

                                Deployment.ODBCDataSourceName = args[0];

                                if(args.length > 1)

                                                Deployment.productTransactionClassName = args[1];

                                if(args.length > 2)

                                                Deployment.productTransactionHostID = args[2];

                                Frame TestWindowFrame = new Frame("Product Maintenance");

                                ProductMaintenanceUI prodPanel = new ProductMaintenanceUI();

                                prodPanel.populateProducts();

                                TestWindowFrame.add(prodPanel, BorderLayout.CENTER);

                                TestWindowFrame.setSize(800,300);

                                TestWindowFrame.setVisible(true);

                                WindowListener l = new WindowAdapter() { public void windowClosing(WindowEvent e) {

                                                System.exit(0);

                                                }

                                };

                                TestWindowFrame.addWindowListener(l);

                }

 

// Currency formatting

                public static String round(double db)

{

                                String str=db+"";

                                int in1=str.length();

                                int in=(int)db;

                               

// If the value is an integer

                                if(in==db) {

                                                return in+".00";

                                } else if (str.charAt(in1-2)=='.') {

                                                // If the value has one number to the right of the decimal

                                                return db+"0";

                                } else {      

                                                // The value has more than 1 number to the right of the decimal             

                                                int temp1=(int) (db*1000);

                                                int temp2=(int) (db*100);

                               

                                                if (temp1-temp2*10>=5)

                                                {

                                                                // Round the number up

                                                                return  ((double)temp2+1)/100.00+"";

                                                } else {

                                                                return ((double)temp2)/100.00+"";

                                                }

                                }

                }

}

 

 
Task 3

 

This final task involved making enhancements to the other packages.  Most of these enhancements are seen in the previous code.  This is what I was responsible for:

·         Improve the appearance of the GUI (ProductPropertiesPanel).

·         Improve handling of the headings (MultiColumnList).

·         Replace the Tax Code text field with a drop down list box (ProductPropertiesPanel).

·         Mask the password with asterisks (LoginPanel from Purchase package).

 

Screenshots for the Product Maintenance GUI

 

 

Edit Product

 

Add Product