/*
* This example is from the book "Java Enterprise in a Nutshell".
* Copyright (c) 1999 by O'Reilly & Associates.
* You may distribute this source code for non-commercial purposes only.
* You may study, modify, and use this example for any purpose, as long as
* this notice is retained. Note that this example is provided "as is",
* WITHOUT WARRANTY of any kind either expressed or implied.
*/
package entity.beanManaged;
import javax.ejb.*;
import java.rmi.RemoteException;
import NoSuchPersonException;
import entity.DuplicateProfileException;
import java.util.Properties;
import java.util.Enumeration;
import java.util.Vector;
import java.sql.*;
import java.io.*;
/**
* A ProfileBean, which provides enterprise
* profile information for a named person.
*/
public class ProfileBean implements EntityBean {
//
// Persistent state for this bean
//
public String mName;
// Entries in the profile (name/value pairs)
public Properties mEntries;
// Store context (non-persistent)
private transient EntityContext mContext = null;
// Entity bean methods
/**
* During activation, create our entry lookup table.
*/
public void ejbActivate() {
mEntries = new Properties();
System.out.println("ProfileBean activated.");
}
/**
* Load bean from persistent store. In this case, we're managing the dbase
* storage, so we store our profile entries as independent records in a
* separate "PROFILE_ENTRY" table.
*/
public void ejbLoad() throws RemoteException {
try {
ProfilePK key = (ProfilePK)mContext.getPrimaryKey();
loadFromDB(key);
}
catch (Exception e) {
System.out.println("Failed to load ProfileBean: ");
e.printStackTrace();
throw new RemoteException("ejbLoad failed: ", e);
}
System.out.println("ProfileBean load finished.");
}
protected void loadFromDB(ProfilePK key) throws FinderException {
boolean found = false;
try {
Connection conn = newConnection();
Statement s = conn.createStatement();
s.executeQuery("select name from profile where name = '" + key.mName +
"'");
ResultSet rs = s.getResultSet();
if (rs.next()) {
found = true;
s.executeQuery("select key, value from profile_entry where name = '" +
key.mName + "'");
rs = s.getResultSet();
while (rs.next()) {
String pKey = rs.getString(1);
String pValue = rs.getString(2);
mEntries.put(pKey, pValue);
}
}
}
catch (SQLException e) {
throw new FinderException("Failed to load profile entries from DB: " +
e.toString());
}
if (!found) {
throw new FinderException("No profile found for " + key.mName);
}
}
private Connection newConnection() throws SQLException {
// Make sure that the JDBC driver is loaded
try {
Class.forName("oracle.jdbc.driver.OracleDriver");
}
catch (ClassNotFoundException cnfe) {
System.out.println("Failed to load JDBC drivers.");
}
// Set the connection properties
Properties dbProps = new Properties();
dbProps.put("user", "libra");
dbProps.put("password", "banana");
// dbProps.put("server", "dev1");
// Get the connection from the pool
return DriverManager.getConnection("jdbc:oracle:thin:@tarazed.hbs.edu:1525:dev1", dbProps);
}
/**
* Store bean to persistent store. Properties are stored as records in the
* PROFILE_ENTRY table.
*/
public void ejbStore() throws RemoteException {
ProfilePK key = (ProfilePK)mContext.getPrimaryKey();
try {
Connection conn = newConnection();
// Clear out old profile entries and replace with the current ones
Statement s = conn.createStatement();
s.executeUpdate("delete from profile_entry where name = '" + key.mName +
"'");
Enumeration pKeys = mEntries.propertyNames();
while (pKeys.hasMoreElements()) {
String pKey = (String)pKeys.nextElement();
String pValue = mEntries.getProperty(pKey);
s.executeUpdate("insert into profile_entry (name, key, value) values "
+ "('" + key.mName + "', '" + pKey + "', '"
+ pValue + "')");
}
// Close the statement and the connection, just to be tidy...
s.close();
conn.close();
}
catch (Exception e) {
System.out.println("Failed to store ProfileBean: ");
e.printStackTrace();
throw new RemoteException("ejbStore failed: ", e);
}
System.out.println("ProfileBean store finished.");
}
/**
* Remove this named profile from the database.
*/
public void ejbRemove() {
// Get this profile's name
ProfilePK key = (ProfilePK)mContext.getPrimaryKey();
try {
Connection conn = newConnection();
// Clear out any profile entries
Statement s = conn.createStatement();
s.executeUpdate("delete from profile_entry where name = '" + key.mName +
"'");
// Clear out the profile itself
s.executeUpdate("delete from profile where name = '" + key.mName + "'");
s.close();
conn.close();
System.out.println("ProfileBean removed.");
}
catch (SQLException se) {
System.out.println("Error removing profile for " + key.mName);
se.printStackTrace();
}
}
/**
* When we're passivated, release our entry table.
*/
public void ejbPassivate() {
mEntries = null;
System.out.println("ProfileBean passivated.");
}
/**
* Get context from container.
*/
public void setEntityContext(EntityContext context) {
mContext = context;
System.out.println("ProfileBean context set.");
}
/**
* Container is removing our context.
*/
public void unsetEntityContext() throws RemoteException {
mContext = null;
System.out.println("ProfileBean context unset.");
}
/**
* Since we're managing persistence here in the bean, we need to
* implement the finder methods.
*/
public ProfilePK ejbFindByPrimaryKey(ProfilePK key)
throws FinderException, RemoteException {
loadFromDB(key);
return key;
}
public Enumeration ejbFindByEntryValue(String key, String value)
throws RemoteException, FinderException {
Vector userList = new Vector();
// Get a new connection fro the EJB server
try {
Connection conn = newConnection();
Statement s = conn.createStatement();
// Issue a query for matching profile entries, grabbing just the name
s.executeQuery("select distinct(name) from profile_entry where " +
" key = '" + key + "' and value = '" + value + "'");
// Convert the results in primary keys and return an enumeration
ResultSet results = s.getResultSet();
while (results.next()) {
String name = results.getString(1);
userList.addElement(new ProfilePK(name));
}
}
catch (SQLException se) {
// Failed to do database lookup
throw new FinderException();
}
return userList.elements();
}
/**
* Create method (corresponds to each create() method on the
* home interface, ProfileHome). Nothing to initialize in this case.
*/
public ProfilePK ejbCreate() {
System.out.println("Nameless ProfileBean created.");
return new ProfilePK();
}
/**
* Create method with name of profile owner.
*/
public ProfilePK ejbCreate(String name) throws DuplicateProfileException {
try {
Connection conn = newConnection();
Statement s = conn.createStatement();
s.executeUpdate("insert into profile (name) values ('" + name + "')");
s.close();
conn.close();
}
catch (SQLException se) {
System.out.println("Error creating profile, assuming duplicate.");
try {
StringWriter strw = new StringWriter();
PrintWriter prntw = new PrintWriter(strw);
se.printStackTrace(prntw);
throw new DuplicateProfileException("SQL error creating profile for " +
name + ": " + se.toString() + "\n" +
strw.toString());
}
catch (Exception e) {}
}
System.out.println("ProfileBean created for " + name + ".");
return new ProfilePK(name);
}
/**
* Post-creation notification. Nothing to do here, but we need
* to provide an implementation.
*/
public void ejbPostCreate() {
System.out.println("ProfileBean post-create called.");
}
/**
* Post-creation notification. Nothing to do here, what we need
* to provide an implementation.
*/
public void ejbPostCreate(String name) {
System.out.println("ProfileBean post-create called for " + name + ".");
}
// Finally, the remote methods. Signatures of methods must match those
// on remote interface (Profile), except that throwing
// RemoteException is not necessary.
public String getName() {
ProfilePK key = (ProfilePK)mContext.getPrimaryKey();
return key.mName;
}
public String getEntry(String key) {
return mEntries.getProperty(key);
}
public void setEntry(String key, String value) {
if (mEntries == null) // ejbhome doesn't call ejbActivate reliably...
mEntries = new Properties();
mEntries.put(key, value);
}
}
|