Summary


Extended Applet & JDBC Example

It’s time now to tie all the concepts presented in this chapter together into one application. Let’s take a look again at the overall architectural diagram for the employee training management system.

Referring to figure 21-35 — an applet communicates with a server-based RMI component. The RMI method calls are translated into JDBC calls to the MySQL database. You are asked to refer to figures 21-13 and 21-14 for the detailed class diagrams for the server-side and client-side components respectively.

image from book
Figure 21-35: Employee Training Management System Architecture

The Code

I have chosen to place the code for the employee training management system in the package structure depicted in figure 21-36. The completed application consists of nine classes arranged in four packages. Each class and a description of its purpose is listed in table 21-2.

image from book
Figure 21-36: Employee Training Management System Source Code Package Structure

Table 21-2: Employee Training Management System Class Descriptions

Class

Name

Package Description

Employee

com.pulpfreepress.business_objects

Java representation of an Employee entity.

EmployeeTraining

com.pulpfreepress.business_objects

Java representation of an EmployeeTraining entity.

AddNewEmployeeDialog

com.pulpfreepress.client

A dialog used by the EmployeeTrainingApplet class that lets users create a new employee.

AddTrainingRecordDialog

com.pulpfreepress.client

A dialog used by the EmployeeTrainingApplet class that lets users create a new employee training record.

EmployeeTrainingApplet

com.pulpfreepress.client

The main applet class for the client-side portion of the employee training management system.

DBServerApp

com.pulpfreepress.dbserver

The main application class for the server-side portion of the employee training management system. The DBServerApp class starts an instance of the RMI registry and registers an instance of the Persister class.

Persister

com.pulpfreepress.dbserver

The server-side RMI component that provides the touch point between clients and the MySQL database. Implements PersisterInterface.

PersisterInterface

com.pulpfreepress.dbserver

Specifies four remote methods.

DBServerProperties

com.pulpfreepress.utils

Extends the Properties class. Provides for flexible application configuration management by allowing application properties to be set via a properties file.

Compiling And Packaging The Applet Code For Distribution

Before the example code can be executed it must be compiled, the Persister_Stub.class must be generated with the rmic tool, the class files must be packaged into a jar file, and the HTML page shown in example 21.27 must be created.

Example 21.27: employeetraining.html

image from book
 1    <title>Employee Training Applet Page</title> 2    <hr> 3    <applet archive="EmployeeAppletClasses.jar" 4            code="com.pulpfreepress.client.EmployeeTrainingApplet.class" 5            width=650 6            height=400> 7    </applet> 8    <hr>
image from book

Compiling The Source Code

The easiest way to compile the code is to compile everything at once. You can do this by changing to the directory that contains the src directory and issuing the javac in the format of the following example:

 javac -d . src/com/pulpfreepress/*/*.java

The -d . option signals the javac compiler to place the resulting class files in the current working directory. They will be written there in their proper package structure. The src/com/pulpfreepress/*/*.java path specifies all the java source files contained in all the subdirectories located in the src/com/pulpfreepress directory. (Note: This form of the javac command will not work in Windows! But it does work on Apple’s OS X and on SuSE Linux 9.3.)

Generating The Persister_Stub.class File

After the code is compiled and the class files generated you must generate the Persister_Stub.class file using the rmic tool. From the project working directory enter the following command:

 rmic -d . -v1.2 com.pulpfreepress.dbserver.Persister

Check to ensure the Persister_Stub.class file was generated.

Creating The Jar File

The classes must now be packaged in a jar file named image from book EmployeeAppletClasses.jar since this is the archive file named in the archive attribute of the applet tag shown in example 21.27. To create the jar file use the jar utility from the working directory in the following fashion:

 jar -cf EmployeeAppletClasses.jar com

The -cf image from book EmployeeAppletClasses.jar tells the jar utility to create a file named image from book EmployeeAppletClasses.jar. The com at the end is the name of the directory (and the packages and classes it contains) to archive.

Running The Example

To run the example you must first make sure MySQL is up and running with the chapter_21 database properly set up. Next, you must start the DBServerApp program on the server computer, and finally, access the image from book employeetraining.html page locally with a browser or serve it up with a web server and access it remotely.

Start MySQL Database Application

If it’s not already running start MySQL. The MySQL application can be set up to start automatically when the computer is powered up.

Start The DBServerApp Program

After MySQL is running start the DBServerApp program. You should see an output on the terminal similar to figure 21-37.

image from book
Figure 21-37: Terminal Output Showing DBServerApp Startup Sequence

Access The employeetraining.html Page

Before you do this make sure the image from book EmployeeAppletClasses.jar file is placed in the same directory as the image from book employeetraining.html page. Once you’ve done this start a browser, browse to the directory where the HTML page is located and open the page. Your browser window should look similar to figure 21-38.

image from book
Figure 21-38: EmployeeTrainingApplet Appearance on First Access

Using The Employee Training Applet

To get a list of all employees simply click the Search By Last Name button leaving the Last Name text field blank. The results are shown in figure 21-39. To show an employee’s training records click on an employee row in the text area and then click the Get Employee Training Records button. The results are shown in figure 21-40.

image from book
Figure 21-39: Complete List of Employees

image from book
Figure 21-40: Training Records for Homer Simpson

To add a new employee click the Add New Employee button to display the Add New Employee dialog. Figures 21-41 and 21-42 illustrate. Figure 21-43 shows a new list of all employees. New employee training records can be added by clicking on an employee and then clicking the Add Employee Training Record button. This is not shown.

image from book
Figure 21-41: Add New Employee Dialog

image from book
Figure 21-42: Add New Employee Dialog with Text Fields Filled In

image from book
Figure 21-43: New Employee Added to the Database

Code Discussion

This section presents a brief discussion of the employee training management system source code presented in examples 21.19 through 21.27. Only the highlights are discussed and you are encouraged to create sequence diagrams that trace code execution throughout the related classes.

Example 21.19: Employee.java

image from book
 1     package com.pulpfreepress.business_objects; 2 3     import java.util.*; 4     import java.io.*; 5 6     public class Employee implements Serializable { 7 8       private int            _id                = 0; 9       private String         _first_name        = null; 10      private String         _middle_name       = null; 11      private String         _last_name         = null; 12      private String         _ssn               = null; 13      private String         _dob               = null; 14      private Vector         _child_relations   = null; 15 16      public Employee(int id, String fn, String mn, String ln, String ssn, String dob, Vector cr){ 17        _id = id; 18        _first_name = fn; 19        _middle_name = mn; 20        _last_name = ln; 21        _ssn = ssn; 22        _dob = dob; 23        if(cr != null) _child_relations = (Vector) cr.clone(); 24      } 25 26      public Employee(){ 27        this(0, null, null, null, null, null, null); 28      } 29 30      public void setEmployeeID(int id){ _id = id; } 31 32      public void setFirstName(String fn){ _first_name = fn; } 33 34      public void setMiddleName(String mn) { _middle_name = mn; } 35 36      public void setLastName(String ln) { _last_name = ln; } 37 38      public void setSSN(String ssn) { _ssn = ssn; } 39 40      public void setDOB(String dob) { _dob = dob; } 41 42      public  void setChildRelations(Vector cr){ _child_relations = (Vector) cr.clone(); } 43 44      public int getEmployeeID() { return _id; } 45 46      public String getFirstName() { return _first_name; } 47 48      public String getMiddleName() { return _middle_name; } 49 50      public String getLastName() { return _last_name; } 51 52      public String getSSN() { return _ssn; } 53 54      public String getDOB() { return _dob; } 55 56      public Vector getChildRelations() { return (Vector) _child_relations.clone(); } 57 58    }
image from book

Example 21.20: EmployeeTraining.java

image from book
 1     package com.pulpfreepress.business_objects; 2 3     import java.io.*; 4 5     public class EmployeeTraining implements Serializable { 6 7       private int     _id     = 0; 8       private int     _emp_id = 0; 9       private String  _date   = null; 10      private String  _topic  = null; 11      private String  _result = null; 12 13      public EmployeeTraining(int id, int emp_id, String date, String topic, String result){ 14        _id     = id; 15        _emp_id = emp_id; 16        _date   = date; 17        _topic  = topic; 18        _result = result; 19      } 20 21      public EmployeeTraining(){ 22        this(0, 0, null, null, null); 23      } 24 25      public void setEmployeeTrainingID(int id) { _id = id; } 26 27      public void setEmployeeID(int id) { _emp_id = id; } 28 29      public void setDate(String date){ _date = date; } 30 31      public void setTopic(String topic) { _topic = topic; } 32 33      public void setResult(String result) { _result = result; } 34 35      public int getEmployeeTrainingID() { return _id; } 36 37      public  int getEmployeeID() { return _emp_id; } 38 39      public String getDate() { return _date; } 40 41      public String getTopic() { return _topic; } 42 43      public String getResult() { return _result; } 44 45    }
image from book

Example 21.21: AddNewEmployeeDialog.java

image from book
 1     package com.pulpfreepress.client; 2 3     import javax.swing.*; 4     import java.awt.event.*; 5     import java.awt.*; 6 7     public class AddNewEmployeeDialog extends JDialog { 8        private JLabel _label1 = null; 9        private JLabel _label2 = null; 10       private JLabel _label3 = null; 11       private JLabel _label4 = null; 12       private JLabel _label5 = null; 13       private JTextField _textfield1 = null; 14       private JTextField _textfield2 = null; 15       private JTextField _textfield3 = null; 16       private JTextField _textfield4 = null; 17       private JTextField _textfield5 = null; 18       private JButton _button1 = null; 19       private JPanel _panel1 = null; 20       private JPanel _blank_panel = null; 21 22       public AddNewEmployeeDialog(ActionListener al){ 23         super(new JFrame(), "Add New Employee Dialog", true); 24 25         _label1 = new JLabel("First Name: "); 26         _label2 = new JLabel("Middle Name: "); 27         _label3 = new JLabel("Last Name: "); 28         _label4 = new JLabel("SSN (nnn-nn-nnnn): "); 29         _label5 = new JLabel("Date of Birth (yyyy-mm-dd): "); 30         _textfield1 = new JTextField(20); 31         _textfield2 = new JTextField(20); 32         _textfield3 = new JTextField(20); 33         _textfield4 = new JTextField(20); 34         _textfield5 = new JTextField(20); 35         _button1 = new JButton("Submit New Employee"); 36         _button1.addActionListener(al); 37         _panel1 = new JPanel(); 38         _panel1.add(_button1); 39         _blank_panel = new JPanel(); 40 41         this.getContentPane().setLayout(new GridLayout(6, 2, 0, 0)); 42         this.getContentPane().add(_label1); 43         this.getContentPane().add(_textfield1); 44         this.getContentPane().add(_label2); 45         this.getContentPane().add(_textfield2); 46         this.getContentPane().add(_label3); 47         this.getContentPane().add(_textfield3); 48         this.getContentPane().add(_label4); 49         this.getContentPane().add(_textfield4); 50         this.getContentPane().add(_label5); 51         this.getContentPane().add(_textfield5); 52         this.getContentPane().add(_blank_panel); 53         this.getContentPane().add(_panel1); 54         this.pack(); 55         this.setSize(400, 200); 56         this.setLocation(150, 150); 57       } // end constructor method 58 59       public void clearAllFields(){ 60         _textfield1.setText(""); 61         _textfield2.setText(""); 62         _textfield3.setText(""); 63         _textfield4.setText(""); 64         _textfield5.setText(""); 65       } 66 67       public String getFirstName() { return _textfield1.getText(); } 68       public String getMiddleName() { return _textfield2.getText(); } 69       public String getLastName() { return _textfield3.getText(); } 70       public String getSSN() { return _textfield4.getText(); } 71       public String getDOB() { return _textfield5.getText(); } 72 73    } // end AddNewEmployeeDialog class definition
image from book

Example 21.22: AddTrainingRecordDialog.java

image from book
 1     package com.pulpfreepress.client; 2 3     import javax.swing.*; 4     import java.awt.event.*; 5     import java.awt.*; 6 7     public class AddTrainingRecordDialog extends JDialog { 8       private JLabel _label1 = null; 9       private JLabel _label2 = null; 10      private JLabel _label3 = null; 11      private JTextField _textfield1 = null; 12      private JTextField _textfield2 = null; 13      private JTextField _textfield3 = null; 14      private JButton _button1 = null; 15      private JPanel _panel1 = null; 16      private JPanel _blank_panel = null; 17 18      public AddTrainingRecordDialog(ActionListener al){ 19        super(new JFrame(), "Add Employee Training Record Dialog", true); 20        _panel1 = new JPanel(); 21        _blank_panel = new JPanel(); 22        _label1 = new JLabel("Date (yyyy-mm-dd):"); 23        _label2 = new JLabel("Topic: "); 24        _label3 = new JLabel("Result: "); 25        _textfield1 = new JTextField(20); 26        _textfield2 = new JTextField(20); 27        _textfield3 = new JTextField(20); 28        _button1 = new JButton("Submit Training Record"); 29        _button1.addActionListener(al); 30        _panel1.add(_button1); 31        this.getContentPane().setLayout(new GridLayout(4, 2, 0, 0)); 32        this.getContentPane().add(_label1); 33        this.getContentPane().add(_textfield1); 34        this.getContentPane().add(_label2); 35        this.getContentPane().add(_textfield2); 36        this.getContentPane().add(_label3); 37        this.getContentPane().add(_textfield3); 38        this.getContentPane().add(_blank_panel); 39        this.getContentPane().add(_panel1); 40        this.setSize(300, 200); 41        this.setLocation(150, 150); 42        this.pack(); 43      } // end constructor 44 45      public String getDate(){ return _textfield1.getText(); } 46      public String getTopic() { return _textfield2.getText(); } 47      public String getResult() { return _textfield3.getText(); } 48 49      public void clearAllFields(){ 50        _textfield1.setText(""); 51        _textfield2.setText(""); 52        _textfield3.setText(""); 53      } 54 55    } // end AddTrainingRecordDialog class definition
image from book

Example 21.23: EmployeeTrainingApplet.java

image from book
 1     package com.pulpfreepress.client; 2 3     import java.awt.*; 4     import java.awt.event.*; 5     import javax.swing.*; 6     import java.rmi.*; 7     import java.util.*; 8     import com.pulpfreepress.dbserver.*; 9     import com.pulpfreepress.business_objects.*; 10    import com.pulpfreepress.utils.*; 11 12    public class EmployeeTrainingApplet extends JApplet implements ActionListener { 13 14       private JPanel _panel1 = null; 15       private JPanel _panel2 = null; 16       private JPanel _south_panel = null; 17       private JTextArea _textarea1 = null; 18       private JScrollPane _scrollpane1 = null; 19       private JButton _button1 = null; 20       private JButton _button2 = null; 21       private JButton _button3 = null; 22       private JButton _button4 = null; 23       private JTextField _textfield1 = null; 24       private JLabel _label1 = null; 25       private PersisterInterface _persister = null; 26       private Vector _employees = null; 27       private AddNewEmployeeDialog _add_employee_dialog = null; 28       private AddTrainingRecordDialog _add_training_record_dialog = null; 29       private static final int TEXTAREA_ROWS = 20; 30       private static final int TEXTAREA_COLS = 50; 31 32       public void init(){ 33         initializeGui(); 34         initializeRMI(); 35         initializeDialogs(); 36       } 37 38 39       private void initializeGui(){ 40         _panel1 = new JPanel(); 41         _panel2 = new JPanel(); 42         _south_panel = new JPanel(); 43         _textarea1 = new JTextArea(TEXTAREA_ROWS, TEXTAREA_COLS); 44         _textarea1.setEditable(false); 45         _scrollpane1 = new JScrollPane(_textarea1); 46         _button1 = new JButton("Search By Last Name"); 47         _button1.addActionListener(this); 48         _button2 = new JButton("Add New Employee"); 49         _button2.addActionListener(this); 50         _button3 = new JButton("Get Employee Training Records"); 51         _button3.addActionListener(this); 52         _button3.setEnabled(false); 53         _button4 = new JButton("Add Employee Training Record"); 54         _button4.addActionListener(this); 55         _button4.setEnabled(false); 56         _textfield1 = new JTextField(20); 57         _label1 = new JLabel("Last Name: "); 58         _panel1.add(_label1); 59         _panel1.add(_textfield1); 60         _panel1.add(_button1); 61         _panel2.add(_button2); 62         _panel2.add(_button3); 63         _panel2.add(_button4); 64         _south_panel.setLayout(new GridLayout(2, 1, 0, 0)); 65         _south_panel.add(_panel1); 66         _south_panel.add(_panel2); 67         this.getContentPane().add(_scrollpane1); 68         this.getContentPane().add(BorderLayout.SOUTH, _south_panel); 69       } 70 71       private void initializeRMI(){ 72         try{ 73            System.out.println("Attempting to lookup Employee_Persister_Service on :" + 74                               this.getCodeBase().getHost()); 75            _persister = (PersisterInterface)Naming.lookup("rmi://" + this.getCodeBase().getHost() + 76                                     "/Employee_Persister_Service"); 77         }catch(Exception e){ 78           e.printStackTrace(); 79         } 80       } 81 82       private void initializeDialogs(){ 83         _add_employee_dialog = new AddNewEmployeeDialog(this); 84         _add_employee_dialog.setVisible(false); 85         _add_training_record_dialog = new AddTrainingRecordDialog(this); 86         _add_training_record_dialog.setVisible(false); 87        } 88 89 90       public void actionPerformed(ActionEvent ae){ 91         if(ae.getActionCommand().equals("Search By Last Name")){ 92            try{ 93              _employees = _persister.queryByLastName(_textfield1.getText()); 94              if(_employees.size() > 0){ 95                _button3.setEnabled(true); 96                _button4.setEnabled(true); 97              } 98              _textarea1.setText(""); 99              for(int i = 0; i < _employees.size(); i++){ 100               _textarea1.append(((Employee)_employees.elementAt(i)).getFirstName() + '\t' + 101                                 ((Employee)_employees.elementAt(i)).getMiddleName() + '\t' + 102                                 ((Employee)_employees.elementAt(i)).getLastName() + '\t' + 103                                 ((Employee)_employees.elementAt(i)).getSSN() + '\n'); 104             } 105           }catch(Exception e){ 106             e.printStackTrace(); 107           } 108        } else if(ae.getActionCommand().equals("Add New Employee")){ 109              _add_employee_dialog.clearAllFields(); 110              _add_employee_dialog.setVisible(true); 111        } else if(ae.getActionCommand().equals("Submit New Employee")){ 112           try{ 113              _add_employee_dialog.setVisible(false); 114              Employee emp = new Employee(0, 115                                          _add_employee_dialog.getFirstName(), 116                                          _add_employee_dialog.getMiddleName(), 117                                          _add_employee_dialog.getLastName(), 118                                          _add_employee_dialog.getSSN(), 119                                          _add_employee_dialog.getDOB(), 120                                          null); 121              _persister.addNewEmployee(emp); 122 123            }catch(Exception e){ 124               e.printStackTrace(); 125            } 126         } else if(ae.getActionCommand().equals("Get Employee Training Records")){ 127           try{ 128             _button3.setEnabled(false); 129             _button4.setEnabled(false); 130             Employee emp = (Employee)_employees.elementAt(getSelectedLineNumber()); 131             emp = _persister.getEmployeeTrainingRecords(emp); 132             _textarea1.setText(""); 133             _textarea1.append(emp.getFirstName() + '\t' + 134                               emp.getMiddleName() + '\t' + 135                               emp.getLastName() + '\t' + 136                               emp.getSSN() + '\n'); 137             _textarea1.append("------------------------------------------------------\n"); 138             Vector training_records = emp.getChildRelations(); 139             for(int i = 0; i < training_records.size(); i++){ 140               _textarea1.append(((EmployeeTraining)training_records.elementAt(i)).getDate() + '\t' + 141                                 ((EmployeeTraining)training_records.elementAt(i)).getTopic() + '\t' + 142                                 ((EmployeeTraining)training_records.elementAt(i)).getResult() + '\n'); 143              } 144 145            }catch(ArrayIndexOutOfBoundsException aioobe){ 146               System.out.println("Invalid Employee Selection"); 147               return; 148             } 149            catch(Exception e){ 150               e.printStackTrace(); 151            } 152          } else if(ae.getActionCommand().equals("Add Employee Training Record")){ 153             _add_training_record_dialog.clearAllFields(); 154             _add_training_record_dialog.setVisible(true); 155          } else if(ae.getActionCommand().equals("Submit Training Record")){ 156            try{ 157              _add_training_record_dialog.setVisible(false); 158              Employee emp = (Employee)_employees.elementAt(getSelectedLineNumber()); 159              EmployeeTraining et = new EmployeeTraining(0, 160                                                         emp.getEmployeeID(), 161                                                         _add_training_record_dialog.getDate(), 162                                                         _add_training_record_dialog.getTopic(), 163                                                         _add_training_record_dialog.getResult()); 164              _persister.addTrainingRecord(et); 165            }catch(ArrayIndexOutOfBoundsException aioobe){ 166               System.out.println("Invalid employee selection"); 167               return; 168            } 169            catch(Exception e){ 170               e.printStackTrace(); 171            } 172 173        } 174      } // end actionPerformed() method 175 176 177      private int getSelectedLineNumber(){ 178        int caret_position = _textarea1.getCaretPosition(); 179        int line_number = 0; 180        int string_length = 0; 181        try{ 182          StringTokenizer st = new StringTokenizer(_textarea1.getText(), "\n"); 183          while(caret_position >= (string_length += st.nextToken().length()) ){ 184            line_number++; 185          } 186        }catch(NoSuchElementException ignored){ } 187        return line_number; 188      } 189 190    } // end EmployeeTrainingApplet class definition
image from book

Example 21.24: DBServerApp.java

image from book
 1     package com.pulpfreepress.dbserver; 2 3     import com.pulpfreepress.utils.*; 4     import java.rmi.*; 5     import java.rmi.registry.*; 6 7     public class DBServerApp { 8       public static void main(String[] args){ 9         DBServerProperties props = DBServerProperties.getInstance(); 10        try{ 11           System.out.println("Starting registry..."); 12           LocateRegistry.createRegistry(Integer.parseInt(props.getProperty(props.DEFAULT_RMI_PORT))); 13           System.out.println("Registry started on port " + props.getProperty(props.DEFAULT_RMI_PORT)); 14           System.out.println("Binding Persister service name with Persister instance..."); 15           Naming.bind(props.getProperty(props.DEFAULT_EMPLOYEE_PERSISTER_SERVICE), new Persister()); 16           System.out.println("Bind successful."); 17           System.out.println("Ready for remote method invocation."); 18        }catch(Exception e){ 19          e.printStackTrace(); 20        } 21      } // end main() method 22    } // end DBServerApp class definition
image from book

Example 21.25: Persister.java

image from book
 1     package com.pulpfreepress.dbserver; 2 3     import java.sql.*; 4     import java.util.*; 5     import java.rmi.*; 6     import java.rmi.server.*; 7     import com.pulpfreepress.business_objects.*; 8     import com.pulpfreepress.utils.*; 9 10 11    public class Persister extends UnicastRemoteObject implements PersisterInterface { 12      private static DBServerProperties _props = null; 13      private Connection _conn = null; 14 15      // Employees Table Column Values 16      private static final int ID_COL = 1; 17      private static final int FN_COL = 2; 18      private static final int MN_COL = 3; 19      private static final int LN_COL = 4; 20      private static final int SSN_COL = 5; 21      private static final int DOB_COL = 6; 22 23      // EmployeeTraining Table Column Values 24      private static final int TR_ID_COL = 1; 25      private static final int EMP_ID_COL = 2; 26      private static final int DATE_COL = 3; 27      private static final int TOPIC_COL = 4; 28      private static final int RESULT_COL = 5; 29 30 31      static{ 32        _props = DBServerProperties.getInstance(); 33       } 34 35      public Persister() throws RemoteException { 36        try{ 37          System.out.println("Loading JDBC driver class..."); 38          Class.forName(_props.getProperty(_props.DEFAULT_JDBC_DRIVER)); 39          System.out.println("JDBC driver class loaded successfully."); 40          System.out.println("Creating connection to database..."); 41          _conn = DriverManager.getConnection(_props.getProperty(_props.DEFAULT_MYSQL_JDBC_PROTOCOL) + 42                                             "://" + 43                                             _props.getProperty(_props.DEFAULT_SERVER_IP) + 44                                             ":" + 45                                             _props.getProperty(_props.DEFAULT_MYSQL_DB_PORT) + 46                                             "/" + 47                                             _props.getProperty(_props.DEFAULT_DATABASE) + 48                                             "?user=" + 49                                             _props.getProperty(_props.DEFAULT_DB_USER)); 50          System.out.println("Database connection created successfully."); 51        System.out.println("Persister object created successfully."); 52        }catch(Exception e){ 53          e.printStackTrace(); 54        } 55 56      } // end constructor 57 58 59      public void finalize() throws Throwable { 60        _conn.close(); 61        super.finalize(); 62      } 63 64      public synchronized Vector queryByLastName(String last_name){ 65           Vector employee_vector = new Vector(); 66           Statement statement = null; 67           ResultSet result_set = null; 68           String query = null; 69           try{ 70             if((last_name == null) || (last_name.equals(""))){ 71                query = "SELECT * FROM employees"; 72                statement = _conn.createStatement(); 73                result_set = statement.executeQuery(query); 74             }else{ 75                query = "SELECT * FROM employees WHERE (employees.last_name = '" + last_name +"')"; 76                statement = _conn.createStatement(); 77                result_set = statement.executeQuery(query); 78               } 79 80             while(result_set.next()){ 81               employee_vector.add(new Employee(result_set.getInt(ID_COL), 82                                                result_set.getString(FN_COL), 83                                                result_set.getString(MN_COL), 84                                                result_set.getString(LN_COL), 85                                                result_set.getString(SSN_COL), 86                                                result_set.getDate(DOB_COL).toString(), 87                                                null)); 88             } 89           }catch(Exception e){ 90              e.printStackTrace(); 91            } 92            finally{ 93              try{ 94              if(statement != null) statement.close(); 95              if(result_set != null) result_set.close(); 96              System.out.println("statement & result_set closed"); 97              }catch(Exception ignored){ } 98            } 99            return employee_vector; 100      } // end queryByLastName() method 101 102 103 104      public synchronized void addNewEmployee(Employee emp){ 105        PreparedStatement statement = null; 106        String insert = 107          "INSERT INTO employees (employee_id, first_name, middle_name, last_name, ssn, date_of_birth)" + 108          "VALUES (?,?,?,?,?,?)"; 109        try{ 110           statement = _conn.prepareStatement(insert); 111           statement.setInt(ID_COL, 0); 112           statement.setString(FN_COL, emp.getFirstName()); 113           statement.setString(MN_COL, emp.getMiddleName()); 114           statement.setString(LN_COL, emp.getLastName()); 115           statement.setString(SSN_COL, emp.getSSN()); 116           statement.setDate(DOB_COL, java.sql.Date.valueOf(emp.getDOB())); 117           statement.executeUpdate(); 118        }catch(Exception e){ 119           e.printStackTrace(); 120         } 121        finally{ 122          try{ 123            statement.close(); 124           }catch(Exception ignored){ } 125        } 126      } // end addNewEmployee() method 127 128 129      public synchronized void addTrainingRecord(EmployeeTraining et){ 130         PreparedStatement statement = null; 131         String insert = 132               "INSERT INTO employee_training (employee_training_id, employee_id, date, topic, result)" + 133               "VALUES (?,?,?,?,?)"; 134         try{ 135            statement = _conn.prepareStatement(insert); 136            statement.setInt(TR_ID_COL, 0); 137            statement.setInt(EMP_ID_COL, et.getEmployeeID()); 138            statement.setDate(DATE_COL, java.sql.Date.valueOf(et.getDate())); 139            statement.setString(TOPIC_COL, et.getTopic()); 140            statement.setString(RESULT_COL, et.getResult()); 141            statement.executeUpdate(); 142 143         }catch(Exception e){ 144           e.printStackTrace(); 145         } 146         finally{ 147           try{ 148             statement.close(); 149           }catch(Exception ignored){ } 150         } 151      } // end addTrainingRecord() method 152 153      public synchronized Employee getEmployeeTrainingRecords(Employee emp){ 154        PreparedStatement statement = null; 155        ResultSet result_set = null; 156        Vector training_records = new Vector(); 157        String query = "SELECT * " + 158                       "FROM employee_training " + 159                       "WHERE (employee_training.employee_id = ?)"; 160        try{ 161           statement = _conn.prepareStatement(query); 162           statement.setInt(1, emp.getEmployeeID()); 163           result_set = statement.executeQuery(); 164           while(result_set.next()){ 165             training_records.add(new EmployeeTraining(result_set.getInt(TR_ID_COL), 166                                                       result_set.getInt(EMP_ID_COL), 167                                                       result_set.getDate(DATE_COL).toString(), 168                                                       result_set.getString(TOPIC_COL), 169                                                       result_set.getString(RESULT_COL))); 170           } 171           emp.setChildRelations(training_records); 172 173        }catch(Exception e){ 174           e.printStackTrace(); 175         } 176        finally{ 177          try{ 178             statement.close(); 179             result_set.close(); 180          }catch(Exception ignored){ } 181        } 182        return emp; 183      }// end getEmployeeTrainingRecords() method 184 185 186 187    }// end Persister class definition
image from book

Example 21.26: DBServerProperties.java

image from book
 1     package com.pulpfreepress.utils; 2 3     import java.util.*; 4     import java.io.*; 5 6 7     public class DBServerProperties extends Properties { 8 9        // class constants - default key strings 10       public static final String DEFAULT_RMI_PORT = "DEFAULT_RMI_PORT"; 11       public static final String DEFAULT_SERVER_IP = "DEFAULT_SERVER_IP"; 12       public static final String DEFAULT_PROPERTIES_FILE = "DEFAULT_PROPERTIES_FILE"; 13       public static final String DEFAULT_JDBC_DRIVER = "DEFAULT_JDBC_DRIVER"; 14       public static final String DEFAULT_MYSQL_DB_PORT = "DEFAULT_MYSQL_DB_PORT"; 15       public static final String DEFAULT_DATABASE = "DEFAULT_DATABASE"; 16       public static final String DEFAULT_DB_USER = "DEFAULT_DB_USER"; 17       public static final String DEFAULT_MYSQL_JDBC_PROTOCOL = "DEFAULT_MYSQL_JDBC_PROTOCOL"; 18       public static final String DEFAULT_EMPLOYEE_PERSISTER_SERVICE = 19                                            "DEFAULT_EMPLOYEE_PERSISTER_SERVICE"; 20 21 22       // class constants - default value strings 23       private static final String DEFAULT_RMI_PORT_VALUE = "1099"; 24       private static final String DEFAULT_SERVER_IP_VALUE = "127.0.0.1"; 25       private static final String DEFAULT_PROPERTIES_FILE_VALUE = "DBserver.properties"; 26       private static final String DEFAULT_JDBC_DRIVER_VALUE = "com.mysql.jdbc.Driver"; 27       private static final String DEFAULT_MYSQL_DB_PORT_VALUE = "3306"; 28       private static final String DEFAULT_DATABASE_VALUE = "chapter_21"; 29       private static final String DEFAULT_DB_USER_VALUE = "swodog"; 30       private static final String DEFAULT_MYSQL_JDBC_PROTOCOL_VALUE = "jdbc:mysql"; 31       private static final String DEFAULT_EMPLOYEE_PERSISTER_SERVICE_VALUE = 32                                                    "Employee_Persister_Service"; 33 34       // class variables 35       private static DBServerProperties _properties_object = null; 36 37 38 39       private DBServerProperties( String properties_file ){ 40          try{ 41             FileInputStream fis = new FileInputStream(properties_file); 42             load(fis); 43           } catch(Exception e) { 44              System.out.println("Problem opening properties file!"); 45              System.out.println("Bootstrapping properties..."); 46              try{ 47                FileOutputStream fos = new FileOutputStream(DEFAULT_PROPERTIES_FILE_VALUE); 48                setProperty(DEFAULT_RMI_PORT, DEFAULT_RMI_PORT_VALUE); 49                setProperty(DEFAULT_SERVER_IP, DEFAULT_SERVER_IP_VALUE); 50                setProperty(DEFAULT_PROPERTIES_FILE, DEFAULT_PROPERTIES_FILE_VALUE); 51                setProperty(DEFAULT_JDBC_DRIVER, DEFAULT_JDBC_DRIVER_VALUE); 52                setProperty(DEFAULT_MYSQL_DB_PORT, DEFAULT_MYSQL_DB_PORT_VALUE); 53                setProperty(DEFAULT_DATABASE, DEFAULT_DATABASE_VALUE); 54                setProperty(DEFAULT_DB_USER, DEFAULT_DB_USER_VALUE); 55                setProperty(DEFAULT_MYSQL_JDBC_PROTOCOL, DEFAULT_MYSQL_JDBC_PROTOCOL_VALUE); 56                setProperty(DEFAULT_EMPLOYEE_PERSISTER_SERVICE, DEFAULT_EMPLOYEE_PERSISTER_SERVICE_VALUE); 57 58                super.store(fos, "DBServerProperties File - Edit Carefully"); 59                fos.close(); 60               }catch(Exception e2){ System.out.println("Uh ohh...Bigger problems exist!"); } 61           } 62       } 63 64 65    /************************************************************************************************** 66    *  Private default constructor. Applications will get an instance via the getInstance() method. 67    *  @see getInstance() 68    ****************************************************************************************************/ 69       private DBServerProperties(){ 70           this(DEFAULT_PROPERTIES_FILE_VALUE); 71       } 72 73    /************************************************************************************************** 74    *  The store() method attempts to persist its properties collection. 75    ****************************************************************************************************/ 76       public void store(){ 77         try{ 78           FileOutputStream fos = new 79                 FileOutputStream(getProperty(DEFAULT_PROPERTIES_FILE)); 80           super.store(fos, "DBServerProperties File"); 81           fos.close(); 82         }catch(Exception e){ System.out.println("Trouble storing properties!"); } 83       } 84 85    /************************************************************************************************** 86    *  getInstance() returns a singleton instance if the DBServerProperties object. 87    ****************************************************************************************************/ 88 89       public static DBServerProperties getInstance(){ 90         if(_properties_object == null){ 91            _properties_object = new DBServerProperties(); 92         } 93         return _properties_object; 94       } 95    } // end DBServerProperties class definition
image from book

Employee and EmployeeTraining Classes

Referring to examples 21.19 and 21.20 — the Employee and EmployeeTraining classes each represent a business object within the employee training management system application domain. The Employee class contains fields that represent important employee attributes. Additionally, on line 14 of example 21.19, the Employee class declares a Vector reference field named _child_relations. The purpose of the _child_relations field is to contain references to an employee’s training records. This field is set to null and populated only when an employee’s training records are retrieved from the database.

The EmployeeTraining class models the employee training entity. Each of its fields maps to a column in the employee_training database table.

AddNewEmployeeDialog and AddTrainingRecordDialog Classes

Referring to examples 21.21 and 21.22 —these two dialog classes are utilized by the EmployeeTrainingApplet class to capture new employee and employee training information for entry into the database.

EmployeeTrainingApplet Class

Referring to example 21.23 — the EmployeeTrainingApplet class is the primary client-side component. Its purpose is to provide the primary user interface, initialize the RMI service, and translate GUI actions into RMI calls where required. The initializeRMI() method on line 71 is responsible for looking up the employee persister service (Employee_Persister_Service) on the host server.

The actionPerformed() method on line 90 handles all the button clicks, even for its two dialog classes. When the “Search By Last Name” button is clicked the persister’s queryByLastName() method is called on line 91 using the contents of _textfield1 as an argument. The _employees Vector reference is initialized as a result of the method call and if its length is greater than zero then each Employee object’s information is appended to the text area on lines 100 through 103. At this point the _child_relations field of each Employee object is not initialized.

When an employee is selected in the text area and the “Get Employee Training Records” button is clicked, the getSelectedLineNumber() method is called to determine which employee is selected. The Employee reference corresponding to the selected line number is retrieved from the _employees Vector and the persister’s getEmployeeTrainin-gRecords() method is called with the Employee reference as an argument on line 131. The employee’s training records are then displayed in the text area.

DBServerApp Class

Referring to example 21.24 — the DBServerApp class serves as the main application class for the server-side component of the employee training management system. Its primary job is to start the RMI registry and register an instance of the Persister class to its service name. Note that all information required by the DBServerApp class is provided by the DBServerProperties class and retrieved from a properties file.

Persister Class

Referring to example 21.25 — the Persister class is the primary server-side component. Its job is to translate RMI method calls into JDBC calls against the employee training management database. The JDBC initialization takes place in the constructor method beginning on line 35. This class, too, utilizes the DBServerProperties class to retrieve server-side configuration information.

Stepping through the queryByLastName() method on line 64 — the main action occurs in the try-catch block starting on line 69. If the last_name String reference is equal to null or contains no value then a query is formulated to retrieve all employees from the database. If, however, the last_name string contains a value, it is used to query on employees having that last name.

The while loop starting on line 80 processes the returned ResultSet and populates a Vector with Employee references. When all is complete the statement and result_set close() methods are called and the Vector of Employee references is returned.

Let’s look now at the getEmployeeTrainingRecords() method on line 153. An Employee reference serves as the method parameter. This Employee reference is already populated with all employee attribute data with the exception of its related employee training records. The Employee reference is used to extract the employeeID which is used to query the database for that employee’s training records. A Vector containing the employee’s training records is populated in the while loop starting on line 164. On line 171 the setChildRelations() method is called using the populated Vector as an argument. The fully populated Employee reference is then returned.

DBServerProperties

Referring to example 21.26 — the DBServerProperties class extends the java.util.Properties class and is utilized by the DBServerApp and Persister classes to retrieve application configuration information from a properties file. You’ve seen examples of Properties classes in previous chapters. I’d like to draw your attention to the default value strings defined on lines 23 through 32. To get the employee training management system to run you will more than likely need to change the following default values: DEFAULT_SERVER_IP_VALUE, DEFAULT_DATABASE_-VALUE, & DEFAULT_DB_USER_VALUE.

Statements vs. Prepared Statements

The Persister class makes use of JDBC Statements and PreparedStatements. (A third type of JDBC statement, CallableStatement, is used to call stored database procedures and is not utilized in this example.) All three types of JDBC statements can be retrieved from a JDBC Connection via its createStatement(), prepareStatement(), and pre- pareCall() methods respectively. I’d like to dwell for a moment on when you would use a Statement vs. a Prepared-Statement.

Statement

Use a Statement when you are executing a simple query statement (select, from, where). By simple I mean one that is not built from too many string concatenations. Long or complex string concatenations are inefficient and error prone.

PreparedStatement

Use a PreparedStatement when the query is complex or you are performing inserts and updates to the database. PreparedStatements can be used repeatedly and are more efficient than their Statement counterparts.

A PreparedStatement is formulated with the help of variable placeholders in the form of question marks: ‘?’. Refer to the addTrainingRecord() method of the Persister class starting on line 129. An EmployeeTraining reference is passed as an argument to the method call. The SQL insert statement string is formulated on lines 131 through 133. The question marks that appear in the parentheses of the values clause on line 133 correspond, from left to right, to the fields that are listed between the parentheses on line 132. On line 135 the PreparedStatement is created using the insert string as an argument. However, before the prepared statement can be executed, each statement variable must be set using a set method that corresponds to the appropriate type. (i.e., setInt(), setString(), etc.) Only after all statement variables are properly set can the PreparedStatement’s executeUpdate() method be called.




Java For Artists(c) The Art, Philosophy, and Science of Object-Oriented Programming
Java For Artists: The Art, Philosophy, And Science Of Object-Oriented Programming
ISBN: 1932504052
EAN: 2147483647
Year: 2007
Pages: 452

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net