Home

MassLight presents

Chapter 7: A Case Study

The MyCo Project

Goals After completing this chapter, the student will be able to
  • understand the use of Enterprise JavaBeans for database access.
  • use EJBs with the Struts framework.
  • better understand the J2EE technologies.
Prerequisites In order to complete this chapter successfully, the student must
  • understand the Struts framework.
  • have a basic knowledge of SQL.
  • know the order that methods of an EJB are invoked.
Objectives The objective for this chapter is to combine all of the technologies learned thus far in the course into one application, demonstrating how each technology works with the other technologies to create powerful and fault-tolerant web applications.

This chapter presents a web application to keep track of the employees in a company, MyCo. This is done through a simple user interface that supports adding, removing, and modifying employee information, which includes the employee's name, extension, department, and city where the employee is located.

The main page represents the user with two options. The user can either view the directory of employees, or add a new employee. From the view page, the user can choose to modify or delete an employee. All pages include links back to the main page.

The application is implemented with JSPs, the Struts framework, and Enterprise Java Beans.

Database Connection Pooling

Database connections are essential resources, but they are heavy to create. Many users can use a web application simultaneously, and each needs to have a database connection, but none of them need to use it for more than a few seconds at a time (if that). Each user could create a new connection every time they need it, but this would lead to poor performance. Each user could create a database connection once and keep it open until they quit, but this would lead to poor scalability. As a compromise, a pool of open connections to the database can be maintained by the J2EE server. When a connection to the database is needed, the user requests one from the pool. When the connection is no longer needed, it is surrendered back to the connection pool.

Setting Up A Connection Pool In JBoss

To use a connection pool in JBoss, open the jboss.jcml configuration file and find the JDBC configuration section. Actually, find the configuration information we added in the previous chapter, that told JBoss about OpenBase. Add the following information just below the OpenBase driver information in the JDBC section:


  <mbean code="org.jboss.jdbc.XADataSourceLoader"
     name="DefaultDomain:service=XADataSource,name=OpenBasePool">
   <attribute name="DataSourceClass">
     org.jboss.pool.jdbc.xa.wrapper.XADataSourceImpl
   </attribute>
   <attribute name="PoolName">OpenBasePool</attribute>
   <attribute name="URL">jdbc:openbase://127.0.0.1/employee</attribute>
   <attribute name="JDBCUser">admin</attribute>
   <attribute name="Password">admin</attribute>
   <attribute name="LoggingEnabled">true</attribute>
  </mbean>

Requesting A Database Connection


System.setProperty("java.naming.factory.initial", 
                   "org.jnp.interfaces.NamingContextFactory");
System.setProperty("java.naming.provider.url", "localhost:1099");
InitialContext ic = new InitialContext();
DataSource ds = (DataSource) ic.lookup("java:OpenBasePool");
connection = ds.getConnection();

Releasing The Database Connection


try {
    connection.close();
} catch (SQLException e) {
    System.out.println("An SQL Exception occurred while closing the connection");
}

Prepared Statements

Instead of creating a normal SQL statement, a prepared statement may be used. A prepared statement looks like a normal SQL statement, except that it may contain ‘?’s. A ‘?’ in a prepared statement will be substituted for a value at runtime. This enables prepared statements to provide quicker results because not all the work is done at runtime. Prepared statements are not always necessary; they are an optimization technique that you can use to speed up the most heavily used areas of your application.

Fetching Data


String sqlString = "select FIRSTNAME, LASTNAME, EXTENSION, CITY_ID, DEPARTMENT_ID " +
    "from EMPLOYEE where EMPLOYEE_ID=?";
java.sql.PreparedStatement preparedStatement = connection.prepareStatement(sqlString);
preparedStatement.clearParameters();
preparedStatement.setObject(1, getEmployeeid(), Types.INTEGER);
preparedStatement.executeQuery();

Accessing Fetched Data


ResultSet rs = preparedStatement.getResultSet();
if (rs.next()) {
    setFirstname(rs.getString(1));
    setLastname(rs.getString(2));
    setExtension(rs.getString(3));
    setCityid(new Integer(rs.getInt(4)));
    setDepartmentid(new Integer(rs.getInt(5)));
}
rs.close();
preparedStatement.close();

Updating Data


try {
    String sqlString = "update EMPLOYEE set FIRSTNAME=?, LASTNAME=?, " +
        "EXTENSION=?, CITY_ID=?, DEPARTMENT_ID=? where EMPLOYEEID=?";
    java.sql.PreparedStatement preparedStatement = connection.prepareStatement(sqlString);
    preparedStatement.clearParameters();
    preparedStatement.setObject(1, getFirstname(), Types.VARCHAR);
    preparedStatement.setObject(2, getLastname(), Types.VARCHAR);
    preparedStatement.setObject(3, getExtension(), Types.VARCHAR);
    preparedStatement.setObject(4, getCityid(), Types.INTEGER);
    preparedStatement.setObject(5, getDepartmentid(), Types.INTEGER);
    preparedStatement.setObject(6, getEmployeeid(), Types.INTEGER);
    connection.setAutoCommit(false);
    preparedStatement.executeQuery();
    connection.commit();
    preparedStatement.close();
} catch (SQLException e) {
    connection.rollback();
}

Inserting New Data


try {
    String sqlString = "insert into EMPLOYEE " +
      "(EMPLOYEE_ID, FIRSTNAME, LASTNAME, EXTENSION, CITY_ID, DEPARTMENT_ID) values (" +
      "?, ?, ?, ?, ?, ?)";
    java.sql.PreparedStatement preparedStatement = connection.prepareStatement(sqlString);
    preparedStatement.clearParameters();
    preparedStatement.setObject(1, getEmployeeid(), Types.INTEGER);
    preparedStatement.setObject(2, getFirstname(), Types.VARCHAR);
    preparedStatement.setObject(3, getLastname(), Types.VARCHAR);
    preparedStatement.setObject(4, getExtension(), Types.VARCHAR);
    preparedStatement.setObject(5, getCityid(), Types.INTEGER);
    preparedStatement.setObject(6, getDepartmentid(), Types.INTEGER);
    connection.setAutoCommit(false);
    preparedStatement.executeQuery();
    connection.commit();
    preparedStatement.close();
} catch (SQLException e) {
    connection.rollback();
}

Deleting Data


try {
    String sqlString = "delete from EMPLOYEE where EMPLOYEE_ID=?";
    java.sql.PreparedStatement preparedStatement = connection.prepareStatement(sqlString);
    preparedStatement.clearParameters();
    preparedStatement.setObject(1, employeeid, Types.INTEGER);
    connection.setAutoCommit(false);
    preparedStatement.executeQuery();
    connection.commit();
    preparedStatement.close();
} catch (SQLException e) {
    connection.rollback();
}

MyCo: A Complete J2EE Application

The MyCo Database

The MyCo database will be implemented in OpenBase, which we saw in the previous chapter. However, the schema is simple enough that it could be implemented in virtually any database. All you would need to do is change the JDBC driver, and the rest of your code would still work.

EMPLOYEE DEPARTMENT CITY
EMP_ID (integer)
primary key, not null
DEPT_ID (integer)
primary key, not null
CITY_ID (integer)
primary key, not null
FIRSTNAME (varchar) NAME (varchar) NAME (varchar)
LASTNAME (varchar) PHONE (varchar)
EXTENSION (varchar) SECRETARY_ID (integer)
CITY_ID (integer)
DEPT_ID (integer)

We will not actually be creating this database from scratch; we have a dump of the data already, so we will be restoring that data (like we did in the previous chapter with the PHONE database).

(If you have not already done so, you can download this and other examples used in this course. Mac OS X or other UNIX users click here instead.)

Do this:

  1. Create the database. This uses the OpenBase Manager program.
databases/employee.bck
create table _SYS_APP_FIELDS (
_rowid longlong NOT NULL UNIQUE ,
_timestamp datetime ,
_version long ,
indexType int ,
name varchar ,
type varchar ,
primaryKey int ,
length int ,
table_id longlong ,
notNull int ,
defaultValue varchar )
go
create table _SYS_APP_PREFERENCES (
_rowid longlong NOT NULL UNIQUE ,
_timestamp datetime ,
_version long ,
key varchar INDEX ,
value varchar ,
order long INDEX )
go
create table _SYS_APP_TABLES (
_rowid longlong NOT NULL UNIQUE ,
_timestamp datetime ,
_version long ,
name varchar ,
x float ,
y float ,
height float ,
width float ,
primaryKeyFieldID longlong ,
clusteredFieldID longlong )
go
delete from _SYS_APPS
go
delete from _SYS_GROUPS
go
create table _SYS_JDBC2v1 (
_rowid longlong NOT NULL UNIQUE ,
_timestamp datetime ,
_version long ,
typename char(50) ,
type int ,
searchable int ,
precision int ,
max_scale int ,
order int )
go
create table _SYS_JDBC4 (
_rowid longlong NOT NULL UNIQUE ,
_timestamp datetime ,
_version long ,
typename char(50) ,
type int ,
searchable int ,
precision int ,
max_scale int ,
order int )
go
delete from _SYS_PERM
go
create table _SYS_QUERY (
_rowid longlong NOT NULL UNIQUE ,
_timestamp datetime ,
_version long ,
title char(200) INDEX ,
sql object )
go
delete from _SYS_RELATIONSHIP
go
delete from _SYS_REPLICATION
go
delete from _SYS_USERS
go
create table CITY (
_rowid longlong NOT NULL UNIQUE ,
_timestamp datetime ,
_version long ,
CITY_ID int UNIQUE ,
NAME varchar )
go
CREATE PRIMARY KEY CITY (CITY_ID)
go
create table DEPARTMENT (
_rowid longlong NOT NULL UNIQUE ,
_timestamp datetime ,
_version long ,
PHONE varchar ,
NAME varchar ,
SECRETARY_ID int ,
DEPARTMENT_ID int UNIQUE )
go
CREATE PRIMARY KEY DEPARTMENT (DEPARTMENT_ID)
go
create table EMPLOYEE (
_rowid longlong NOT NULL UNIQUE ,
_timestamp datetime ,
_version long ,
CITY_ID int ,
DEPARTMENT_ID int ,
EMPLOYEE_ID int NOT NULL UNIQUE ,
LASTNAME varchar ,
FIRSTNAME varchar ,
EXTENSION varchar )
go
CREATE PRIMARY KEY EMPLOYEE (EMPLOYEE_ID)
go
create table EO_PK_TABLE (
_rowid longlong NOT NULL UNIQUE ,
_timestamp datetime ,
_version long ,
NAME char(40) ,
PK int )
go
TABLE _SYS_APP_FIELDS
_rowid, _timestamp, _version, defaultValue, indexType, length, name, notNull, primaryKey, table_id, type
'1' , '11207787.889387995004' , '5' , '' , '2' , '4' , 'CITY_ID' , '0' , '1' , '1' , 'integer' 
'2' , '11207787.873592067510' , '5' , '' , '2' , '8' , '_rowid' , '1' , '0' , '1' , 'longlong' 
'3' , '11207787.881354546174' , '5' , '' , '0' , '8' , '_timestamp' , '0' , '0' , '1' , 'datetime' 
'4' , '11207787.885409614071' , '5' , '' , '0' , '4' , '_version' , '0' , '0' , '1' , 'long' 
'5' , '11207787.894005864858' , '5' , '' , '0' , '4096' , 'NAME' , '0' , '0' , '1' , 'char' 
'6' , '11207787.995252961292' , '6' , '' , '0' , '4096' , 'LASTNAME' , '0' , '0' , '2' , 'char' 
'7' , '11207787.975824093446' , '5' , '' , '0' , '4' , '_version' , '0' , '0' , '2' , 'long' 
'8' , '11207787.979770679026' , '5' , '' , '0' , '4' , 'CITY_ID' , '0' , '0' , '2' , 'integer' 
'9' , '11207787.962303306907' , '5' , '' , '2' , '8' , '_rowid' , '1' , '0' , '2' , 'longlong' 
'10' , '11207787.970909984782' , '5' , '' , '0' , '8' , '_timestamp' , '0' , '0' , '2' , 'datetime' 
'11' , '11207936.149342946708' , '7' , '' , '0' , '4096' , 'EXTENSION' , '0' , '0' , '2' , 'char' 
'12' , '11207787.991427551954' , '7' , '' , '2' , '4' , 'EMPLOYEE_ID' , '1' , '1' , '2' , 'integer' 
'13' , '11207788.003969855606' , '6' , '' , '0' , '4096' , 'FIRSTNAME' , '0' , '0' , '2' , 'char' 
'14' , '11207787.987668121233' , '5' , '' , '0' , '4' , 'DEPARTMENT_ID' , '0' , '0' , '2' , 'integer' 
'15' , '11207788.081188667565' , '5' , '' , '0' , '4096' , 'PHONE' , '0' , '0' , '3' , 'char' 
'16' , '11207788.073375049978' , '5' , '' , '0' , '8' , '_timestamp' , '0' , '0' , '3' , 'datetime' 
'17' , '11207788.064866315573' , '5' , '' , '2' , '8' , '_rowid' , '1' , '0' , '3' , 'longlong' 
'18' , '11207788.084977816790' , '5' , '' , '0' , '4096' , 'NAME' , '0' , '0' , '3' , 'char' 
'19' , '11207788.088803105056' , '5' , '' , '0' , '4' , 'SECRETARY_ID' , '0' , '0' , '3' , 'integer' 
'20' , '11207788.077288936823' , '5' , '' , '0' , '4' , '_version' , '0' , '0' , '3' , 'long' 
'21' , '11207788.092554474250' , '5' , '' , '2' , '4' , 'DEPARTMENT_ID' , '0' , '1' , '3' , 'integer' 
TABLE _SYS_APP_PREFERENCES
_rowid, _timestamp, _version, key, order, value
'1' , '11725615.682600136846' , '9' , 'SchemaDatabaseVersion' , '0' , '1' 
'2' , '9475504.511265635490' , '1' , 'SchemaVersion' , '0' , '' 
'3' , '11207936.239944290370' , '12' , 'SchemaTimeStamp' , '0' , '182;2001-05-10 13:18:56 -0400;3;2001-05-10 13:18:56 -0400;21;2001-05-10 13:18:56 -0400' 
TABLE _SYS_APP_TABLES
_rowid, _timestamp, _version, clusteredFieldID, height, name, primaryKeyFieldID, width, x, y
'1' , '11207936.171712143346' , '11' , '405328' , '75.0000000000000' , 'CITY' , NULL, '150.0000000000000' , '204.0000000000000' , '153.0000000000000' 
'2' , '11207936.153827134520' , '11' , '405328' , '75.0000000000000' , 'EMPLOYEE' , NULL, '150.0000000000000' , '204.0000000000000' , '153.0000000000000' 
'3' , '11207936.188525659963' , '10' , '405328' , '75.0000000000000' , 'DEPARTMENT' , NULL, '150.0000000000000' , '204.0000000000000' , '153.0000000000000' 
TABLE _SYS_APPS
_rowid, _timestamp, _version, appName
'2' , '9475502.458313584327' , '1' , 'OpenBaseManager' 
'3' , '11125299.483367169275' , '1' , 'JDBC' 
TABLE _SYS_GROUPS
_rowid, _timestamp, _version, appAuthorizationEnabled, authorizedApps, blockedRadApps, group
'1' , '15869401.859825039282' , '3' , '0' , '||' , '||' , 'admin' 
TABLE _SYS_JDBC2v1
_rowid, _timestamp, _version, max_scale, order, precision, searchable, type, typename
'1' , '15869376.265289928764' , '1' , '0' , '0' , '0' , '3' , '1' , 'char' 
'2' , '15869376.267148101702' , '1' , '0' , '0' , '10' , '2' , '4' , 'int' 
'3' , '15869376.268743053078' , '1' , '0' , '0' , '0' , '1' , '-4' , 'object' 
'4' , '15869376.276104232296' , '1' , '0' , '0' , '20' , '2' , '-5' , 'longlong' 
'5' , '15869376.277965048328' , '1' , '0' , '1' , '20' , '2' , '8' , 'double' 
'6' , '15869376.279329052194' , '1' , '6' , '0' , '20' , '2' , '93' , 'datetime' 
'7' , '15869376.280617693440' , '1' , '2' , '0' , '20' , '2' , '3' , 'money' 
'8' , '15869376.281898763030' , '1' , '15' , '0' , '20' , '2' , '8' , 'float' 
'9' , '15869376.283183138817' , '1' , '0' , '1' , '10' , '2' , '4' , 'long' 
'10' , '15869376.284771358594' , '1' , '0' , '0' , '0' , '2' , '91' , 'date' 
'11' , '15869376.286046359688' , '1' , '0' , '0' , '0' , '2' , '92' , 'time' 
TABLE _SYS_JDBC4
_rowid, _timestamp, _version, max_scale, order, precision, searchable, type, typename
'1' , '9475499.504065632820' , '1' , '0' , '0' , '0' , '3' , '1' , 'char' 
'2' , '9475499.504065632820' , '1' , '0' , '0' , '10' , '2' , '4' , 'int' 
'3' , '9475499.514080047607' , '1' , '0' , '0' , '0' , '1' , '-4' , 'object' 
'4' , '9475499.514080047607' , '1' , '0' , '0' , '20' , '2' , '-5' , 'longlong' 
'5' , '9475499.514080047607' , '1' , '0' , '1' , '20' , '2' , '8' , 'double' 
'6' , '9475499.514080047607' , '1' , '6' , '0' , '20' , '2' , '93' , 'datetime' 
'7' , '9475499.514080047607' , '1' , '2' , '0' , '20' , '2' , '3' , 'money' 
'8' , '9475499.514080047607' , '1' , '15' , '0' , '20' , '2' , '8' , 'float' 
'9' , '9475499.514080047607' , '1' , '0' , '1' , '10' , '2' , '4' , 'long' 
'10' , '9475499.524094343185' , '1' , '0' , '0' , '0' , '2' , '91' , 'date' 
'11' , '9475499.524094343185' , '1' , '0' , '0' , '0' , '2' , '92' , 'time' 
TABLE _SYS_PERM
_rowid, _timestamp, _version, name, p_delete, p_insert, p_select, p_update, table
TABLE _SYS_QUERY
_rowid, _timestamp, _version, sql, title
OBJECT
'<<<<*1*>>>>'
object
78
53454C4543542074302E5F726F7769642C2074302E5F74696D657374616D702C2074302E5F7665727369
6F6E2C2074302E434954595F49442C2074302E4E414D452046524F4D2043495459207430
.end.
'1' , '10515524.025541719050' , '2' , '<<<<*1*>>>>' , 'CityQuery' 
OBJECT
'<<<<*2*>>>>'
object
111
53454C4543542074302E5F726F7769642C2074302E5F74696D657374616D702C2074302E5F7665727369
6F6E2C2074302E444550545F49442C2074302E4E414D452C2074302E50484F4E452C2074302E53454352
45544152595F49442046524F4D204445504152544D454E54207430
.end.
'2' , '10515536.128062479197' , '1' , '<<<<*2*>>>>' , 'DepartmentQuery' 
OBJECT
'<<<<*3*>>>>'
object
137
53454C4543542074302E5F726F7769642C2074302E5F74696D657374616D702C2074302E5F7665727369
6F6E2C2074302E434954595F49442C2074302E444550545F49442C2074302E454D505F49442C2074302E
455854454E53494F4E2C2074302E46495253544E414D452C2074302E4C4153544E414D452046524F4D20
454D504C4F594545207430
.end.
'3' , '10515545.771298721432' , '1' , '<<<<*3*>>>>' , 'EmployeeQuery' 
TABLE _SYS_REPLICATION
_rowid, _timestamp, _version, conflict_code, local_date, remote_date, tablename, target_database, target_host, target_password
TABLE _SYS_USERS
_rowid, _timestamp, _version, appSecurity, authorizedApps, email, fullname, login, password, popLogin, popPassword, popServer, smtpServer, usergroup
'1' , '15869401.867665303871' , '3' , '0' , NULL, '' , 'Administrator' , 'admin' , 'DIAJDIGDHDBCJDCI' , '' , '' , '' , '' , 'admin' 
TABLE CITY
_rowid, _timestamp, _version, CITY_ID, NAME
'1' , '11733756.967038359493' , '9' , '1' , 'Orlando' 
'2' , '11125299.370046524330' , '4' , '2' , 'New York' 
'3' , '11125299.436561474576' , '6' , '3' , 'Toronto' 
'5' , '11125299.423119541257' , '4' , '5' , 'San Luis Obispo' 
'6' , '11125299.429148418828' , '5' , '6' , 'Salt Lake City' 
'7' , '11125299.441440487280' , '4' , '7' , 'Kansas City' 
'8' , '11125299.440038463100' , '3' , '8' , 'Bismarck' 
'10' , '11296994.582311162725' , '1' , '300' , 'Springfield' 
'11' , '11733755.998177478090' , '3' , '11' , 'Washington DC' 
TABLE DEPARTMENT
_rowid, _timestamp, _version, DEPARTMENT_ID, NAME, PHONE, SECRETARY_ID
'1' , '11125299.410846965387' , '12' , '1' , 'Sales' , '5521' , NULL
'2' , '11125299.409506827592' , '4' , '2' , 'Engineering' , '5531' , NULL
TABLE EMPLOYEE
_rowid, _timestamp, _version, CITY_ID, DEPARTMENT_ID, EMPLOYEE_ID, EXTENSION, FIRSTNAME, LASTNAME
'52' , '21482695.351134277880' , '1' , '2' , '2' , '90' , '9032' , 'Mark' , 'Yellowford' 
'33' , '11824000.298210268840' , '1' , '3' , '2' , '7878' , '2932' , 'Katie' , 'Mullholland' 
'32' , '11733864.158240400254' , '1' , '11' , '2' , '69' , '6969' , 'Stan' , 'Foresight' 
'31' , '11733666.934869606047' , '1' , '6' , '2' , '59' , '5555' , 'Catalin' , 'Poll' 
'30' , '16134490.803055632860' , '5' , '5' , '2' , '89' , '2222' , 'Quentin' , 'Varquee' 
'26' , '11733875.436699779704' , '4' , '11' , '1' , '2' , '9023' , 'Elisabeth' , 'Muskrat' 
'25' , '11824025.344245314598' , '3' , '1' , '1' , '6' , '9932' , 'Juniper' , 'Beads' 
'24' , '11725296.852966878563' , '3' , '6' , '1' , '7' , '2930' , 'Debbie' , 'Reynolds' 
'23' , '11725305.505942394956' , '4' , '8' , '2' , '5' , '6609' , 'Marilyn' , 'Colburn' 
'22' , '11721548.348074020817' , '1' , '7' , '2' , '3' , '4004' , 'Colby' , 'Smith' 
'20' , '16132498.553308600560' , '4' , '1' , '2' , '1' , '1001' , 'Joseph' , 'Turner' 
'39' , '16134802.706042600795' , '2' , '1' , '1' , '9095' , '23' , 'Tracy' , 'Davis' 
'40' , '16132589.374745823442' , '2' , '1' , '1' , '9096' , '0033' , 'Michael' , 'Strongman' 
'44' , '21482777.570284608751' , '4' , '1' , '1' , '666' , '666' , 'Jonathan' , 'Wensleydale' 
'48' , '16149047.240697329863' , '1' , '1' , '1' , '9102' , '1234' , 'Peter' , 'Piper' 
'49' , '16149221.292628999800' , '3' , '5' , '2' , '888' , '9876' , 'Theodore' , 'Bonn' 
'50' , '17162220.083476159721' , '1' , '5' , '2' , '9890' , '9923' , 'Gweneth' , 'Pecan' 
TABLE EO_PK_TABLE
_rowid, _timestamp, _version, NAME, PK
'1' , '16149047.143503218890' , '10' , 'EMPLOYEE' , '9102'

The directory structure for this case study is shown below. This should be old hat by now. Copy the struts.jar to the lib folder and the matching .tld files into the WEB-INF folder. Any JSPs should be placed in the same folder as the WEB-INF/. The source files to the Action and ActionForm classes and the EJBs should go in the classes folder, with an appropriate hierarchy for the package name. The ApplicationResources.properties file should be placed in the top level of the classes folder. The struts.jar and accompanying files should be placed in the lib and WEB-INF/ folders, respectively.

code/Chapter7/Employee
Employee
  |
  +-- build.xml (*)
  |
  +-- EmployeeClient
  |     |
  |     +-- employeeadd.jsp (*)
  |     |
  |     +-- employeeaddfailure.jsp (*)
  |     |
  |     +-- employeeaddsuccess.jsp (*)
  |     |
  |     +-- employeedeletefailure.jsp (*)
  |     |
  |     +-- employeedeletesuccess.jsp (*)
  |     |
  |     +-- employeeviewfailure.jsp (*)
  |     |
  |     +-- index.jsp (*)
  |     |
  |     +-- build.xml (*)
  |     |
  |     +-- employeeviewsuccess.jsp (*)
  |     |
  |     +-- employeemodify.jsp (*)
  |     |
  |     +-- WEB-INF
  |           |
  |           +-- ApplicationResources.properties (*)
  |           |
  |           +-- web.xml (*)
  |           |
  |           +-- app.tld (*)
  |           |
  |           +-- struts-bean.tld (*)
  |           |
  |           +-- struts-form.tld (*)
  |           |
  |           +-- struts-html.tld (*)
  |           |
  |           +-- struts-logic.tld (*)
  |           |
  |           +-- struts-template.tld (*)
  |           |
  |           +-- struts.tld (*)
  |           |
  |           +-- struts-config.xml (*)
  |           |
  |           +-- classes
  |           |     |
  |           |     +-- com
  |           |           |
  |           |           +-- masslight
  |           |                 |
  |           |                 +-- Employee
  |           |                       |
  |           |                       +-- EmployeeDeleteForm.java (*)
  |           |                       |
  |           |                       +-- EmployeeAddForm.java (*)
  |           |                       |
  |           |                       +-- EmployeeDeleteAction.java (*)
  |           |                       |
  |           |                       +-- EmployeeAddAction.java (*)
  |           |                       |
  |           |                       +-- EmployeeModifyAction.java (*)
  |           |                       |
  |           |                       +-- EmployeeModifyForm.java (*)
  |           |                       |
  |           |                       +-- EmployeeModifySetupForm.java (*)
  |           |                       |
  |           |                       +-- EmployeeViewAction.java (*)
  |           |                       |
  |           |                       +-- EmployeeAddSetupAction.java (*)
  |           |                       |
  |           |                       +-- EmployeeModifySetupAction.java (*)
  |           |
  |           +-- lib
  |                 |
  |                 +-- struts.jar (*)
  |
  +-- EmployeeEJB
        |
        +-- build.xml (*)
        |
        +-- META-INF
        |     |
        |     +-- sun-j2ee-ri.xml (*)
        |     |
        |     +-- application.xml (*)
        |
        +-- com
              |
              +-- masslight
                    |
                    +-- Employee
                    |     |
                    |     +-- Employee.java (*)
                    |     |
                    |     +-- ejb-jar.xml (*)
                    |     |
                    |     +-- EmployeeHome.java (*)
                    |     |
                    |     +-- EmployeeEJB.java (*)
                    |
                    +-- Department
                    |     |
                    |     +-- Department.java (*)
                    |     |
                    |     +-- ejb-jar.xml (*)
                    |     |
                    |     +-- DepartmentHome.java (*)
                    |     |
                    |     +-- DepartmentEJB.java (*)
                    |
                    +-- City
                          |
                          +-- City.java (*)
                          |
                          +-- CityHome.java (*)
                          |
                          +-- ejb-jar.xml (*)
                          |
                          +-- CityEJB.java (*)

(*) denotes a file


Employee EJB

The Employee EJB is an Entity Enterprise Bean with Bean Managed Persistence. It provides accessor and mutator methods for each column in the Employee table. It also must provide accessor and mutator methods for the Department and City relationships that correspond to the keys provided by EMPLOYEE.CITY_ID and EMPLOYEE.DEPT_ID attributes.

Only one create method is defined. It requires an id for use with the employee being created, along with the first name, last name, and the extension for the employee. The SQL for this operation is

insert into EMPLOYEE (EMP_ID, FIRSTNAME, LASTNAME, EXTENSION, CITY_ID, DEPT_ID)
     values (XXX, 'XXXXXXXXXXXXX', 'XXXXXXXXXX', 'XXXX', XXX, XXX)

The SQL for removing an employee with a given employee id is

delete from EMPLOYEE where EMP_ID = XXX

For retrieving a row with a given employee id, the SQL is

select FIRSTNAME, LASTNAME, EXTENSION, CITY_ID, DEPT_ID from EMPLOYEE where EMP_ID = XXX

The findAll method must return a Collection of primary keys for the records in the table. The Home interface will convert these primary keys into a Collection of Employee interfaces for us; it is only necessary to fetch the primary keys from the EMPLOYEE table. The SQL to do this is

select EMP_ID from EMPLOYEE

Similar SQL is used in the load and store methods, as is appropriate.

Getting the City and Department objects is as easy as getting a handle on the Home interface for the respective object. Secondly, the findByPrimaryKey method is invoked to obtain a reference to a Remote interface that corresponds with the record found in the database whose primary key was passed to findByPrimaryKey. The accessor methods can then be invoked on the Remote interface to get information about the associated object.

For example, to find the extension for the secretary of the department for an employee, first find the department to which the employee is a member. Next, find the employee whose id is the same as the id of the secretary listed in the department record. Invoking getExtension on that object reveals the extension. Following is a snippet of code that does these things.

   // Create a string in which to store the extension for the secretary
   String extensionForSecretary = null;

   // Setup the properties for out context
   Properties env = new Properties();
   env.setProperty("...");

   try {
     // Get a context
     InitialContext jndiContext = new InitialContext(env);

     // Do a JNDI lookup for Department
     Object ref = jndiContext.lookup("Department");

     // Get the Home interface for Department
     DepartmentHome home =
       (DepartmentHome)PortableRemoteObject.narrow(ref, DepartmentHome.class);

     // Use the getDepartmentid from the current Employee to get a Remote
     // interface to the appropriate Department
     Department department = home.findByPrimaryKey(getDepartmentid());

     // Get the id for the secretary for the department
     Integer secretaryId = department.getSecretaryId();

     // Get a new context
     InitialContext jndiContext2 = new InitialContext(env);

     // Do a JNDI lookup for Employee
     Object ref2 = jndiContext2.lookup("Employee");

     // Get the Home interface for Employee
     EmployeeHome home2 =
       (EmployeeHome)PortableRemoteObject.narrow(ref2, EmployeeHome.class);

     // Get a remote interface to the appropriate Employee
     Employee secretary = home2.findByPrimaryKey(secretaryId);

     // Access the extension for the secretary
     extensionForSecretary = secretary.getExtension();

   } catch (Exception e) {

     System.out.println("Encountered an error while getting secretary's extenion.");

   }

The makeConnection method creates a connection to the database by looking up the DataSource associated with the JNDI name java:OpenBasePool, which is the name defined for the connection pool. If the DataSource lookup is successful, a connection is obtained from it.

The appropriate hostname or IP address should be substituted for localhost where appropriate, if the EJBs will be running on a different machine than the JNDI service.

Here are the sources to the Remote and Home interfaces, and the Bean class.

code/Chapter7/Employee/EmployeeEJB/com/masslight/Employee/Employee.java
package com.masslight.Employee;

import com.masslight.City.CityHome;
import com.masslight.City.City;

import com.masslight.Department.DepartmentHome;
import com.masslight.Department.Department;

import javax.ejb.EJBObject;
import java.rmi.RemoteException;

public interface Employee extends EJBObject {

 public Integer getEmployeeid() throws RemoteException;
 public void setEmployeeid(Integer value) throws RemoteException;
 public String getLastname() throws RemoteException;
 public void setLastname(String value) throws RemoteException;
 public String getFirstname() throws RemoteException;
 public void setFirstname(String value) throws RemoteException;
 public String getExtension() throws RemoteException;
 public void setExtension(String value) throws RemoteException;
 public Integer getDepartmentid() throws RemoteException;
 public void setDepartmentid(Integer value) throws RemoteException;
 public Integer getCityid() throws RemoteException;
 public void setCityid(Integer value) throws RemoteException;
 public City getCity() throws RemoteException;
 public void setCity(City value) throws RemoteException;
 public Department getDepartment() throws RemoteException;
 public void setDepartment(Department value) throws RemoteException;

}

code/Chapter7/Employee/EmployeeEJB/com/masslight/Employee/EmployeeHome.java
package com.masslight.Employee;

import java.util.Collection;
import java.rmi.RemoteException;
import javax.ejb.*;

public interface EmployeeHome extends EJBHome {

 public Employee create(Integer employeeid, 
			String firstname,
			String lastname, 
			String extension, 
			Integer cityid, 
			Integer departmentid) 
     throws RemoteException, CreateException;
 public Employee findByPrimaryKey(Integer employeeid) 
     throws FinderException, RemoteException;
 public Collection findAll() 
     throws FinderException, RemoteException;

}

code/Chapter7/Employee/EmployeeEJB/com/masslight/Employee/EmployeeEJB.java
package com.masslight.Employee;

import com.masslight.City.CityHome;
import com.masslight.City.City;

import com.masslight.Department.DepartmentHome;
import com.masslight.Department.Department;

import java.sql.*;
import java.util.Enumeration;
import java.util.Vector;
import java.util.Collection;
import java.util.Iterator;
import javax.ejb.*;

import java.util.Properties;
import javax.rmi.PortableRemoteObject;
import javax.naming.*;

import java.rmi.RemoteException;

import javax.sql.*;

public class EmployeeEJB implements EntityBean {

 private EntityContext context = null;

 private Connection connection = null;

 private Integer employeeid = new Integer(0);
 private String firstname = new String();
 private String lastname = new String();
 private String extension = new String();
 private Integer cityid;
 private Integer departmentid;

 /////////////////////////////////////////////////////////////////////////////

 public void makeConnection() {
   try {
     System.setProperty("java.naming.factory.initial", 
			"org.jnp.interfaces.NamingContextFactory");
     System.setProperty("java.naming.provider.url", "localhost:1099");

     InitialContext ic = new InitialContext();
     if(ic == null) throw new Exception("initial context is null");
     DataSource ds = (DataSource) ic.lookup("java:OpenBasePool");
     if(ds != null) {
       connection = ds.getConnection();
     } else {
       throw new Exception("datasource is null");
     }
   } catch(javax.naming.NamingException exc) {
     System.out.println("naming exception: "+exc.getMessage());
   } catch(java.sql.SQLException ex) {
     System.out.println("sql exception: "+ex.getMessage());
   } catch(Exception except) {
     System.out.println(except.getMessage());
   }
 }

 /////////////////////////////////////////////////////////////////////////////

 public void closeConnection() {
   try {
     connection.close();
   } catch (SQLException e) {
     System.out.println("An SQL Exception occurred while closing the connection");
   }
 }

 /////////////////////////////////////////////////////////////////////////////

 public Integer ejbCreate(Integer employeeid, 
			  String firstname, 
			  String lastname, 
			  String extension, 
			  Integer cityid, 
			  Integer departmentid) throws CreateException {
   try {
     insertRow(employeeid, firstname, lastname, extension, cityid, departmentid);
   } catch (Exception ex) {
     throw new EJBException("ejbCreate: " + ex.getMessage());
   }
   setEmployeeid(employeeid);
   setFirstname(firstname);
   setLastname(lastname);
   setExtension(extension);
   setCityid(cityid);
   setDepartmentid(departmentid);
   return employeeid;
 }

 public void ejbPostCreate(Integer employeeid, 
			   String firstname, 
			   String lastname, 
			   String extension, 
			   Integer cityid, 
			   Integer departmentid) {
 }

 private void insertRow(Integer employeeid, 
			String firstname, 
			String lastname, 
			String extension, 
			Integer cityid, 
			Integer departmentid) {

   String sqlString = "insert into EMPLOYEE " +
       "(EMPLOYEE_ID, FIRSTNAME, LASTNAME, EXTENSION, CITY_ID, DEPARTMENT_ID) values (";
   sqlString += employeeid;
   sqlString += ", '" + firstname;
   sqlString += "', '" + lastname;
   sqlString += "', '" + extension;
   sqlString += "', " + cityid;
   sqlString += ", " + departmentid;
   sqlString += ")";

   try {
     connection.setAutoCommit(false);
     Statement s = connection.createStatement();
     s.executeUpdate(sqlString);
     connection.commit();
     s.close();
   } catch (SQLException e) {
     try {
       connection.rollback();
     } catch (SQLException e2) {
       System.out.println("Big problems, error committing, error rolling back!!!");
     }
     System.out.println("Error inserting Employee into database");
   }

 }

 /////////////////////////////////////////////////////////////////////////////

 public void ejbRemove() {

   try {
     deleteRow(getEmployeeid());
   } catch (Exception ex) {
     throw new EJBException("ejbRemove: " + ex.getMessage());
   }

 }

 private void deleteRow(Integer employeeid) {

     System.out.println("EmployeeEJB.deleteRow: enter, employeeid=" + employeeid);
     try {
	 String sqlString = "delete from EMPLOYEE where EMPLOYEE_ID=?";
	 java.sql.PreparedStatement preparedStatement = connection.prepareStatement(sqlString);
	 preparedStatement.clearParameters();
	 preparedStatement.setObject(1, employeeid, Types.INTEGER);
	 connection.setAutoCommit(false);
	 preparedStatement.executeQuery();
	 connection.commit();
	 preparedStatement.close();
     } catch (SQLException e) {
	 try {
	     connection.rollback();
	 } catch (SQLException e2) {
	     System.out.println("Big problems, error committing, error rolling back!!!");
	 }
	 System.out.println("Error deleting Employee from database");
     }
     System.out.println("EmployeeEJB.deleteRow: exit");
 }

 /////////////////////////////////////////////////////////////////////////////

 public void ejbLoad() {

   setEmployeeid((Integer)(context.getPrimaryKey()));
   try {
     loadRow();
   } catch (Exception ex) {
     throw new EJBException("ejbLoad: " + ex.getMessage());
   }

 }

 private void loadRow() {
     System.out.println("EmployeeEJB.loadRow: enter, employeeid=" + getEmployeeid());
     try {
	 String sqlString = "select FIRSTNAME, LASTNAME, EXTENSION, CITY_ID, DEPARTMENT_ID " +
	     "from EMPLOYEE where EMPLOYEE_ID=?";
	 java.sql.PreparedStatement preparedStatement = connection.prepareStatement(sqlString);
	 preparedStatement.clearParameters();
	 preparedStatement.setObject(1, getEmployeeid(), Types.INTEGER);
	 preparedStatement.executeQuery();
	 ResultSet rs = preparedStatement.getResultSet();
	 if (rs.next()) {
	     setFirstname(rs.getString(1));
	     setLastname(rs.getString(2));
	     setExtension(rs.getString(3));
	     setCityid(new Integer(rs.getInt(4)));
	     setDepartmentid(new Integer(rs.getInt(5)));
	 }
	 rs.close();
	 preparedStatement.close();
     } catch (SQLException e) {
	 System.out.println("Error fetching Employee from database");
     }
     System.out.println("EmployeeEJB.loadRow: exit");
 }

 /////////////////////////////////////////////////////////////////////////////

 public void ejbStore() {

   setEmployeeid((Integer)(context.getPrimaryKey()));

   try {
     storeRow();
   } catch (Exception ex) {
     throw new EJBException("ejbLoad: " + ex.getMessage());
   }

 }

 private void storeRow() {

     System.out.println("EmployeeEJB.storeRow: enter, employeeid=" + getEmployeeid());
     try {
	 String sqlString = "update EMPLOYEE set FIRSTNAME=?, LASTNAME=?, " +
	     "EXTENSION=?, CITY_ID=?, DEPARTMENT_ID=? where EMPLOYEEID=?";
	 java.sql.PreparedStatement preparedStatement = connection.prepareStatement(sqlString);
	 preparedStatement.clearParameters();
	 preparedStatement.setObject(1, getFirstname(), Types.VARCHAR);
	 preparedStatement.setObject(2, getLastname(), Types.VARCHAR);
	 preparedStatement.setObject(3, getExtension(), Types.VARCHAR);
	 preparedStatement.setObject(4, getCityid(), Types.INTEGER);
	 preparedStatement.setObject(5, getDepartmentid(), Types.INTEGER);
	 preparedStatement.setObject(6, getEmployeeid(), Types.INTEGER);
	 connection.setAutoCommit(false);
	 preparedStatement.executeQuery();
	 connection.commit();
	 preparedStatement.close();
     } catch (SQLException e) {
	 try {
	     connection.rollback();
	 } catch (SQLException e2) {
	     System.out.println("Big problems, error committing, error rolling back!!!");
	 }
	 System.out.println("Error updating Employee in database");
     }
     System.out.println("EmployeeEJB.storeRow: exit");
 }

 /////////////////////////////////////////////////////////////////////////////

 public Integer ejbFindByPrimaryKey(Integer employeeid) throws FinderException {

   boolean result;

   try {
     result = selectByPrimaryKey(employeeid);
   } catch (Exception ex) {
     throw new EJBException("ejbFindByPrimaryKey: " + ex.getMessage());
   }

   if (result) {
     System.out.println("leaving ejbFindByPrimaryKey with " + employeeid);
     return employeeid;
   } else {
     throw new ObjectNotFoundException("Row for id " + employeeid + " not found.");
   }

 }

 private boolean selectByPrimaryKey(Integer employeeid) {
     System.out.println("EmployeeEJB.selectByPrimaryKey: enter, employeeid=" + employeeid);
     try {
	 String sqlString = "select FIRSTNAME, LASTNAME, EXTENSION, CITY_ID, DEPARTMENT_ID " +
	     "from EMPLOYEE where EMPLOYEE_ID=?";
	 java.sql.PreparedStatement preparedStatement = connection.prepareStatement(sqlString);
	 preparedStatement.clearParameters();
	 preparedStatement.setObject(1, employeeid, Types.INTEGER);
	 preparedStatement.executeQuery();
	 ResultSet rs = preparedStatement.getResultSet();
	 if (rs.next()) {
	     setFirstname(rs.getString(1));
	     setLastname(rs.getString(2));
	     setExtension(rs.getString(3));
	     setCityid(new Integer(rs.getInt(4)));
	     setDepartmentid(new Integer(rs.getInt(5)));
	 }
	 rs.close();
	 preparedStatement.close();
     } catch (SQLException e) {
	 System.out.println("Error fetching Employee from database");
     }
     System.out.println("EmployeeEJB.selectByPrimaryKey: exit");
     return true;
 }

 /////////////////////////////////////////////////////////////////////////////

 public Collection ejbFindAll() {

   Vector employeeKeys = new Vector();

   String sqlString = "select EMPLOYEE_ID from EMPLOYEE";

   try {
     Statement s = connection.createStatement();
     ResultSet rs = s.executeQuery(sqlString);

     while (rs.next()) {
       employeeKeys.addElement(new Integer(rs.getInt(1)));
     }

   } catch (SQLException e) {

     System.out.println("An SQL Exception occurred while querying result set of employee");

   }

   return employeeKeys;

 }

 /////////////////////////////////////////////////////////////////////////////

 public void setEntityContext(EntityContext context) {
   this.context = context;
   makeConnection();
 }

 public void unsetEntityContext() {
   this.context = null;
   closeConnection();
 }

 /////////////////////////////////////////////////////////////////////////////

 public void ejbActivate() {
 }

 /////////////////////////////////////////////////////////////////////////////

 public void ejbPassivate() {
 }

 /////////////////////////////////////////////////////////////////////////////

 public Integer getEmployeeid() {
   return this.employeeid;
 }

 public String getFirstname() {
   return this.firstname;
 }

 public String getLastname() {
   return this.lastname;
 }

 public String getExtension() {
   return this.extension;
 }

 public Integer getCityid() {
   return this.cityid;
 }

 public Integer getDepartmentid() {
   return this.departmentid;
 }

 public City getCity() {
   Properties env = new Properties();
   env.setProperty("java.naming.factory.initial", 
		   "org.jnp.interfaces.NamingContextFactory");
   env.setProperty("java.naming.provider.url", "localhost:1099");
   env.setProperty("java.naming.factory.url.pkgs", "org.jboss.naming");
   try {
     InitialContext jndiContext = new InitialContext(env);
     Object ref = jndiContext.lookup("City");
     CityHome home = (CityHome)PortableRemoteObject.narrow(ref, CityHome.class);
     City city = home.findByPrimaryKey(getCityid());
     return city;
   } catch (Exception e) {
     System.out.println("Error retrieving city in employee bean");
   }
   return null;
 }

 public Department getDepartment() {
   Properties env = new Properties();
   env.setProperty("java.naming.factory.initial", 
		   "org.jnp.interfaces.NamingContextFactory");
   env.setProperty("java.naming.provider.url", "localhost:1099");
   env.setProperty("java.naming.factory.url.pkgs", "org.jboss.naming");
   try {
     InitialContext jndiContext = new InitialContext(env);
     Object ref = jndiContext.lookup("Department");
     System.out.println(ref);
     DepartmentHome home = (DepartmentHome)PortableRemoteObject.narrow(
			      ref, DepartmentHome.class);
     System.out.println(home);
     Department department = home.findByPrimaryKey(getDepartmentid());
     System.out.println(department);
     return department;
   } catch (Exception e) {
     System.out.println("Error retrieving department in employee bean");
   }
   return null;
 }

 public void setEmployeeid(Integer value) {
   employeeid = value;
 }

 public void setFirstname(String value) {
   firstname = new String(value);
 }

 public void setLastname(String value) {
   lastname = new String(value);
 }

 public void setExtension(String value) {
   extension = new String(value);
 }

 public void setCityid(Integer value) {
   cityid = value;
 }

 public void setDepartmentid(Integer value) {
   departmentid = value;
 }

 public void setCity(City value) throws RemoteException {
   try {
     setCityid(value.getCityid());
   } catch (RemoteException e) {
     System.out.println("Error setting city in employee bean");
   }
 }

 public void setDepartment(Department value) {
   try {
     setDepartmentid(value.getDepartmentid());
   } catch (RemoteException e) {
     System.out.println("Error setting department in department bean");
   }
 }

}


City EJB

The City EJB is an Entity Enterprise Bean with Bean Managed Persistence. It provides accessor and mutator methods for each column in the City table.

The City EJB works just as the Employee EJB does. If a question arises, ask the instructor.

Here are the sources to the City EJB.

code/Chapter7/Employee/EmployeeEJB/com/masslight/City/City.java
package com.masslight.City;

import javax.ejb.EJBObject;
import java.rmi.RemoteException;

public interface City extends EJBObject {

 public Integer getCityid() throws RemoteException;
 public String getName() throws RemoteException;
 public void setCityid(Integer value) throws RemoteException;
 public void setName(String value) throws RemoteException;

}

code/Chapter7/Employee/EmployeeEJB/com/masslight/City/CityHome.java
package com.masslight.City;

import java.util.Collection;
import java.rmi.RemoteException;
import javax.ejb.*;

public interface CityHome extends EJBHome {

 public City create(Integer cityid, String name) throws RemoteException, CreateException;
 public City findByPrimaryKey(Integer cityid) throws FinderException, RemoteException;
 public Collection findAll() throws FinderException, RemoteException;

}

code/Chapter7/Employee/EmployeeEJB/com/masslight/City/CityEJB.java
package com.masslight.City;

import java.sql.*;
import java.util.Enumeration;
import java.util.Vector;
import java.util.Collection;
import java.util.Iterator;
import javax.ejb.*;

import javax.sql.*;
import javax.naming.*;

public class CityEJB implements EntityBean {

 private EntityContext context = null;

 private Connection connection = null;

 private Integer cityid = new Integer(0);
 private String name = new String();

 /////////////////////////////////////////////////////////////////////////////

 public void makeConnection() {
   try {
     System.setProperty("java.naming.factory.initial", 
			"org.jnp.interfaces.NamingContextFactory");
     System.setProperty("java.naming.provider.url", "localhost:1099");

     InitialContext ic = new InitialContext();
     if(ic == null) throw new Exception("initial context is null");
     DataSource ds = (DataSource) ic.lookup("java:OpenBasePool");
     if(ds != null) {
       connection = ds.getConnection();
     } else {
       throw new Exception("datasource is null");
     }
   } catch(javax.naming.NamingException exc) {
     System.out.println("naming exception: "+exc.getMessage());
   } catch(java.sql.SQLException ex) {
     System.out.println("sql exception: "+ex.getMessage());
   } catch(Exception except) {
     System.out.println(except.getMessage());
   }
 }

 /////////////////////////////////////////////////////////////////////////////

 public void closeConnection() {
   try {
     connection.close();
   } catch (SQLException e) {
     System.out.println("An SQL Exception occurred while closing the connection");
   }
 }

 /////////////////////////////////////////////////////////////////////////////

 public Integer ejbCreate(Integer cityid, String name) throws CreateException {
   try {
     insertRow(cityid, name);
   } catch (Exception ex) {
     throw new EJBException("ejbCreate: " + ex.getMessage());
   }
   setCityid(cityid);
   setName(name);
   return cityid;
 }

 public void ejbPostCreate(Integer cityid, String name) {
 }

 private void insertRow(Integer cityid, String name) {

   String sqlString = "insert into CITY (CITY_ID, NAME) values (";
   sqlString += cityid;
   sqlString += ", '" + name;
   sqlString += "')";

   try {
     connection.setAutoCommit(false);
     Statement s = connection.createStatement();
     s.executeUpdate(sqlString);
     connection.commit();
     s.close();
   } catch (SQLException e) {
     try {
       connection.rollback();
     } catch (SQLException e2) {
       System.out.println("Big problems, error committing, error rolling back!!!");
     }
     System.out.println("Error inserting City into database");
   }

 }

 /////////////////////////////////////////////////////////////////////////////

 public void ejbRemove() {

   try {
     deleteRow(getCityid());
   } catch (Exception ex) {
     throw new EJBException("ejbRemove: " + ex.getMessage());
   }

 }

 private void deleteRow(Integer cityid) {

   String sqlString = "delete from CITY where CITY_ID = ";
   sqlString += cityid;

   try {
     connection.setAutoCommit(false);
     Statement s = connection.createStatement();
     s.executeUpdate(sqlString);
     connection.commit();
     s.close();
   } catch (SQLException e) {
     try {
       connection.rollback();
     } catch (SQLException e2) {
       System.out.println("Big problems, error committing, error rolling back!!!");
     }
     System.out.println("Error deleting City from database");
   }

 }

 /////////////////////////////////////////////////////////////////////////////

 public void ejbLoad() {
   setCityid((Integer)(context.getPrimaryKey()));
   try {
     loadRow();
   } catch (Exception ex) {
     throw new EJBException("ejbLoad: " + ex.getMessage());
   }
 }

 private void loadRow() {
   try {
     String sqlString = "select NAME from CITY where CITY_ID=";
     sqlString += getCityid();
     Statement s = connection.createStatement();
     s.executeQuery(sqlString);
     ResultSet rs = s.getResultSet();
     if (rs.next()) {
       setName(rs.getString(1));
     }
     s.close();
   } catch (SQLException e) {
     System.out.println("Error fetching City from database");
   }
 }

 /////////////////////////////////////////////////////////////////////////////

 public void ejbStore() {

   setCityid((Integer)(context.getPrimaryKey()));

   try {
     storeRow();
   } catch (Exception ex) {
     throw new EJBException("ejbLoad: " + ex.getMessage());
   }

 }

 private void storeRow() {

   String sqlString = "update CITY set NAME = '";
   sqlString += getName();
   sqlString += "'";
   sqlString += " where CITY_ID = ";
   sqlString += getCityid();

   try {
     connection.setAutoCommit(false);
     Statement s = connection.createStatement();
     s.executeUpdate(sqlString);
     connection.commit();
     s.close();
   } catch (SQLException e) {
     try {
       connection.rollback();
     } catch (SQLException e2) {
       System.out.println("Big problems, error committing, error rolling back!!!");
     }
     System.out.println("Error updating City in database");
   }

 }

 /////////////////////////////////////////////////////////////////////////////

 public Integer ejbFindByPrimaryKey(Integer cityid) throws FinderException {

   boolean result;

   try {
     result = selectByPrimaryKey(cityid);
   } catch (Exception ex) {
     throw new EJBException("ejbFindByPrimaryKey: " + ex.getMessage());
   }

   if (result) {
     System.out.println("leaving ejbFindByPrimaryKey with " + cityid);
     return cityid;
   } else {
     throw new ObjectNotFoundException("Row for id " + cityid + " not found.");
   }

 }

 private boolean selectByPrimaryKey(Integer cityid) {

   try {
     String sqlString = "select NAME from CITY where CITY_ID=";
     sqlString += cityid;
     Statement s = connection.createStatement();
     s.executeQuery(sqlString);
     ResultSet rs = s.getResultSet();
     if (rs.next()) {
       setName(rs.getString(1));
     }
     s.close();
   } catch (SQLException e) {
     System.out.println("Error fetching City from database");
   }

   return true;

 }

 /////////////////////////////////////////////////////////////////////////////

 public Collection ejbFindAll() {

   Vector cityKeys = new Vector();

   String sqlString = "select CITY_ID from CITY";

   try {
     Statement s = connection.createStatement();
     ResultSet rs = s.executeQuery(sqlString);

     while (rs.next()) {
       cityKeys.addElement(new Integer(rs.getInt(1)));
     }

   } catch (SQLException e) {

     System.out.println("An SQL Exception occurred while querying result set of city");

   }

   return cityKeys;

 }

 /////////////////////////////////////////////////////////////////////////////

 public void setEntityContext(EntityContext context) {
   this.context = context;
   makeConnection();
 }

 public void unsetEntityContext() {
   this.context = null;
   closeConnection();
 }

 /////////////////////////////////////////////////////////////////////////////

 public void ejbActivate() {
 }

 /////////////////////////////////////////////////////////////////////////////

 public void ejbPassivate() {
 }

 /////////////////////////////////////////////////////////////////////////////

 public Integer getCityid() {
   return this.cityid;
 }

 public String getName() {
   return this.name;
 }

 public void setCityid(Integer value) {
   cityid = value;
 }

 public void setName(String value) {
   name = new String(value);
 }

}


Department EJB

The Department EJB is an Entity Enterprise Bean with Bean Managed Persistence. It provides accessor and mutator methods for each column in the Department table. Although a foreign key exists in the database to associate an Employee as the secretary for a Department, it is not implemented. Only one create method is defined. It requires an id for use with the department being created, along with the name of the department, and the phone number. As before, the SQL is not discussed here. Again, ask the instructor any questions.

Here are the sources for the Department EJB.

code/Chapter7/Employee/EmployeeEJB/com/masslight/Department/Department.java
package com.masslight.Department;

import javax.ejb.EJBObject;
import java.rmi.RemoteException;

public interface Department extends EJBObject {

 public Integer getDepartmentid() throws RemoteException;
 public String getName() throws RemoteException;
 public String getPhone() throws RemoteException;
 public void setDepartmentid(Integer value) throws RemoteException;
 public void setName(String value) throws RemoteException;
 public void setPhone(String value) throws RemoteException;

}

code/Chapter7/Employee/EmployeeEJB/com/masslight/Department/DepartmentHome.java
package com.masslight.Department;

import java.util.Collection;
import java.rmi.RemoteException;
import javax.ejb.*;

public interface DepartmentHome extends EJBHome {

 public Department create(Integer departmentid, 
			  String name, 
			  String phone) 
     throws RemoteException, CreateException;
 public Department findByPrimaryKey(Integer departmentid) 
     throws FinderException, RemoteException;
 public Collection findAll() 
     throws FinderException, RemoteException;

}

code/Chapter7/Employee/EmployeeEJB/com/masslight/Department/DepartmentEJB.java
package com.masslight.Department;

import java.sql.*;
import java.util.Enumeration;
import java.util.Vector;
import java.util.Collection;
import java.util.Iterator;
import javax.ejb.*;

import javax.sql.*;
import javax.naming.*;

public class DepartmentEJB implements EntityBean {

 private EntityContext context = null;

 private Connection connection = null;

 private Integer departmentid = new Integer(0);
 private String name = new String();
 private String phone = new String();

 /////////////////////////////////////////////////////////////////////////////

 public void makeConnection() {
   try {
     System.setProperty("java.naming.factory.initial", 
			"org.jnp.interfaces.NamingContextFactory");
     System.setProperty("java.naming.provider.url", "localhost:1099");

     InitialContext ic = new InitialContext();
     if(ic == null) throw new Exception("initial context is null");
     DataSource ds = (DataSource) ic.lookup("java:OpenBasePool");
     if(ds != null) {
       connection = ds.getConnection();
     } else {
       throw new Exception("datasource is null");
     }
   } catch(javax.naming.NamingException exc) {
     System.out.println("naming exception: "+exc.getMessage());
   } catch(java.sql.SQLException ex) {
     System.out.println("sql exception: "+ex.getMessage());
   } catch(Exception except) {
     System.out.println(except.getMessage());
   }
 }

 /////////////////////////////////////////////////////////////////////////////

 public void closeConnection() {
   try {
     connection.close();
   } catch (SQLException e) {
     System.out.println("An SQL Exception occurred while closing the connection");
   }
 }

 /////////////////////////////////////////////////////////////////////////////

 public Integer ejbCreate(Integer departmentid, 
			  String name, 
			  String phone) throws CreateException {
   try {
     insertRow(departmentid, name, phone);
   } catch (Exception ex) {
     throw new EJBException("ejbCreate: " + ex.getMessage());
   }
   setDepartmentid(departmentid);
   setName(name);
   setPhone(phone);
   return departmentid;
 }

 public void ejbPostCreate(Integer departmentid, String name, String phone) {
 }

 private void insertRow(Integer departmentid, String name, String phone) {

   String sqlString = "insert into DEPARTMENT (DEPARTMENT_ID, NAME, PHONE) values (";
   sqlString += departmentid;
   sqlString += ", '" + name;
   sqlString += "', '" + phone;
   sqlString += "')";

   try {
     connection.setAutoCommit(false);
     Statement s = connection.createStatement();
     s.executeUpdate(sqlString);
     connection.commit();
     s.close();
   } catch (SQLException e) {
     try {
       connection.rollback();
     } catch (SQLException e2) {
       System.out.println("Big problems, error committing, error rolling back!!!");
     }
     System.out.println("Error inserting Department into database");
   }

 }

 /////////////////////////////////////////////////////////////////////////////

 public void ejbRemove() {

   try {
     deleteRow(getDepartmentid());
   } catch (Exception ex) {
     throw new EJBException("ejbRemove: " + ex.getMessage());
   }

 }

 private void deleteRow(Integer departmentid) {

   String sqlString = "delete from DEPARTMENT where DEPARTMENT_ID = ";
   sqlString += departmentid;

   System.out.println("using sql: " + sqlString);

   try {
     connection.setAutoCommit(false);
     Statement s = connection.createStatement();
     s.executeUpdate(sqlString);
     connection.commit();
     s.close();
   } catch (SQLException e) {
     try {
       connection.rollback();
     } catch (SQLException e2) {
       System.out.println("Big problems, error committing, error rolling back!!!");
     }
     System.out.println("Error deleting Department from database");
   }

 }

 /////////////////////////////////////////////////////////////////////////////

 public void ejbLoad() {
   setDepartmentid((Integer)(context.getPrimaryKey()));
   try {
     loadRow();
   } catch (Exception ex) {
     throw new EJBException("ejbLoad: " + ex.getMessage());
   }
 }

 private void loadRow() {
   try {
     String sqlString = "select NAME, PHONE from DEPARTMENT where DEPARTMENT_ID=";
     sqlString += getDepartmentid();
     Statement s = connection.createStatement();
     s.executeQuery(sqlString);
     ResultSet rs = s.getResultSet();
     if (rs.next()) {
       setName(rs.getString(1));
       setPhone(rs.getString(2));
     }
     s.close();
   } catch (SQLException e) {
     System.out.println("Error fetching Department from database");
   }
 }

 /////////////////////////////////////////////////////////////////////////////

 public void ejbStore() {

   setDepartmentid((Integer)(context.getPrimaryKey()));

   try {
     storeRow();
   } catch (Exception ex) {
     throw new EJBException("ejbLoad: " + ex.getMessage());
   }

 }

 private void storeRow() {

   String sqlString = "update DEPARTMENT set NAME = '";
   sqlString += getName();
   sqlString += "', PHONE='";
   sqlString += getPhone();
   sqlString += "' where DEPARTMENT_ID = ";
   sqlString += getDepartmentid();

   try {
     connection.setAutoCommit(false);
     Statement s = connection.createStatement();
     s.executeUpdate(sqlString);
     connection.commit();
     s.close();
   } catch (SQLException e) {
     try {
       connection.rollback();
     } catch (SQLException e2) {
       System.out.println("Big problems, error committing, error rolling back!!!");
     }
     System.out.println("Error updating Department in database");
   }

 }

 /////////////////////////////////////////////////////////////////////////////

 public Integer ejbFindByPrimaryKey(Integer departmentid) throws FinderException {

   boolean result;

   try {
     result = selectByPrimaryKey(departmentid);
   } catch (Exception ex) {
     throw new EJBException("ejbFindByPrimaryKey: " + ex.getMessage());
   }

   if (result) {
     System.out.println("leaving ejbFindByPrimaryKey with " + departmentid);
     return departmentid;
   } else {
     throw new ObjectNotFoundException("Row for id " + departmentid + " not found.");
   }

 }

 private boolean selectByPrimaryKey(Integer departmentid) {

   try {
     String sqlString = "select NAME, PHONE from DEPARTMENT where DEPARTMENT_ID=";
     sqlString += departmentid;
     Statement s = connection.createStatement();
     s.executeQuery(sqlString);
     ResultSet rs = s.getResultSet();
     if (rs.next()) {
       setName(rs.getString(1));
       setPhone(rs.getString(2));
     }
     s.close();
   } catch (SQLException e) {
     System.out.println("Error fetching Department from database");
   }

   return true;

 }

 /////////////////////////////////////////////////////////////////////////////

 public Collection ejbFindAll() {

   Vector departmentKeys = new Vector();

   String sqlString = "select DEPARTMENT_ID from DEPARTMENT";

   try {
     Statement s = connection.createStatement();
     ResultSet rs = s.executeQuery(sqlString);

     while (rs.next()) {
       departmentKeys.addElement(new Integer(rs.getInt(1)));
     }

   } catch (SQLException e) {

     System.out.println("An SQL Exception occurred while querying result set of department");

   }

   return departmentKeys;

 }

 /////////////////////////////////////////////////////////////////////////////

 public void setEntityContext(EntityContext context) {
   this.context = context;
   makeConnection();
 }

 public void unsetEntityContext() {
   this.context = null;
   closeConnection();
 }

 /////////////////////////////////////////////////////////////////////////////

 public void ejbActivate() {
 }

 /////////////////////////////////////////////////////////////////////////////

 public void ejbPassivate() {
 }

 /////////////////////////////////////////////////////////////////////////////

 public Integer getDepartmentid() {
   return this.departmentid;
 }

 public String getName() {
   return this.name;
 }

 public String getPhone() {
   return this.phone;
 }

 public void setDepartmentid(Integer value) {
   departmentid = value;
 }

 public void setName(String value) {
   name = new String(value);
 }

 public void setPhone(String value) {
   phone = new String(value);
 }

}


Designing the user interface

Shown here is the big picture for the user interface.


JSPs

The JSPs for the application are shown below.

code/Chapter7/Employee/EmployeeClient/index.jsp
<%@ page language="java" %>
<%@ taglib uri="/WEB-INF/struts-bean.tld" prefix="bean" %>
<%@ taglib uri="/WEB-INF/struts-form.tld" prefix="form" %>
<%@ taglib uri="/WEB-INF/struts-html.tld" prefix="html" %>
<%@ taglib uri="/WEB-INF/struts-logic.tld" prefix="logic" %>

<html:html locale="true">
 <head>
 <title>
  My Co - Main Menu
 </title>
 <html:base/>
 </head>
 <body bgcolor="white">
 <h3>
  My Co - Main Menu
 </h3>
 <html:errors/>
 <hr/>
 <html:link href="employeeview.do">Employee Directory</html:link>
 <br/>
 <html:link href="employeeaddsetup.do">Add an Employee</html:link>
 <br/>
 <hr/>
 </body>
</html:html>

code/Chapter7/Employee/EmployeeClient/employeeviewsuccess.jsp
<%@ page language="java" %>
<%@ taglib uri="/WEB-INF/struts-bean.tld" prefix="bean" %>
<%@ taglib uri="/WEB-INF/struts-form.tld" prefix="form" %>
<%@ taglib uri="/WEB-INF/struts-html.tld" prefix="html" %>
<%@ taglib uri="/WEB-INF/struts-logic.tld" prefix="logic" %>

<html:html locale="true">
 <head>
 <title>
  My Co - Employee Directory
 </title>
 <html:base/>
 </head>
 <body bgcolor="white">
 <h3>
  My Co - Employee Directory
 </h3>
 <html:errors/>
 <hr/>
  <table border="1">
   <tr>
    <th>
     Employee ID
    </th>
    <th>
     First Name
    </th>
    <th>
     Last Name
    </th>
    <th>
     Extension
    </th>
    <th>
     Department
    </th>
    <th>
     City
    </th>
    <th>
    </th>
    <th>
    </th>
   </tr>
   <logic:present name="employees">
    <logic:iterate id="currentEmployee" name="employees" scope="session">
     <tr>
      <td>
       <bean:write name="currentEmployee" property="employeeid"/>
      </td>
      <td>
       <bean:write name="currentEmployee" property="firstname"/>
      </td>
      <td>
       <bean:write name="currentEmployee" property="lastname"/>
      </td>
      <td>
       <bean:write name="currentEmployee" property="extension"/>
      </td>
      <td>
       <bean:write name="currentEmployee" property="department.name"/>
      </td>
      <td>
       <bean:write name="currentEmployee" property="city.name"/>
      </td>
      <td>
       <a href="employeedelete.do?id=<bean:write 
		name="currentEmployee" property="employeeid"/>">Delete</a>
      </td>
      <td>
       <a href="employeemodifysetup.do?id=<bean:write 
		name="currentEmployee" property="employeeid"/>">Modify</a>
      </td>
     </tr>
    </logic:iterate>
   </logic:present>
  </table>
 <hr/>
 <html:link href="index.jsp">
  Return to My Co - Main Menu
 </html:link>
 </body>
</html:html>

code/Chapter7/Employee/EmployeeClient/employeeviewfailure.jsp
<%@ page language="java" %>
<%@ taglib uri="/WEB-INF/struts-bean.tld" prefix="bean" %>
<%@ taglib uri="/WEB-INF/struts-form.tld" prefix="form" %>
<%@ taglib uri="/WEB-INF/struts-html.tld" prefix="html" %>
<%@ taglib uri="/WEB-INF/struts-logic.tld" prefix="logic" %>

<html:html locale="true">
 <head>
 <title>
  Failure Viewing Employee
 </title>
 <html:base/>
 </head>
 <body bgcolor="white">
 <h3>
  Failure Viewing Employee
 </h3>
 <html:errors/>
 <hr/>
 <hr/>
 <html:link href="index.jsp">
  Return to My Co - Main Menu
 </html:link>
 </body>
</html:html>

code/Chapter7/Employee/EmployeeClient/employeeadd.jsp
<%@ page language="java" %>
<%@ taglib uri="/WEB-INF/struts-bean.tld" prefix="bean" %>
<%@ taglib uri="/WEB-INF/struts-form.tld" prefix="form" %>
<%@ taglib uri="/WEB-INF/struts-html.tld" prefix="html" %>
<%@ taglib uri="/WEB-INF/struts-logic.tld" prefix="logic" %>

<html:html locale="true">
 <head>
 <title>
  Add an employee
 </title>
 <html:base/>
 </head>
 <body bgcolor="white">
 <h3>
  Add an employee
 </h3>
 <html:errors/>
 <hr/>
  <html:form action="/employeeadd">
   <table>
    <tr>
     <td>
      Employee ID
     </td>
     <td>
      <html:text property="employeeid" size="5" maxlength="5"/>
     </td>
    </tr>
    <tr>
     <td>
      First Name
     </td>
     <td>
      <html:text property="firstname" size="20" maxlength="20"/>
     </td>
    </tr>
    <tr>
     <td>
      Last Name
     </td>
     <td>
      <html:text property="lastname" size="20" maxlength="20"/>
     </td>
    </tr>
    <tr>
     <td>
      Extension
     </td>
     <td>
      <html:text property="extension" size="4" maxlength="4"/>
     </td>
    </tr>
    <tr>
     <td>
      City
     </td>
     <td>
      <html:select property="cityid">
       <html:options collection="cities" 
         name="employee" property="cityid" labelProperty="name"/>
      </html:select>
     </td>
    </tr>
    <tr>
     <td>
      Department
     </td>
     <td>
      <html:select property="departmentid">
       <html:options collection="departments" 
         name="employee" property="departmentid" labelProperty="name"/>
      </html:select>
     </td>
    </tr>
   </table>
   <html:submit>
    Add
   </html:submit>
   <html:reset>
    Reset
   </html:reset>
  </html:form>
 <hr/>
 <html:link href="index.jsp">
  Return to My Co - Main Menu
 </html:link>
 </body>
</html:html>

code/Chapter7/Employee/EmployeeClient/employeeaddsuccess.jsp
<%@ page language="java" %>
<%@ taglib uri="/WEB-INF/struts-bean.tld" prefix="bean" %>
<%@ taglib uri="/WEB-INF/struts-form.tld" prefix="form" %>
<%@ taglib uri="/WEB-INF/struts-html.tld" prefix="html" %>
<%@ taglib uri="/WEB-INF/struts-logic.tld" prefix="logic" %>

<html:html locale="true">
 <head>
 <title>
  Employee Added Successfully
 </title>
 <html:base/>
 </head>
 <body bgcolor="white">
 <h3>
  Employee Added Successfully
 </h3>
 <html:errors/>
 <hr/>
 <hr/>
 <html:link href="index.jsp">
  Return to My Co - Main Menu
 </html:link>
 </body>
</html:html>

code/Chapter7/Employee/EmployeeClient/employeeaddfailure.jsp
<%@ page language="java" %>
<%@ taglib uri="/WEB-INF/struts-bean.tld" prefix="bean" %>
<%@ taglib uri="/WEB-INF/struts-form.tld" prefix="form" %>
<%@ taglib uri="/WEB-INF/struts-html.tld" prefix="html" %>
<%@ taglib uri="/WEB-INF/struts-logic.tld" prefix="logic" %>

<html:html locale="true">
 <head>
 <title>
  Failure Adding Employee
 </title>
 <html:base/>
 </head>
 <body bgcolor="white">
 <h3>
  Failure Adding Employee
 </h3>
 <html:errors/>
 <hr/>
 <hr/>
 <html:link href="index.jsp">
  Return to My Co - Main Menu
 </html:link>
 </body>
</html:html>

code/Chapter7/Employee/EmployeeClient/employeedeletesuccess.jsp
<%@ page language="java" %>
<%@ taglib uri="/WEB-INF/struts-bean.tld" prefix="bean" %>
<%@ taglib uri="/WEB-INF/struts-form.tld" prefix="form" %>
<%@ taglib uri="/WEB-INF/struts-html.tld" prefix="html" %>
<%@ taglib uri="/WEB-INF/struts-logic.tld" prefix="logic" %>

<html:html locale="true">
 <head>
 <title>
  Employee Deleted Successfully
 </title>
 <html:base/>
 </head>
 <body bgcolor="white">
 <h3>
  Employee Deleted Successfully
 </h3>
 <html:errors/>
 <hr/>
 <hr/>
 <html:link href="index.jsp">
  Return to My Co - Main Menu
 </html:link>
 </body>
</html:html>

code/Chapter7/Employee/EmployeeClient/employeedeletefailure.jsp
<%@ page language="java" %>
<%@ taglib uri="/WEB-INF/struts-bean.tld" prefix="bean" %>
<%@ taglib uri="/WEB-INF/struts-form.tld" prefix="form" %>
<%@ taglib uri="/WEB-INF/struts-html.tld" prefix="html" %>
<%@ taglib uri="/WEB-INF/struts-logic.tld" prefix="logic" %>

<html:html locale="true">
 <head>
 <title>
  Failure Deleting Employee
 </title>
 <html:base/>
 </head>
 <body bgcolor="white">
 <h3>
  Failure Deleting Employee
 </h3>
 <html:errors/>
 <hr/>
 <hr/>
 <html:link href="index.jsp">
  Return to My Co - Main Menu
 </html:link>
 </body>
</html:html>

code/Chapter7/Employee/EmployeeClient/employeemodify.jsp
<%@ page language="java" %>
<%@ taglib uri="/WEB-INF/struts-bean.tld" prefix="bean" %>
<%@ taglib uri="/WEB-INF/struts-form.tld" prefix="form" %>
<%@ taglib uri="/WEB-INF/struts-html.tld" prefix="html" %>
<%@ taglib uri="/WEB-INF/struts-logic.tld" prefix="logic" %>

<html:html locale="true">
 <head>
 <title>
  Modify employee
 </title>
 <html:base/>
 </head>
 <body bgcolor="white">
 <h3>
  Modify employee
 </h3>
 <html:errors/>
 <hr/>
  <html:form action="/employeemodify">
   <html:hidden name="employee" property="employeeid"/>
   <table>
    <tr>
     <td>
      First Name
     </td>
     <td>
      <html:text name="employee" property="firstname" size="20" maxlength="20"/>
     </td>
    </tr>
    <tr>
     <td>
      Last Name
     </td>
     <td>
      <html:text name="employee" property="lastname" size="20" maxlength="20"/>
     </td>
    </tr>
    <tr>
     <td>
      Extension
     </td>
     <td>
      <html:text name="employee" property="extension" size="4" maxlength="4"/>
     </td>
    </tr>
    <tr>
     <td>
      City
     </td>
     <td>
      <html:select name="employee" property="cityid">
       <html:options collection="cities"
         name="employee" property="cityid" labelProperty="name"/>
      </html:select>
     </td>
    </tr>
    <tr>
     <td>
      Department
     </td>
     <td>
      <html:select name="employee" property="departmentid">
       <html:options collection="departments" 
         name="employee" property="departmentid" labelProperty="name"/>
      </html:select>
     </td>
    </tr>
   </table>
   <html:submit>
    Modify
   </html:submit>
   <html:reset>
    Reset
   </html:reset>
  </html:form>
 <hr/>
 <html:link href="index.jsp">
  Return to My Co - Main Menu
 </html:link>
 </body>
</html:html>

ApplicationResources.properties

Create the ApplicationResources.properties file under the classes directory.

code/Chapter7/Employee/EmployeeClient/WEB-INF/ApplicationResources.properties
employee.employeeidrequired=Employee ID is required<BR>
employee.employeeidalreadyused=Empoyee ID is not available<BR>
employee.lastnamerequired=Last name is required<BR>
employee.firstnamerequired=First name is required<BR>
errors.header=<font color="red"><HR>Validation Error</HR></font><UL>
errors.footer=</UL>

The Action and Form Classes

The actions contain the business logic for the application. Here are the sources for the Action classes and any ActionForm classes that may be associated with an action.

code/Chapter7/Employee/EmployeeClient/WEB-INF/classes/com/masslight/Employee/EmployeeAddAction.java
package com.masslight.Employee;

import com.masslight.City.City;
import com.masslight.City.CityHome;

import com.masslight.Department.Department;
import com.masslight.Department.DepartmentHome;

import java.util.Vector;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.util.Locale;
import java.util.Hashtable;
import javax.servlet.*;
import javax.servlet.http.*;
import org.apache.struts.action.*;
import org.apache.struts.util.*;

import java.util.Properties;
import javax.rmi.PortableRemoteObject;
import javax.naming.*;

public final class EmployeeAddAction extends Action {

 public EmployeeAddAction() {
 }

 public ActionForward perform(ActionMapping mapping,
                              ActionForm form,
                              HttpServletRequest request,
                              HttpServletResponse response)
   throws IOException, ServletException {

   Locale locale = getLocale(request);
   MessageResources messages = getResources();
   HttpSession session = request.getSession();
   EmployeeAddForm employeeAddForm = (EmployeeAddForm)form;

   ActionErrors errors = new ActionErrors();

   // insert logic here

   Properties env = new Properties();
   env.setProperty("java.naming.factory.initial", "org.jnp.interfaces.NamingContextFactory");
   env.setProperty("java.naming.provider.url", "localhost:1099");
   env.setProperty("java.naming.factory.url.pkgs", "org.jboss.naming");

   try {
     InitialContext jndiContext = new InitialContext(env);
     Object ref = jndiContext.lookup("Employee");
     EmployeeHome home = (EmployeeHome)PortableRemoteObject.narrow(ref, EmployeeHome.class);
     Employee employee = home.create(employeeAddForm.getEmployeeid(),
                                     employeeAddForm.getFirstname(),
                                     employeeAddForm.getLastname(),
                                     employeeAddForm.getExtension(),
                                     employeeAddForm.getCityid(),
                                     employeeAddForm.getDepartmentid()
                                    );
   } catch (Exception e) {
     return (mapping.findForward("employeeaddfailure"));
   }

   if (mapping.getAttribute() != null) {

     if ("request".equals(mapping.getScope()))
       request.removeAttribute(mapping.getAttribute());
     else
       session.removeAttribute(mapping.getAttribute());

   }

   return (mapping.findForward("employeeaddsuccess"));

 }

}

code/Chapter7/Employee/EmployeeClient/WEB-INF/classes/com/masslight/Employee/EmployeeAddForm.java
package com.masslight.Employee;

import com.masslight.City.City;
import com.masslight.City.CityHome;

import com.masslight.Department.Department;
import com.masslight.Department.DepartmentHome;

import javax.servlet.http.HttpServletRequest;
import org.apache.struts.action.*;

public class EmployeeAddForm extends ActionForm {

 private Integer employeeid = new Integer(0);
 private String firstname = new String();
 private String lastname = new String();
 private String extension = new String();
 private Integer cityid = new Integer(0);
 private Integer departmentid = new Integer(0);

 public EmployeeAddForm() {
 }

 public void reset(ActionMapping mapping, HttpServletRequest request) {
 }

 public ActionErrors validate(ActionMapping mapping, HttpServletRequest request) {
   ActionErrors errors = new ActionErrors();

   // validate fields here

   /*
   try {
     if (getEmployeeid().intValue() == 0) {
       errors.add("employeeid", new ActionError("employee.employeeidrequired"));
     }

     Employee employee = new Employee();
     employee.setEmployeeid(getEmployeeid());
     if (employee.fetch() != false) {
       errors.add("employeeid", new ActionError("employee.employeeidalreadyused"));
     }
   } catch (Exception e) {
     errors.add("employeeid", new ActionError("employee.employeeidrequired"));
   }

   if (getFirstname() == null || getFirstname().length() < 1) {
     errors.add("firstname", new ActionError("employee.firstnamerequired"));
   }

   if (getLastname() == null || getLastname().length() < 1) {
     errors.add("lastname", new ActionError("employee.lastnamerequired"));
   }
   */

   return errors;
 }

 public Integer getEmployeeid() { return employeeid; }
 public void setEmployeeid(Integer value) { employeeid = value; }
 public String getLastname() { return lastname; }
 public void setLastname(String value) { lastname = new String(value); }
 public String getFirstname() { return firstname; }
 public void setFirstname(String value) { firstname = new String(value); }
 public String getExtension() { return extension; }
 public void setExtension(String value) { extension = new String(value); }
 public Integer getDepartmentid() { return departmentid; }
 public void setDepartmentid(Integer value) { departmentid = value; }
 public Integer getCityid() { return cityid; }
 public void setCityid(Integer value) { cityid = value; }

}

code/Chapter7/Employee/EmployeeClient/WEB-INF/classes/com/masslight/Employee/EmployeeAddSetupAction.java
package com.masslight.Employee;

import com.masslight.City.City;
import com.masslight.City.CityHome;

import com.masslight.Department.Department;
import com.masslight.Department.DepartmentHome;

import java.util.Vector;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.util.Locale;
import java.util.Hashtable;
import java.util.Collection;
import java.util.Properties;
import javax.servlet.*;
import javax.servlet.http.*;
import org.apache.struts.action.*;
import org.apache.struts.util.*;
import javax.rmi.PortableRemoteObject;
import javax.naming.*;

public final class EmployeeAddSetupAction extends Action {

 public EmployeeAddSetupAction() {
 }

 public ActionForward perform(ActionMapping mapping,
                              ActionForm form,
                              HttpServletRequest request,
                              HttpServletResponse response)
   throws IOException, ServletException {

   Locale locale = getLocale(request);
   MessageResources messages = getResources();
   HttpSession session = request.getSession();

   ActionErrors errors = new ActionErrors();

   // insert logic here

   Properties env = new Properties();
   env.setProperty("java.naming.factory.initial", 
		   "org.jnp.interfaces.NamingContextFactory");
   env.setProperty("java.naming.provider.url", "localhost:1099");
   env.setProperty("java.naming.factory.url.pkgs", "org.jboss.naming");

   try {
     InitialContext jndiContext = new InitialContext(env);
     Object ref = jndiContext.lookup("City");
     CityHome home = (CityHome)PortableRemoteObject.narrow(ref, CityHome.class);
     Collection cities = home.findAll();
     session.setAttribute("cities", cities);
   } catch (Exception e1) {
     return (mapping.findForward("employeeaddsetupfailure"));
   }

   try {
     InitialContext jndiContext = new InitialContext(env);
     Object ref = jndiContext.lookup("Department");
     DepartmentHome home = (DepartmentHome)PortableRemoteObject.narrow(
			       ref, DepartmentHome.class);
     Collection departments = home.findAll();
     session.setAttribute("departments", departments);
   } catch (Exception e2) {
     return (mapping.findForward("employeeaddsetupfailure"));
   }

   if (mapping.getAttribute() != null) {

     if ("request".equals(mapping.getScope()))
       request.removeAttribute(mapping.getAttribute());
     else
       session.removeAttribute(mapping.getAttribute());

   }

   return (mapping.findForward("employeeaddsetupsuccess"));

 }

}

code/Chapter7/Employee/EmployeeClient/WEB-INF/classes/com/masslight/Employee/EmployeeDeleteAction.java
package com.masslight.Employee;

import com.masslight.City.City;
import com.masslight.City.CityHome;

import com.masslight.Department.Department;
import com.masslight.Department.DepartmentHome;

import java.util.Vector;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.util.Locale;
import java.util.Hashtable;
import java.util.Properties;
import javax.servlet.*;
import javax.servlet.http.*;
import org.apache.struts.action.*;
import org.apache.struts.util.*;
import javax.rmi.PortableRemoteObject;
import javax.naming.*;

public final class EmployeeDeleteAction extends Action {

 public EmployeeDeleteAction() {
 }

 public ActionForward perform(ActionMapping mapping,
                              ActionForm form,
                              HttpServletRequest request,
                              HttpServletResponse response)
   throws IOException, ServletException {

   Locale locale = getLocale(request);
   MessageResources messages = getResources();
   HttpSession session = request.getSession();
   EmployeeDeleteForm employeeDeleteForm = (EmployeeDeleteForm)form;

   ActionErrors errors = new ActionErrors();

   // insert logic here
   Properties env = new Properties();
   env.setProperty("java.naming.factory.initial", "org.jnp.interfaces.NamingContextFactory");
   env.setProperty("java.naming.provider.url", "localhost:1099");
   env.setProperty("java.naming.factory.url.pkgs", "org.jboss.naming");

   try {
     InitialContext jndiContext = new InitialContext(env);
     Object ref = jndiContext.lookup("Employee");
     EmployeeHome home = (EmployeeHome)PortableRemoteObject.narrow(ref, EmployeeHome.class);
     Employee employee = home.findByPrimaryKey(employeeDeleteForm.getId());
     employee.remove();
   } catch (Exception e) {
     return (mapping.findForward("employeedeletefailure"));
   }

   if (mapping.getAttribute() != null) {

     if ("request".equals(mapping.getScope()))
       request.removeAttribute(mapping.getAttribute());
     else
       session.removeAttribute(mapping.getAttribute());

   }

   return (mapping.findForward("employeedeletesuccess"));

 }

}

code/Chapter7/Employee/EmployeeClient/WEB-INF/classes/com/masslight/Employee/EmployeeDeleteForm.java
package com.masslight.Employee;

import com.masslight.City.City;
import com.masslight.City.CityHome;

import com.masslight.Department.Department;
import com.masslight.Department.DepartmentHome;

import javax.servlet.http.HttpServletRequest;
import org.apache.struts.action.*;

public class EmployeeDeleteForm extends ActionForm {

 private Integer id;

 public EmployeeDeleteForm() {
 }

 public Integer getId() { return id; }
 public void setId(Integer value) { id = value; }

 public void reset(ActionMapping mapping, HttpServletRequest request) {
 }

 public ActionErrors validate(ActionMapping mapping, HttpServletRequest request) {
   ActionErrors errors = new ActionErrors();

   // validate fields here

   return errors;
 }

}

code/Chapter7/Employee/EmployeeClient/WEB-INF/classes/com/masslight/Employee/EmployeeModifyAction.java
package com.masslight.Employee;

import com.masslight.City.City;
import com.masslight.City.CityHome;

import com.masslight.Department.Department;
import com.masslight.Department.DepartmentHome;

import java.util.Vector;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.util.Locale;
import java.util.Hashtable;
import javax.servlet.*;
import javax.servlet.http.*;
import org.apache.struts.action.*;
import org.apache.struts.util.*;
import java.util.Properties;
import javax.rmi.PortableRemoteObject;
import javax.naming.*;

public final class EmployeeModifyAction extends Action {

 public EmployeeModifyAction() {
 }

 public ActionForward perform(ActionMapping mapping,
                              ActionForm form,
                              HttpServletRequest request,
                              HttpServletResponse response)
   throws IOException, ServletException {

   Locale locale = getLocale(request);
   MessageResources messages = getResources();
   HttpSession session = request.getSession();
   EmployeeModifyForm employeeModifyForm = (EmployeeModifyForm)form;

   ActionErrors errors = new ActionErrors();

   // insert logic here

   Properties env = new Properties();
   env.setProperty("java.naming.factory.initial", "org.jnp.interfaces.NamingContextFactory");
   env.setProperty("java.naming.provider.url", "localhost:1099");
   env.setProperty("java.naming.factory.url.pkgs", "org.jboss.naming");

   try {
     InitialContext jndiContext = new InitialContext(env);
     Object ref = jndiContext.lookup("Employee");
     EmployeeHome home = (EmployeeHome)PortableRemoteObject.narrow(ref, EmployeeHome.class);
     Employee employee = home.findByPrimaryKey(employeeModifyForm.getEmployeeid());
     employee.setFirstname(employeeModifyForm.getFirstname());
     employee.setLastname(employeeModifyForm.getLastname());
     employee.setExtension(employeeModifyForm.getExtension());
     employee.setCityid(employeeModifyForm.getCityid());
     employee.setDepartmentid(employeeModifyForm.getDepartmentid());
   } catch (Exception e) {
     return (mapping.findForward("employeemodifyfailure"));
   }

   if (mapping.getAttribute() != null) {

     if ("request".equals(mapping.getScope()))
       request.removeAttribute(mapping.getAttribute());
     else
       session.removeAttribute(mapping.getAttribute());

   }

   return (mapping.findForward("employeemodifysuccess"));

 }

}

code/Chapter7/Employee/EmployeeClient/WEB-INF/classes/com/masslight/Employee/EmployeeModifyForm.java
package com.masslight.Employee;

import com.masslight.City.City;
import com.masslight.City.CityHome;

import com.masslight.Department.Department;
import com.masslight.Department.DepartmentHome;

import javax.servlet.http.HttpServletRequest;
import org.apache.struts.action.*;

public class EmployeeModifyForm extends ActionForm {

 private Integer employeeid = new Integer(0);
 private String firstname = new String();
 private String lastname = new String();
 private String extension = new String();
 private Integer cityid = new Integer(0);
 private Integer departmentid = new Integer(0);

 public EmployeeModifyForm() {
 }

 public void reset(ActionMapping mapping, HttpServletRequest request) {
 }

 public ActionErrors validate(ActionMapping mapping, HttpServletRequest request) {
   ActionErrors errors = new ActionErrors();

   /*
   // validate fields here
   try {
     if (getEmployeeid().intValue() == 0) {
       errors.add("employeeid", new ActionError("employee.employeeidrequired"));
     }
   } catch (Exception e) {
     errors.add("employeeid", new ActionError("employee.employeeidrequired"));
   }

   if (getFirstname() == null || getFirstname().length() < 1) {
     errors.add("firstname", new ActionError("employee.firstnamerequired"));
   }

   if (getLastname() == null || getLastname().length() < 1) {
     errors.add("lastname", new ActionError("employee.lastnamerequired"));
   }
   */

   return errors;
 }

 public Integer getEmployeeid() { return employeeid; }
 public void setEmployeeid(Integer value) { employeeid = value; }
 public String getLastname() { return lastname; }
 public void setLastname(String value) { lastname = new String(value); }
 public String getFirstname() { return firstname; }
 public void setFirstname(String value) { firstname = new String(value); }
 public String getExtension() { return extension; }
 public void setExtension(String value) { extension = new String(value); }
 public Integer getDepartmentid() { return departmentid; }
 public void setDepartmentid(Integer value) { departmentid = value; }
 public Integer getCityid() { return cityid; }
 public void setCityid(Integer value) { cityid = value; }

}

code/Chapter7/Employee/EmployeeClient/WEB-INF/classes/com/masslight/Employee/EmployeeModifySetupAction.java
package com.masslight.Employee;

import com.masslight.City.City;
import com.masslight.City.CityHome;

import com.masslight.Department.Department;
import com.masslight.Department.DepartmentHome;

import java.util.Vector;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.util.Locale;
import java.util.Hashtable;
import javax.servlet.*;
import javax.servlet.http.*;
import org.apache.struts.action.*;
import org.apache.struts.util.*;
import java.util.Collection;
import java.util.Properties;
import javax.rmi.PortableRemoteObject;
import javax.naming.*;

public final class EmployeeModifySetupAction extends Action {

 public EmployeeModifySetupAction() {
 }

 public ActionForward perform(ActionMapping mapping,
                              ActionForm form,
                              HttpServletRequest request,
                              HttpServletResponse response)
   throws IOException, ServletException {

   Locale locale = getLocale(request);
   MessageResources messages = getResources();
   HttpSession session = request.getSession();
   EmployeeModifySetupForm employeeModifySetupForm = (EmployeeModifySetupForm)form;

   ActionErrors errors = new ActionErrors();

   // insert logic here

   Properties env = new Properties();
   env.setProperty("java.naming.factory.initial", 
		   "org.jnp.interfaces.NamingContextFactory");
   env.setProperty("java.naming.provider.url", "localhost:1099");
   env.setProperty("java.naming.factory.url.pkgs", "org.jboss.naming");

   try {
     InitialContext jndiContext = new InitialContext(env);
     Object ref = jndiContext.lookup("City");
     CityHome home = (CityHome)PortableRemoteObject.narrow(ref, CityHome.class);
     Collection cities = home.findAll();
     session.setAttribute("cities", cities);
   } catch (Exception e1) {
     return (mapping.findForward("employeemodifysetupfailure"));
   }

   try {
     InitialContext jndiContext = new InitialContext(env);
     Object ref = jndiContext.lookup("Department");
     DepartmentHome home = (DepartmentHome)PortableRemoteObject.narrow(
			        ref, DepartmentHome.class);
     Collection departments = home.findAll();
     session.setAttribute("departments", departments);
   } catch (Exception e2) {
     return (mapping.findForward("employeemodifysetupfailure"));
   }

   try {
     InitialContext jndiContext = new InitialContext(env);
     Object ref = jndiContext.lookup("Employee");
     EmployeeHome home = (EmployeeHome)PortableRemoteObject.narrow(
                              ref, EmployeeHome.class);
     Employee employee = home.findByPrimaryKey(employeeModifySetupForm.getId());
     session.setAttribute("employee", employee);
   } catch (Exception e3) {
     return (mapping.findForward("employeemodifysetupfailure"));
   }

   if (mapping.getAttribute() != null) {

     if ("request".equals(mapping.getScope()))
       request.removeAttribute(mapping.getAttribute());
     else
       session.removeAttribute(mapping.getAttribute());

   }

   return (mapping.findForward("employeemodifysetupsuccess"));

 }

}

code/Chapter7/Employee/EmployeeClient/WEB-INF/classes/com/masslight/Employee/EmployeeModifySetupForm.java
package com.masslight.Employee;

import com.masslight.City.City;
import com.masslight.City.CityHome;

import com.masslight.Department.Department;
import com.masslight.Department.DepartmentHome;

import javax.servlet.http.HttpServletRequest;
import org.apache.struts.action.*;

public class EmployeeModifySetupForm extends ActionForm {

 private Integer id;

 public EmployeeModifySetupForm() {
 }

 public Integer getId() { return id; }
 public void setId(Integer value) { id = value; }

 public void reset(ActionMapping mapping, HttpServletRequest request) {
 }

 public ActionErrors validate(ActionMapping mapping, HttpServletRequest request) {
   ActionErrors errors = new ActionErrors();

   // validate fields here

   return errors;
 }

}

code/Chapter7/Employee/EmployeeClient/WEB-INF/classes/com/masslight/Employee/EmployeeViewAction.java
package com.masslight.Employee;

import com.masslight.City.*;
import com.masslight.Department.*;

import java.util.Vector;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.util.Locale;
import java.util.Hashtable;
import javax.servlet.*;
import javax.servlet.http.*;
import org.apache.struts.action.*;
import org.apache.struts.util.*;
import java.util.Properties;
import javax.rmi.PortableRemoteObject;
import javax.naming.*;

import java.util.Collection;

public final class EmployeeViewAction extends Action {

 public EmployeeViewAction() {
 }

 public ActionForward perform(ActionMapping mapping,
                              ActionForm form,
                              HttpServletRequest request,
                              HttpServletResponse response)
   throws IOException, ServletException {

   Locale locale = getLocale(request);
   MessageResources messages = getResources();
   HttpSession session = request.getSession();

   ActionErrors errors = new ActionErrors();

   // insert logic here

   Properties env = new Properties();
   env.setProperty("java.naming.factory.initial", "org.jnp.interfaces.NamingContextFactory");
   env.setProperty("java.naming.provider.url", "localhost:1099");
   env.setProperty("java.naming.factory.url.pkgs", "org.jboss.naming");

   try {
     InitialContext jndiContext = new InitialContext(env);
     Object ref = jndiContext.lookup("Employee");
     EmployeeHome home = (EmployeeHome)PortableRemoteObject.narrow(ref, EmployeeHome.class);
     Collection employees = home.findAll();
     session.setAttribute("employees", employees);
   } catch (Exception e) {
     return (mapping.findForward("employeeviewfailure"));
   }

   if (mapping.getAttribute() != null) {

     if ("request".equals(mapping.getScope()))
       request.removeAttribute(mapping.getAttribute());
     else
       session.removeAttribute(mapping.getAttribute());

   }

   return (mapping.findForward("employeeviewsuccess"));

 }

}


Configuring the Actions for the Application

As with all applications that use the Struts framework, a struts-config.xml file is needed to provide the appropriate mappings between the actions and forms and for specifying global forwards.

code/Chapter7/Employee/EmployeeClient/WEB-INF/struts-config.xml
<?xml version="1.0" encoding="ISO-8859-1" ?>

<!DOCTYPE struts-config PUBLIC
         "-//Apache Software Foundation//DTD Struts Configuration 1.0//EN"
         "http://jakarta.apache.org/struts/dtds/struts-config_1_0.dtd">

<struts-config>

 <!-- ========== Form Bean Definitions =================================== -->
 <form-beans>
   <form-bean name="employeeModifySetupForm"
     type="com.masslight.Employee.EmployeeModifySetupForm"/>
   <form-bean name="employeeModifyForm" type="com.masslight.Employee.EmployeeModifyForm"/>
   <form-bean name="employeeAddForm" type="com.masslight.Employee.EmployeeAddForm"/>
   <form-bean name="employeeDeleteForm" type="com.masslight.Employee.EmployeeDeleteForm"/>
 </form-beans>

 <!-- ========== Global Forward Definitions ============================== -->
 <global-forwards>
   <forward name="employeeaddsetupsuccess" path="/employeeadd.jsp"/>
   <forward name="employeeaddsuccess" path="/employeeaddsuccess.jsp"/>
   <forward name="employeeaddfailure" path="/employeeaddfailure.jsp"/>
   <forward name="employeeviewsuccess" path="/employeeviewsuccess.jsp"/>
   <forward name="employeeviewfailure" path="/employeeviewfailure.jsp"/>
   <forward name="employeedeletesuccess" path="/employeeview.do"/>
   <forward name="employeedeletefailure" path="/employeedeletefailure.jsp"/>
   <forward name="employeemodifysetupsuccess" path="/employeemodify.jsp"/>
   <forward name="employeemodifysuccess" path="/employeeview.do"/>
   <forward name="employeemodifyfailure" path="/employeemodifyfailure.jsp"/>
   <forward name="cityviewsuccess" path="/cityviewsuccess.jsp"/>
   <forward name="cityviewfailure" path="/cityviewfailure.jsp"/>
 </global-forwards>

 <!-- ========== Action Mapping Definitions ============================== -->
 <action-mappings>
   <action path="/employeeaddsetup" type="com.masslight.Employee.EmployeeAddSetupAction"/>
   <action path="/employeeadd" type="com.masslight.Employee.EmployeeAddAction"
     name="employeeAddForm" scope="request" input="/employeeadd.jsp"/>
   <action path="/employeeview" type="com.masslight.Employee.EmployeeViewAction"/>
   <action path="/employeedelete" type="com.masslight.Employee.EmployeeDeleteAction"
     name="employeeDeleteForm" scope="request" input="employeeviewsuccess.jsp"/>
   <action path="/employeemodifysetup"
     type="com.masslight.Employee.EmployeeModifySetupAction"
     name="employeeModifySetupForm" scope="request" input="/employeeviewsuccess.jsp"/>
   <action path="/employeemodify" type="com.masslight.Employee.EmployeeModifyAction"
     name="employeeModifyForm" scope="request" input="/employeemodify.jsp"/>
   <action path="/cityview" type="com.masslight.City.CityViewAction"/>
 </action-mappings>

</struts-config>


The web.xml Configuration File

The web.xml configuration used for this web application is no more special than the ones used for other web applications, except that it provides support for the Struts framework.

The action servlet mapping specifies that any request ending in .do should be considered an Action servlet. When a request for a URL ending in .do is submitted, the class specified in the struts-config.xml action mappings will be instantiated and methods invoked on it to perform the logic. For example, consider the case when the URL http://.../employeeaddsetup.do is requested. The container knows from struts-config.xml that an instance of com.masslight.Employee.EmployeeAddSetupAction should be instantiated and invokes the appropriate methods.

Also notice that the welcome file is index.jsp.

code/Chapter7/Employee/EmployeeClient/WEB-INF/web.xml
<?xml version="1.0" encoding="ISO-8859-1"?>

<!DOCTYPE web-app
 PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.2//EN"
 "http://java.sun.com/j2ee/dtds/web-app_2_2.dtd">

<web-app>

 <!-- Action Servlet Configuration -->
 <servlet>
 <servlet-name>action</servlet-name>
 <servlet-class>org.apache.struts.action.ActionServlet</servlet-class>
 <init-param>
  <param-name>application</param-name>
  <param-value>ApplicationResources</param-value>
 </init-param>
 <init-param>
  <param-name>config</param-name>
  <param-value>/WEB-INF/struts-config.xml</param-value>
 </init-param>
 <init-param>
  <param-name>debug</param-name>
  <param-value>2</param-value>
 </init-param>
 <init-param>
  <param-name>detail</param-name>
  <param-value>2</param-value>
 </init-param>
 <init-param>
  <param-name>validate</param-name>
  <param-value>true</param-value>
 </init-param>
 <load-on-startup>2</load-on-startup>
 </servlet>

 <!-- Action Servlet Mapping -->
 <servlet-mapping>
 <servlet-name>action</servlet-name>
 <url-pattern>*.do</url-pattern>
 </servlet-mapping>

 <!-- The Welcome File List -->
 <welcome-file-list>
 <welcome-file>index.jsp</welcome-file>
 </welcome-file-list>

 <!-- Application Tag Library Descriptor -->
 <taglib>
 <taglib-uri>/WEB-INF/application.tld</taglib-uri>
 <taglib-location>/WEB-INF/app.tld</taglib-location>
 </taglib>

 <!-- Struts Tag Library Descriptors -->
 <taglib>
 <taglib-uri>/WEB-INF/struts-bean.tld</taglib-uri>
 <taglib-location>/WEB-INF/struts-bean.tld</taglib-location>
 </taglib>

 <taglib>
 <taglib-uri>/WEB-INF/struts-html.tld</taglib-uri>
 <taglib-location>/WEB-INF/struts-html.tld</taglib-location>
 </taglib>

 <taglib>
 <taglib-uri>/WEB-INF/struts-logic.tld</taglib-uri>
 <taglib-location>/WEB-INF/struts-logic.tld</taglib-location>
 </taglib>

</web-app>

Creating the Enterprise Archive (.ear) containing the Enterprise Beans

To make creating deployment descriptors easier for developers, Sun provides an application called Deploy Tool with the J2EE SDK. It is located in the bin directory of the J2EE installation, and the file name is deploytool. Start the Deploy Tool and choose File->New->Application. Name the new application Chapter6ejb.


Make sure that Chapter6ejb is selected and choose File->New->Enterprise Bean. The New Enterprise Bean Wizard will appear. Click the Next button on the Introduction screen. Enter EJBsChapter6 for the JAR Display Name.


The Home and Remote interfaces, and the class for the first EJB need to be added. To do this, select the Add button. Add the City EJB first. In the top portion of the window that appears, navigate to where the Home and Remote interfaces and the EJB implementation from the City EJB are located.


Choose Add and click OK.

Move to the next section in the New Enterprise Bean Wizard. Since City is an entity bean, choose Entity for the Bean Type. Make the appropriate selections in the Enterprise Bean Class, Home Interface, and Remote Interface pop-up menus. Give the Enterprise Bean the name City.


Choose Bean-Managed Persistence and enter java.lang.Integer for the Primary Key Class. Then continue to the next section.


Skip through the next several sections in the wizard, and stop at the Transaction-Management dialog. Choose Container-Managed Transactions.  For the accessor and mutator methods, select Supports for the Transaction Type. For the remove, create, and finder methods, choose Required for the Transaction Type.


In the next dialog, the EJB deployment descriptor will be shown. Choose Finish.


The deployment tool main window shows the City EJB has been added.


Repeat the appropriate steps above to add the Employee and Department Enterprise Beans.

Finally, choose File->Save to save the EJB .ear file. The .ear can now be deployed, making the Enteprise Beans available for use in other applications. Copy the .ear to the deploy directory under the JBoss installation hierarchy.

Compiling and Deploying

This application has three Ant build scripts, one for the JSPs and Actions, one for the EJBs, and one that ties both of them together. Change to the root directory of the Employee project and run ant all.

code/Chapter7/Employee/EmployeeClient/build.xml
<project name="Employee" default="dist" basedir=".">

 <!-- set global properties for this build -->
 <property environment="env"/>
 <property name="top" value="."/>
 <property name="src" value="."/>
 <property name="build" value="build"/>
 <property name="dist" value="dist"/>
 <property name="war_dir" value="${dist}/lib"/>
 <property name="war_file" value="${war_dir}/Employee.war"/>

 <property name="webinf" value="${top}/WEB-INF"/>
 <property name="web.xml" value="${webinf}/web.xml"/>
 <property name="classes" value="${webinf}/classes"/>
 <property name="lib" value="${top}/WEB-INF/lib"/>
 <property name="ejb.src" value="${top}/../EmployeeEJB"/>
 <property name="struts.jar" value="${env.STRUTS_HOME}/lib/struts.jar"/>
 <property name="servlet.jar" value="${env.TOMCAT_HOME}/lib/servlet.jar"/>
 <property name="ejb.jar" value="${env.JBOSS_HOME}/lib/ext/jboss-j2ee.jar"/>
 <property name="jdbc.jar" value="${env.JBOSS_HOME}/lib/jboss-jdbc_ext.jar"/>
 <property name="deploy" value="${env.JBOSS_HOME}/deploy"/>

 <target name="clean">
   <!-- Delete our the ${build} and ${dist} directory trees -->
   <delete dir="${build}"/>
   <delete dir="${dist}"/>
   <delete dir="${war_dir}"/>
 </target>
 <target name="init">
   <!-- Create the build directory structure used by compile and dist -->
   <mkdir dir="${build}"/>
   <mkdir dir="${dist}"/>
   <mkdir dir="${war_dir}"/>
 </target>

 <target name="compile" depends="init">
   <!-- Compile the java code from ${src} into ${build} -->
   <javac
     srcdir="${ejb.src}"
     destdir="${build}"
     classpath="${ejb.jar};${jdbc.jar}"/>
   <javac
     srcdir="${top}/${src}"
     destdir="${build}"
     classpath="${servlet.jar};${struts.jar};${ejb.jar}"/>
 </target>

 <target name="dist" depends="compile">
   <!-- Put everything in a war file -->
   <war warfile="${war_file}" webxml="${web.xml}">
     <!-- include all JSPs in root level, and all .properties files anywhere -->
     <fileset dir="${top}/${src}">
       <include name="*.jsp"/>
       <include name="**/*.properties"/>
     </fileset>

     <!-- include all tag libraries in WEB-INF, and all .xml config files,
          but not web.xml (that's handled separately) -->
     <webinf dir="${webinf}">
       <include name="*.tld"/>
       <include name="*.xml"/>
       <exclude name="web.xml"/>
     </webinf>

     <!-- include all libraries in WEB-INF/lib (like struts.jar) -->
     <lib dir="${lib}"/>

     <!-- include all compiled classes -->
     <classes dir="${build}"/>
   </war>
 </target>

 <target name="deploy">
   <!-- Copy the war file to the JBoss deploy directory -->
   <copy file="${war_file}" todir="${deploy}"/>
 </target>

 <target name="all" depends="clean,dist,deploy"/>

</project>

code/Chapter7/Employee/EmployeeEJB/build.xml
<project name="EmployeeEJB" default="dist" basedir