/*******************************************************************************
$Source: /cvs/repositories/openii3/project/java/examples/org/any_openeai_enterprise/gateways/warehouse/EnterpriseWarehouseCommand.java,v $
$Revision: 1.4 $
*******************************************************************************/
/**********************************************************************
This file is part of the OpenEAI sample, reference implementation,
and deployment management suite created by Tod Jackson
(tod@openeai.org) and Steve Wheat (steve@openeai.org) at
the University of Illinois Urbana-Champaign.
Copyright (C) 2002 The OpenEAI Software Foundation
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
For specific licensing details and examples of how this software
can be used to implement integrations for your enterprise, visit
http://www.OpenEai.org/licensing.
*/
package org.any_openeai_enterprise.gateways.warehouse;
import javax.jms.*;
import java.util.*;
import java.io.*;
import org.jdom.Document;
import org.jdom.Element;
import org.jdom.JDOMException;
import org.jdom.output.XMLOutputter;
import org.openeai.dbpool.*;
import org.openeai.xml.*;
import org.openeai.jms.producer.*;
import org.openeai.jms.consumer.*;
import org.openeai.jms.consumer.commands.*;
import org.openeai.layouts.*;
import org.openeai.config.*;
import org.openeai.moa.*;
import org.openeai.moa.objects.resources.*;
import org.openeai.moa.objects.testsuite.*;
import com.any_erp_vendor.moa.jmsobjects.person.v1_0.BasicPerson;
import com.any_erp_vendor.moa.objects.resources.v1_0.Date;
import com.any_erp_vendor.moa.objects.resources.v1_0.Name;
import com.any_erp_vendor.moa.objects.resources.v1_0.Address;
import com.any_erp_vendor.moa.objects.resources.v1_0.Phone;
import java.sql.*;
import java.net.URL;
import java.io.*;
/**
* This command is part of the OpenEAI Getting Started guide. It is an example of
* a gateway that consumes Synchronizaton messages from our ficticious ERP system
* from the ficticious "any-erp-vendor.com" company. That ERP (com.any-erp-vendor.Gateway) is authoritative for the
* following messages:
* <ul>
* <li>com.any-erp-vendor.Person/BasicPerson/1.0
* <li>com.any-erp-vendor.Person/EmergencyContact/1.0
* <li>com.any-erp-vendor.Employee/BasicEmployee/1.0
* </ul>
* This command will consume Synchronization messages for the
* com.any-erp-vendor.Person.BasicPerson/1.0 message object.
* This includes: Create, Update, Delete. When it consumes a Sync message, it
* will pull relevant information from the message it consumes and store it in it's
* own repository. This information will be stored in a more 'traditional' repository
* meaning it will actually store data in individual columns in its database.
* <P>
* You can use the SelfServiceApplication or the TestSuite Application (also included in the Getting Started
* distribution) to create, update, delete and query for people, employees and emergency
* contacts in the com.any-erp-vendor.Gateway. When you create, delete or update
* BasicPerson objects synchronization messages will be published and routed to this
* gateway.
* <P>
* Note, this command is purposely simple. It does not attempt to factor out much of the
* logic that could or should be. This is so most of the work being done is contained in this single
* file. Wile it is completely and fully functional, it should not be considered
* the best way to actually code some of this stuff. It is thouroughly commented so you
* should be able to get a pretty good idea about what's going on at all the critical points
* within the command execution.
* <P>
* To start this gateway you must execute the org.openeai.jms.consumer.MessageConsumerClient
* class passing the path to the properties file you wish to use.
* <P>
* e.g. - java -cp [classpath] org.openeai.jms.consumer.MessageConsumerClient c:\GettingStarted.properties
* <P>
* In the GettingStarted.properties file, you must un-comment the line that contains:
* <P>
* <i>messageComponentName=org.any-openeai-enterprise.EnterpriseWarehouse</i>
* <P>
* This tells AppConfig which Messaging Component (gateway) it's configuring.
* Refer to the GettingStarted guide and installation instructions for more information.
* <P>
* <B>Gateway Configuration</B>
* <P>
* These are the configuration parameters required by the sample org.any-openeai-enterprise.EnterpriseWarehouse.
* They are specified in the AnyOpenEaiEnterprise.xml Deployment Descriptor which is provided
* in the sample enterprise distribution.
* This gateway is identified in the AnyOpenEaiEnterprise.xml Deployment
* Descriptor as <b>org.any-openeai-enterprise.EnterpriseWarehouse</b>.
* <P>
* Configuration for a gateway can be broken into two pieces:
* <ul>
* <li>Configuring the consumer to connect to a topic or queue and telling it what commands it executes.
* <li>Configuring the command(s) executed by that consumer.
* </ul>
* <P>
* <b>Configuring the Consumer</b>
* <P>
* The items listed below can be found in the 'Configuration' Element associated to
* the org.any-openeai-enterprise.EnterpriseWarehouse gateway in the deployment descriptor.
* This Configuration element becomes the AppConfig
* object associated to this gateway <b>(remember, all OpenEAI gateways are started through
* the org.openeai.jms.consumer.MessageConsumerClient class)</b>.
* <P>
* The consumer's Configuration is fairly simple. It contains a LoggerConfig object that specifies
* how the log4j logger will behave and it contains a ConsumerConfigs element. Below is a description
* of the Consumer configuration. Note, not all configurable items are mentioned but that
* information can be reviewed by looking at the core OpenEAI API Javadoc.
* <P>
* <TABLE BORDER=2 CELLPADDING=5 CELLSPACING=2>
* <TR>
* <TH>Configuration Object Name</TH>
* <TH>Required</TH>
* <TH>Description</TH>
* </TR>
* <TR HALIGN="left" VALIGN="top">
* <TD>WarehouseConsumer1</TD>
* <TD>yes</TD>
* <TD>An OpenEAI PubSubConsumer object configured to consume JMS messages off
* the 'cn=EnterpriseWarehouseTopic' topic. When the com.any-erp-vendor.Gateway publishes
* Sync messages, the EnterpriseTransRouter will route messages that contain messageObjects of
* type BasicPerson to this topic. This consumer will consume those messages and execute
* the org.any_openeai_enterprise.gateways.warehouse.EnterpriseWarehouseCommand (this command)
* which is specified as a Command executed by this consumer. As a matter of fact, it is the ONLY command
* that will ever be executed by this consumer since its 'isAbsolute' attribute is 'true'.
* That Command will perform the necessary business logic. If any errors occur, the command
* will publish an org.openeai.CoreMessaging/Sync/1.0/Error-Sync message that will be logged
* by the 'Enterprise Logging Service'.
* <P>
* The Consumer's configuration specifies that it will connect to the broker
* and be ready to consume messages when it is initialized ('startOnInitialization=true') use the
* InitialContextFactory 'org.exolab.jms.jndi.rmi.RmiJndiInitialContextFactory' to retrieve the JMS
* administered objects from the 'rmi://localhost:1099/JndiServer' ProviderURL (the directory server normally).
* Then it will connect to the JMS Provider using the 'cn=EnterpriseWarehouseConsumerTCF' JMS TopicConnectionFactory
* administered object.
* <P>
* NOTE: These are the parameters you change when you wish to switch JMS providers or use different JNDI stores
* to store your administered objects.
* <P>
* It will execute the Commands specified in a ThreadPool that has 30 pre-allocated Threads available to it and it will
* detect when the ThreadPool is busy and only add another Command execution to the ThreadPool when the ThreadPool has
* available threads to process the transaction.</TD>
* </TR>
* </TABLE>
* <P>
* <b>Configuring the Command(s) executed by the Consumer</b>
* <P>
* The EnterpriseWarehouseCommand command will NOT validate
* the JDOM Document created from the JMS Message that's passed to it (inboundXmlValidation=false).
* If you'd like it to validate incomming XML, you can change this attribute to true.
* Additionally, it will not write the XML Document to a file (writeToFile=false) when it receives it. As stated
* before, this command is the 'absolute' command associated to this consumer. So, no matter what "COMMAND_NAME" is
* associated to the JMS Message as it is consumed by the consumer, this command will be executed. The
* EnterpriseWarehouse (CommandName) is implemented by the
* org.any_openeai_enterprise.gateways.warehouse.EnterpriseWarehouseCommand class (CommandClass) and
* it is a 'syncMessage' Command (type=syncMessage).
* <P>
* The items listed below can be found in the 'Configuration' Element associated to the
* EnterpriseWarehouse in the deployment descriptor. This Configuration element becomes the AppConfig
* object associated to this Command that is used by the command when it is executed.
* <P>
* They are broken apart by Configuration object type. This command
* will Publish Sync-Error messages if it ever has any problems performing the business logic,
* it will use Message Objects to operate on the data contained in the message consumed, it will
* use a DbConnectionPool to persist data and it will use several general Properties object.
* Therefore, there are four categories of configuration objects used: ProducerConfigs,
* MessageObjectConfigs, DbConnectionPoolConfigs and PropertyConfigs.
* <P>
* <TABLE BORDER=2 CELLPADDING=5 CELLSPACING=2>
* <TR>
* <TH>Configuration Object Type</TH>
* <TH>Configuration Object Name</TH>
* <TH>Required</TH>
* <TH>Description</TH>
* </TR>
* <TR HALIGN="left" VALIGN="top">
* <TD>ProducerConfigs</TD>
* <TD>SyncErrorPublisher</TD>
* <TD>yes</TD>
* <TD>An OpenEAI PubSubProducer object configured to publish Synchronization message to the
* 'cn=EnterpriseSyncErrorLoggerTopic'. This will be used any time the command encounters
* errors performing its business logic. That Sync-Error message will then be logged
* by the 'Enterprise Logging Service' for follow-up by EAI support staff.
* <P>
* NOTE: This is a required object for all SyncCommand implementations. The gateway
* will not start if you have not specified a PubSubProducer named 'SyncErrorPublisher'.</TD>
* </TR>
* </TABLE>
* <P>
* <b>MessageObjectConfigs</b>
* <P>
* These configuration objects are used to configure all Message objects required by this command.
* The message objects themselves are part of the com.any-erp-vendor Message Object API (MOA) which
* was provided by the vendor because they've defined enterprise messages according to the OpenEAI
* Message Protocol. These objects were generated off of their enterprise message definitions (their Segments.dtd file).
* <P>
* The objects are configured to use the Enterprise Object (EO) documents supplied by the com.any-erp-vendor organization that
* were also generated from their Segments.dtd file.
* In our sample enterprise, we've added some of our own formatting rules (datatypes, lengths, scrubbers and translations)
* to these EO documents that our sample organization require.
* <P>
* The objects are used to operate on the data supplied in the sync messages as well
* as to persist the relevant information to the database.
* <P>
* <TABLE BORDER=2 CELLPADDING=5 CELLSPACING=2>
* <TR>
* <TH>Configuration Object Name</TH>
* <TH>Required</TH>
* <TH>Description</TH>
* </TR>
* <TR HALIGN="left" VALIGN="top">
* <TD>BasicPerson.v1_0</TD>
* <TD>yes</TD>
* <TD>A com.any_erp_vendor.moa.jmsobjects.person.v1_0.BasicPerson Java object that was generated
* from the com/any-erp-vendor/Resources/1.0/Segments.dtd file. This object will be built
* from the contents of the messages consumed
* and used to store relevant information in the repository associated to this command.</TD>
* </TR>
* </TABLE>
* <P>
* <TABLE BORDER=2 CELLPADDING=5 CELLSPACING=2>
* <TR>
* <TH>Configuration Object Type</TH>
* <TH>Configuration Object Name</TH>
* <TH>Required</TH>
* <TH>Description</TH>
* </TR>
* <TR HALIGN="left" VALIGN="top">
* <TD>DbConnectionPoolConfigs</TD>
* <TD>WarehouseDbPool</TD>
* <TD>yes</TD>
* <TD>This is an OpenEAI org.openeai.dbpool.EnterpriseConnectionPool object. The command will
* retrieve a pre-established database connection from the pool and execute SQL statements. By default,
* the connections in the pool are configured to work with a MySql database. However, scripts
* are provided in the Sample Enterprise distribution that will create Oracle structures as well. To
* use these Oracle structures, you would simply change the pool configuration information here.</TD>
* </TR>
* </TABLE>
* <P>
* <TABLE BORDER=2 CELLPADDING=5 CELLSPACING=2>
* <TR>
* <TH>Configuration Object Type</TH>
* <TH>Configuration Object Name</TH>
* <TH>Required</TH>
* <TH>Description</TH>
* </TR>
* <TR HALIGN="left" VALIGN="top">
* <TD>PropertyConfig</TD>
* <TD>WarehouseProperties</TD>
* <TD>yes</TD>
* <TD>These are 'general' properties that will be associated to this Command.</TD>
* </TR>
* </TABLE>
* <P>
* <TABLE BORDER=2 CELLPADDING=5 CELLSPACING=2>
* <TR>
* <TH>Configuration Object Type</TH>
* <TH>Configuration Object Name</TH>
* <TH>Required</TH>
* <TH>Description</TH>
* </TR>
* <TR HALIGN="left" VALIGN="top">
* <TD>PropertyConfig</TD>
* <TD>SyncErrorSyncProperties</TD>
* <TD>yes</TD>
* <TD>These are REQUIRED properties that are used by SyncCommandImpl (this command's anscestor)
* to configure itself to publish Sync-Error messages. All SyncCommand implementations must
* have a PropertyConfig object named 'SyncErrorSyncProperties' or they will not start. These
* Properties specify the 'primed' Sync-Error document location so that resource can be made
* available when the Command is first initialized and so it doesn't have to do it itself
* later when/if there's an error.</TD>
* </TR>
* </TABLE>
* <P>
* @author Tod Jackson (tod@openeai.org)
**/
public class EnterpriseWarehouseCommand
extends SyncCommandImpl
implements SyncCommand {
private EnterpriseConnectionPool m_connPool = null;
public EnterpriseWarehouseCommand(CommandConfig cConfig) throws InstantiationException {
super(cConfig);
try {
// default properties associated to this command (there could be others named differently).
PropertyConfig pConfig = (PropertyConfig)getAppConfig().getObject("WarehouseProperties");
setProperties(pConfig.getProperties());
// initialize db connection pool that will be used to store information from the
// message into our own repository
m_connPool = (EnterpriseConnectionPool)getAppConfig().getObject("WarehouseDbPool");
}
catch (Exception e) {
logger.fatal("Error initializing 'EnterpriseWarehouse' command.");
logger.fatal(e.getMessage(), e);
throw new InstantiationException(e.getMessage());
}
logger.info("EnterpriseWarehouseCommand instantiated successfully.");
}
/**
* Takes the BasicPerson sync messages that have been published by the ERP system
* and routed to this gateway and stores relevant information from the consumed
* messages in its own repository for "wharehousing" purposes like report writing etc.
**/
public void execute(int messageNumber, Message aMessage) throws CommandException {
String errMessage = "";
Document inDoc = null;
try {
inDoc = initializeInput(messageNumber, aMessage);
}
catch (Exception e) {
errMessage = "Exception occurred processing input message in ConsumerCommand. Exception: " + e.getMessage();
ArrayList errors = new ArrayList();
errors.add(buildError("application", "SYNC-1001", errMessage));
publishSyncError(new Element("EmptyControlArea"), errors, e);
throw new CommandException(e.getMessage());
}
Element eControlArea = getControlArea(inDoc.getRootElement());
Element eDataArea = inDoc.getRootElement().getChild(DATA_AREA);
String msgAction = eControlArea.getAttribute(MESSAGE_ACTION).getValue();
String msgObject = eControlArea.getAttribute(MESSAGE_OBJECT).getValue();
String msgRelease = eControlArea.getAttribute(MESSAGE_RELEASE).getValue();
String msgCategory = eControlArea.getAttribute(MESSAGE_CATEGORY).getValue();
String msgType = eControlArea.getAttribute(MESSAGE_TYPE).getValue();
// if the message object isn't one we're interested in (BasicPerson) publish
// a sync error and return...
String dataAreaChild = NEW_DATA; // Default, this will work for Create and Update
if (msgAction.equalsIgnoreCase(DELETE_ACTION)) {
dataAreaChild = DELETE_DATA;
}
// Get the DataArea element out of the document
// This should correspond to one of our message objects.
Element eMessageObject = eDataArea.getChild(dataAreaChild).getChild(msgObject);
if (eMessageObject == null) {
// Error!
errMessage = "Could not find an element at DataArea/" + dataAreaChild + "/" + msgObject +
"in the " + msgObject + "-" + msgAction + "-Sync Document passed in";
logger.fatal(errMessage);
logger.fatal("Message sent in is: \n" + getMessageBody(inDoc));
ArrayList errors = new ArrayList();
errors.add(buildError("application", "MSG-1001", errMessage));
publishSyncError(eControlArea, errors);
return;
}
// if the msgAction is Update, we'll need to get the baseline object out of the document as well.
Element eBaselineMessageObject = null;
if (msgAction.equalsIgnoreCase(UPDATE_ACTION)) {
// we need to create a baseline BasicPerson also so we have to get the baseline element...
eBaselineMessageObject = inDoc.getRootElement().
getChild(DATA_AREA).
getChild(BASELINE_DATA).
getChild(msgObject);
if (eBaselineMessageObject == null) {
// Error!
errMessage = "Could not find a " + msgObject + " + element at DataArea/BaselineData/" + msgObject +
" in the "+msgObject+"-"+msgAction+"-" + msgAction + " Document passed in";
ArrayList errors = logErrors("MSG-1012", errMessage, inDoc);
publishSyncError(eControlArea, errors);
return;
}
}
// get the object(s) we need to build from AppConfig
BasicPerson bPerson = null;
BasicPerson baselinePerson = null;
// build the message object from the element retrieved from the XML document.
// this is done via the default XmlLayout manager.
try {
bPerson = (BasicPerson)getAppConfig().getObject(msgObject + "." + generateRelease(msgRelease));
bPerson.buildObjectFromInput(eMessageObject);
if (msgAction.equalsIgnoreCase(UPDATE_ACTION)) {
baselinePerson = (BasicPerson)getAppConfig().getObject(msgObject + "." + generateRelease(msgRelease));
baselinePerson.buildObjectFromInput(eBaselineMessageObject);
}
}
catch (Exception e) {
errMessage = "Exception occurred building the " + eMessageObject.getName() + " Java object from the Element passed in. Exception: " + e.getMessage();
ArrayList errors = logErrors("MSG-1003", errMessage, inDoc);
publishSyncError(eControlArea, errors, e);
return;
}
// now, perform the actual database activity based on the action associated to
// the message consumed.
if (msgAction.equalsIgnoreCase(CREATE_ACTION)) {
try {
createPerson(msgCategory, msgObject, msgRelease, bPerson);
return;
}
catch (Exception e) {
errMessage = "Exception occurred Creating the " + msgObject + " Java object in the database. Exception: " + e.getMessage();
logger.fatal(errMessage, e);
ArrayList errors = logErrors("MSG-1003", errMessage, inDoc);
publishSyncError(eControlArea, errors, e);
return;
}
}
else if (msgAction.equalsIgnoreCase(DELETE_ACTION)) {
try {
String deleteAction = "delete";
deletePerson(msgCategory, msgObject, msgRelease, deleteAction, bPerson);
return;
}
catch (Exception e) {
errMessage = "Exception occurred Deleting the " + msgObject + " Java object from the database. Exception: " + e.getMessage();
logger.fatal(errMessage, e);
ArrayList errors = logErrors("MSG-1003", errMessage, inDoc);
publishSyncError(eControlArea, errors, e);
return;
}
}
else if (msgAction.equalsIgnoreCase(UPDATE_ACTION)) {
try {
// since we're not authoritative, we just want to do the update if the person
// exists, if it doesn't exist, we could create the person?
updatePerson(msgCategory, msgObject, msgRelease, bPerson, baselinePerson);
}
catch (Exception e) {
errMessage = "Exception occurred Updating the " + msgObject + " Java object in the database. Exception: " + e.getMessage();
logger.fatal(errMessage, e);
ArrayList errors = logErrors("MSG-1003", errMessage, inDoc);
publishSyncError(eControlArea, errors, e);
return;
}
}
else {
// error, invalid message action.
}
}
protected BasicPerson retrievePerson(String instId) throws SQLException {
PreparedStatement stmt = null;
String sqlString = "SELECT INST_ID, FIRST_NAME, MIDDLE_NAME, LAST_NAME, " +
"GENDER, ETHNICITY, BIRTH_DATE, SSN FROM T_PERSON " +
"WHERE INST_ID=?";
java.sql.Connection conn = null;
EnterprisePooledConnection p = null;
try {
p = m_connPool.getExclusiveConnection();
conn = p.getConnection();
conn.setAutoCommit(true);
}
catch (Exception e) {
logger.fatal(e.getMessage(), e);
throw new SQLException(e.getMessage());
}
try {
stmt = conn.prepareStatement(sqlString);
stmt.clearParameters();
stmt.setString(1, instId);
logger.info("Retrieving Person record for InstitutionalId: " + instId);
ResultSet rs = stmt.executeQuery();
logger.info("Retreived Person record for InstitutionalId: " + instId);
BasicPerson bPerson = (BasicPerson)getAppConfig().getObject("BasicPerson.v1_0");
Name aName = bPerson.newName();
boolean foundPerson = false;
while (rs.next()) {
foundPerson = true;
bPerson.setInstitutionalId(rs.getString(1));
aName.setFirstName(rs.getString(2));
aName.setMiddleName(rs.getString(3));
aName.setLastName(rs.getString(4));
bPerson.setName(aName);
bPerson.setGender(rs.getString(5));
bPerson.setEthnicity(rs.getString(6));
com.any_erp_vendor.moa.objects.resources.v1_0.Date bDate = bPerson.newBirthDate();
java.sql.Date dbDate = rs.getDate(7);
if (dbDate != null) {
Calendar calendar = new GregorianCalendar();
calendar.setTime(dbDate);
bDate.setYear(Integer.toString(calendar.get(Calendar.YEAR)));
bDate.setMonth(Integer.toString(calendar.get(Calendar.MONTH)+1));
bDate.setDay(Integer.toString(calendar.get(Calendar.DAY_OF_MONTH)));
logger.info("BirthDate from db is: " + bDate.toString());
bPerson.setBirthDate(bDate);
}
bPerson.setSocialSecurityNumber(rs.getString(8));
}
stmt.close();
// finally, release the connection.
m_connPool.releaseExclusiveConnection(p);
if (foundPerson) {
return bPerson;
}
else {
return null;
}
}
catch (Exception e) {
if (stmt != null) {
stmt.close();
}
logger.fatal(e.getMessage(), e);
throw new SQLException(e.getMessage());
}
finally {
m_connPool.releaseExclusiveConnection(p);
}
}
/**
* This method updates the information in T_PERSON for the BasicPerson object passed in.
* Since this is a SyncCommand (it's not authoritative), it simply takes the data provided
* and updates its repository. If anything had been changed in the local repository, it would
* be overridden. Since's this is a warehouse gateway, data is only viewed, it's not changed
* in the local repository.
* <P>
* In addition to updating the T_PERSON table, this method also looks at each Address and Phone
* object contained within the newData BasicPerson object and compares them against the
* Address and Phone objects contained withing the baselinePerson BasicPerson object. Depending
* on that comparison, it may call any of the create, delete or update methods associated to
* Addresses and Phones. It uses the 'key' fields associated to the Address and Phone objects
* to determine if the Address or Phone transaction needs to be an insert, update or delete.
* <P>
* @param msgCategory the 'messageCategory' attribute extracted from the
* ControlAreaRequest of the enterprise message. Example: 'com.any-erp-vendor.Person'.
* @param msgObject the 'messageObject' attribute extracted from the
* ControlAreaRequest of the enterprise message. Example: 'BasicPerson'.
* @param msgRelease the 'messageRelease' attribute extracted from the
* ControlAreaRequest of the enterprise message. Example: '1.1'.
* @param deleteAction the delete action associated to the request that was pulled
* from the 'DataArea/DeleteData/DeleteAction' element in the enterprise message.
* @param newData the BasicPerson Java object that was built from the contents of the
* enterprise message passed in (DataArea/NewData). This is the new state of the BasicPerson. When
* this method is complete, the state of the object in our local repository (T_PERSON, T_ADDRESS and T_PHONE)
* should match this object.
* @param baselinePerson the BasicPerson Java object that was built from the contents of the
* enterprise message passed in (DataArea/BaselineData). This is the baseline state of the BasicPerson. This
* object is used to determine what transaction should be perfored on the Address and Phone
* objects (insert, update or deletes)
* @throws SQLException if errors occur deleting the message object from the database or if
* errors occur publishing the resulting Delete-Sync message.
**/
protected void updatePerson(String msgCategory, String msgObject, String msgRelease, BasicPerson newData, BasicPerson baselinePerson) throws SQLException {
BasicPerson dbPerson = retrievePerson(newData.getInstitutionalId());
if (dbPerson == null) {
logger.info("Person did not exist in our repository, we'll just create them.");
createPerson(msgCategory, msgObject, msgRelease, newData);
return;
}
PreparedStatement stmt = null;
String sqlString = "UPDATE T_PERSON " +
"SET FIRST_NAME=?, MIDDLE_NAME=?, LAST_NAME=?, GENDER=?, " +
"ETHNICITY=?, BIRTH_DATE=?, SSN=?, MOD_DATE=?, MOD_USER=? " +
"WHERE INST_ID=? AND MESSAGE_CATEGORY=? AND MESSAGE_OBJECT=? AND MESSAGE_RELEASE=?";
String instId = newData.getInstitutionalId();
java.sql.Connection conn = null;
EnterprisePooledConnection p = null;
try {
p = m_connPool.getExclusiveConnection();
conn = p.getConnection();
conn.setAutoCommit(false);
}
catch (Exception e) {
logger.fatal(e.getMessage(), e);
throw new SQLException(e.getMessage());
}
try {
stmt = conn.prepareStatement(sqlString);
stmt.clearParameters();
stmt.setString(1, newData.getName().getFirstName());
stmt.setString(2, newData.getName().getMiddleName());
stmt.setString(3, newData.getName().getLastName());
stmt.setString(4, newData.getGender(getAppName()));
stmt.setString(5, newData.getEthnicity(getAppName()));
String sBirthDate = "";
if (newData.getBirthDate() != null && newData.getBirthDate().isEmpty() == false) {
sBirthDate = newData.getBirthDate().getMonth() + "/" +
newData.getBirthDate().getDay() + "/" +
newData.getBirthDate().getYear();
java.util.Date d = new java.util.Date();
java.text.SimpleDateFormat formatter = new java.text.SimpleDateFormat( "MM/dd/yyyy" );
d = formatter.parse(sBirthDate);
stmt.setDate(6, new java.sql.Date(d.getTime()));
}
else {
stmt.setDate(6, null);
}
stmt.setString(7, newData.getSocialSecurityNumber());
stmt.setTimestamp(8, new java.sql.Timestamp(System.currentTimeMillis()));
stmt.setString(9, conn.getMetaData().getUserName());
stmt.setString(10, instId);
stmt.setString(11, msgCategory);
stmt.setString(12, msgObject);
stmt.setString(13, msgRelease);
logger.info("Attempting to Update " + msgObject + " record for InstitutionalId: " + instId);
int rc = stmt.executeUpdate();
logger.info("Updated " + msgObject + " record for InstitutionalId: " + instId + " rc=" + rc);
stmt.close();
// now the address(s), using the same connection
// have to determine if we need to insert, delete or update any
logger.info("Starting Address update process...");
java.util.List newAddresses = newData.getAddress();
java.util.List oldAddresses = baselinePerson.getAddress();
for (int i=0; i<newAddresses.size(); i++) {
Address newAddress = (Address)newAddresses.get(i);
String newAddressKey = newAddress.getCombinedKeyValue();
boolean foundMatch = false;
for (int j=0; j<oldAddresses.size(); j++) {
Address oldAddress = (Address)oldAddresses.get(j);
String oldAddressKey = oldAddress.getCombinedKeyValue();
if (oldAddressKey.equalsIgnoreCase(newAddressKey)) {
// found a match, might have to update...
foundMatch = true;
if (newAddress.equals(oldAddress) == false) {
// need to update individual address
logger.info("updating existing address object.");
updateAddress(conn, msgCategory, msgObject, msgRelease, instId, newAddress);
}
}
}
if (foundMatch == false) {
// need to create address
logger.info("creating new address object.");
createAddress(conn, msgCategory, msgObject, msgRelease, instId, newAddress);
}
}
// now we need to check the oldAddresses and delete any that don't
// exist in the newAddress list
for (int i=0; i<oldAddresses.size(); i++) {
Address oldAddress = (Address)oldAddresses.get(i);
String oldAddressKey = oldAddress.getCombinedKeyValue();
boolean foundMatch = false;
for (int j=0; j<newAddresses.size(); j++) {
Address newAddress = (Address)newAddresses.get(j);
String newAddressKey = newAddress.getCombinedKeyValue();
if (oldAddressKey.equalsIgnoreCase(newAddressKey)) {
// found a match, don't delete
foundMatch = true;
}
}
if (foundMatch == false) {
// must delete the oldAddress
logger.info("deleting old address object.");
deleteAddress(conn, msgCategory, msgObject, msgRelease, instId, oldAddress);
}
}
logger.info("Finished Address update process...");
// now the phone(s), using the same connection
// have to determine if we need to insert, delete or update any
logger.info("Starting Phone update process...");
java.util.List newPhones = newData.getPhone();
java.util.List oldPhones = baselinePerson.getPhone();
for (int i=0; i<newPhones.size(); i++) {
Phone newPhone = (Phone)newPhones.get(i);
String newPhoneKey = newPhone.getCombinedKeyValue();
boolean foundMatch = false;
for (int j=0; j<oldPhones.size(); j++) {
Phone oldPhone = (Phone)oldPhones.get(j);
String oldPhoneKey = oldPhone.getCombinedKeyValue();
if (oldPhoneKey.equalsIgnoreCase(newPhoneKey)) {
// found a match, might have to update...
foundMatch = true;
if (newPhone.equals(oldPhone) == false) {
// need to update individual phone
logger.info("updating existing phone object.");
updatePhone(conn, msgCategory, msgObject, msgRelease, instId, newPhone);
}
}
}
if (foundMatch == false) {
// need to create phone
logger.info("creating new address object.");
createPhone(conn, msgCategory, msgObject, msgRelease, instId, newPhone);
}
}
// now we need to check the oldPhones and delete any that don't
// exist in the newAddress list
for (int i=0; i<oldPhones.size(); i++) {
Phone oldPhone = (Phone)oldPhones.get(i);
String oldPhoneKey = oldPhone.getCombinedKeyValue();
boolean foundMatch = false;
for (int j=0; j<newPhones.size(); j++) {
Phone newPhone = (Phone)newPhones.get(j);
String newPhoneKey = newPhone.getCombinedKeyValue();
if (oldPhoneKey.equalsIgnoreCase(newPhoneKey)) {
// found a match, don't delete
foundMatch = true;
}
}
if (foundMatch == false) {
// must delete the oldPhone
logger.info("deleting old address object.");
deletePhone(conn, msgCategory, msgObject, msgRelease, instId, oldPhone);
}
}
logger.info("Finished Phone update process...");
// now the email(s), using the same connection
// finally, commit it all if everything went okay.
conn.commit();
m_connPool.releaseExclusiveConnection(p);
}
catch (Exception e) {
conn.rollback();
if (stmt != null) {
stmt.close();
}
logger.fatal(e.getMessage(), e);
throw new SQLException(e.getMessage());
}
finally {
m_connPool.releaseExclusiveConnection(p);
}
}
/**
* This method first deletes all Address and Phone objects contained within the BasicPerson
* object passed in by calling the deleteAddress and deletePhone methods. Then it
* deletes the T_PERSON row associated to the BasicPerson message object passed in.
* <P>
* @param msgCategory the 'messageCategory' attribute extracted from the
* ControlAreaRequest of the enterprise message. Example: 'com.any-erp-vendor.Person'.
* @param msgObject the 'messageObject' attribute extracted from the
* ControlAreaRequest of the enterprise message. Example: 'BasicPerson'.
* @param msgRelease the 'messageRelease' attribute extracted from the
* ControlAreaRequest of the enterprise message. Example: '1.1'.
* @param deleteAction the delete action associated to the request that was pulled
* from the 'DataArea/DeleteData/DeleteAction' element in the enterprise message.
* @param bPerson the BasicPerson Java object that was built from the contents of the
* enterprise message passed. The InstitutionalId from this object will be used
* to delete data from the T_PERSON table. Additionally, Address and Phone objects will
* be extracted from the object and deleted from their respective tables.
* @throws SQLException if errors occur deleting the message object from the database or if
* errors occur publishing the resulting Delete-Sync message.
**/
protected void deletePerson(String msgCategory, String msgObject, String msgRelease, String deleteAction, BasicPerson bPerson) throws SQLException {
PreparedStatement stmt = null;
String sqlString = "delete from T_PERSON " +
"where inst_id=? AND MESSAGE_CATEGORY=? AND MESSAGE_OBJECT=? AND MESSAGE_RELEASE=?";
String instId = bPerson.getInstitutionalId();
java.sql.Connection conn = null;
EnterprisePooledConnection p = null;
try {
p = m_connPool.getExclusiveConnection();
conn = p.getConnection();
conn.setAutoCommit(false);
}
catch (Exception e) {
logger.fatal(e.getMessage(), e);
throw new SQLException(e.getMessage());
}
try {
// first the address(s), using the same connection
for (int i=0; i<bPerson.getAddress().size(); i++) {
Address a = bPerson.getAddress(i);
deleteAddress(conn, msgCategory, msgObject, msgRelease, instId, a);
}
// now the phone(s), using the same connection
for (int i=0; i<bPerson.getPhone().size(); i++) {
Phone phone = bPerson.getPhone(i);
deletePhone(conn, msgCategory, msgObject, msgRelease, instId, phone);
}
// now the email(s), using the same connection
// now the actual person record
stmt = conn.prepareStatement(sqlString);
stmt.clearParameters();
stmt.setString(1, instId);
stmt.setString(2, msgCategory);
stmt.setString(3, msgObject);
stmt.setString(4, msgRelease);
logger.info("Attempting to delete " + msgObject + " record for InstitutionalId: " + instId);
int rc = stmt.executeUpdate();
logger.info("Deleted " + msgObject + " record for InstitutionalId: " + instId);
stmt.close();
// finally, commit it all if everything went okay.
conn.commit();
m_connPool.releaseExclusiveConnection(p);
}
catch (Exception e) {
conn.rollback();
if (stmt != null) {
stmt.close();
}
logger.fatal(e.getMessage(), e);
throw new SQLException(e.getMessage());
}
finally {
m_connPool.releaseExclusiveConnection(p);
}
}
/**
* Inserts the InstitutionalId, FirstName, MiddleName, LastName, Gender, Ethnicity
* BirthDate and SocialSecurityNumber fields into the T_PERSON table. Note, that the
* values stored for fields like Gender and Ethnicity are reverse translated from
* "enterprise values" to "application values" that are specified in the BasicPersonEO.xml
* file (EO doc) for the BasicPerson object being used by this command.
* <P>
* Then it goes through each Address object contained within the BasicPerson object passed in
* and inserts it into the T_ADDRESS table by calling the 'createAddress' method.
* <P>
* Then it goes through each Phone object containe within the BasicPerson object passed in and
* inserts it into the T_PHONE table calling the 'createPhone' method.
* <P>
* @param msgCategory the 'messageCategory' attribute extracted from the
* ControlAreaRequest of the enterprise message. Example: 'com.any-erp-vendor.Person'.
* @param msgObject the 'messageObject' attribute extracted from the
* ControlAreaRequest of the enterprise message. Example: 'BasicPerson'.
* @param msgRelease the 'messageRelease' attribute extracted from the
* ControlAreaRequest of the enterprise message. Example: '1.1'.
* @param bPerson the BasicPerson Java object that was built from the contents of the
* enterprise message passed. Individual fields from this object will be extracted
* and inserted into the T_PERSON table. Additionally, Address and Phone objects will
* be extracted from the object and inserted into their respective tables.
* @throws SQLException if errors occur deleting the message object from the database or if
* errors occur publishing the resulting Delete-Sync message.
**/
protected void createPerson(String msgCategory, String msgObject, String msgRelease, BasicPerson bPerson) throws SQLException {
PreparedStatement insertStmt = null;
String insertString = "INSERT INTO T_PERSON (INST_ID, MESSAGE_CATEGORY, MESSAGE_OBJECT, MESSAGE_RELEASE, FIRST_NAME, " +
"MIDDLE_NAME, LAST_NAME, GENDER, ETHNICITY, " +
"BIRTH_DATE, SSN, " +
"CREATE_DATE, CREATE_USER, MOD_DATE, MOD_USER) " +
"VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)";
// get the institutional id from the BasicPerson
String instId = bPerson.getInstitutionalId();
// get an exclusive connection from our OpenEAI database connection pool.
// this is required if we're going to perform database activities within
// a transaction (autocommit=false)
java.sql.Connection conn = null;
EnterprisePooledConnection p = null;
try {
p = m_connPool.getExclusiveConnection();
conn = p.getConnection();
conn.setAutoCommit(false);
}
catch (Exception e) {
logger.fatal(e.getMessage(), e);
throw new SQLException(e.getMessage());
}
// Now, prepare our SQL statement setting values that should be inserted into
// the T_PERSON table. Note, when fields like Gender and Ethnicity are retrieved
// from the BasicPerson object, we're passing our application name. This will
// result in the enterprise values contained in the BasicPerson object being reverse
// translated into application specific values for our system.
try {
insertStmt = conn.prepareStatement(insertString);
insertStmt.clearParameters();
insertStmt.setString(1, instId);
insertStmt.setString(2, msgCategory);
insertStmt.setString(3, msgObject);
insertStmt.setString(4, msgRelease);
insertStmt.setString(5, bPerson.getName().getFirstName());
insertStmt.setString(6, bPerson.getName().getMiddleName());
insertStmt.setString(7, bPerson.getName().getLastName());
insertStmt.setString(8, bPerson.getGender(getAppName()));
insertStmt.setString(9, bPerson.getEthnicity(getAppName()));
String sBirthDate = "";
if (bPerson.getBirthDate() != null && bPerson.getBirthDate().isEmpty() == false) {
sBirthDate = bPerson.getBirthDate().getMonth() + "/" +
bPerson.getBirthDate().getDay() + "/" +
bPerson.getBirthDate().getYear();
java.util.Date d = new java.util.Date();
java.text.SimpleDateFormat formatter = new java.text.SimpleDateFormat( "MM/dd/yyyy" );
d = formatter.parse(sBirthDate);
insertStmt.setDate(10, new java.sql.Date(d.getTime()));
}
else {
insertStmt.setDate(10, null);
}
insertStmt.setString(11, bPerson.getSocialSecurityNumber());
insertStmt.setTimestamp(12, new java.sql.Timestamp(System.currentTimeMillis()));
insertStmt.setString(13, conn.getMetaData().getUserName());
insertStmt.setTimestamp(14, new java.sql.Timestamp(System.currentTimeMillis()));
insertStmt.setString(15, conn.getMetaData().getUserName());
logger.info("Attempting to insert " + msgObject + " record for InstitutionalId: " + instId);
logger.debug("Gender appValue: '" + bPerson.getGender(getAppName()) + "'");
logger.debug("Ethnicity appValue: '" + bPerson.getEthnicity(getAppName()) + "'");
int insertRc = insertStmt.executeUpdate();
logger.info("Inserted " + msgObject + " record for InstitutionalId: " + instId);
insertStmt.close();
// now the address(s), using the same connection
for (int i=0; i<bPerson.getAddress().size(); i++) {
Address a = bPerson.getAddress(i);
createAddress(conn, msgCategory, msgObject, msgRelease, instId, a);
}
// now the phone(s), using the same connection
for (int i=0; i<bPerson.getPhone().size(); i++) {
Phone phone = bPerson.getPhone(i);
createPhone(conn, msgCategory, msgObject, msgRelease, instId, phone);
}
// now the email(s), using the same connection
// finally, commit it all if everything went okay.
conn.commit();
m_connPool.releaseExclusiveConnection(p);
}
catch (Exception e) {
conn.rollback();
if (insertStmt != null) {
insertStmt.close();
}
logger.fatal(e.getMessage(), e);
throw new SQLException(e.getMessage());
}
finally {
m_connPool.releaseExclusiveConnection(p);
}
}
/**
* Deletes a single Address row from the T_ADDRESS table. Uses the msgCategory,
* msgObject, msgRelease and instId parameters passed in as well as the Address type associated
* to the Address object passed in as the delete criteria.
* <P>
* @param conn a pre-established database connection. Since an Address is only ever
* deleted as part of a larger transaction (BasicPerson-Delete or Update) this
* delete must occur within that same transaction, therefore, this method does not
* commit the transaction.
* @param msgCategory the 'messageCategory' attribute extracted from the
* ControlAreaRequest of the enterprise message. Example: 'com.any-erp-vendor.Person'.
* @param msgObject the 'messageObject' attribute extracted from the
* ControlAreaRequest of the enterprise message. Example: 'BasicPerson'.
* @param msgRelease the 'messageRelease' attribute extracted from the
* ControlAreaRequest of the enterprise message. Example: '1.1'.
* @param instId associated to the person we're deleting an address for.
* @param a the Address Java object that was pulled from the BasicPerson object that was
* built from the enterprise message passed.
* @throws SQLException if errors occur deleting the Address from the database.
**/
protected void deleteAddress(java.sql.Connection conn, String msgCategory, String msgObject, String msgRelease, String instId, Address a) throws SQLException {
PreparedStatement stmt = null;
String sqlString = "delete from T_ADDRESS " +
"where inst_id=? and MESSAGE_CATEGORY=? AND " +
"MESSAGE_OBJECT=? AND MESSAGE_RELEASE=? AND " +
"ADDR_TYPE=?";
try {
// delete the individual address record passed in
stmt = conn.prepareStatement(sqlString);
stmt.clearParameters();
stmt.setString(1, instId);
stmt.setString(2, msgCategory);
stmt.setString(3, msgObject);
stmt.setString(4, msgRelease);
stmt.setString(5, a.getType(getAppName()));
logger.info("Attempting to delete Address record " + a.toString() + " for InstitutionalId: " + instId);
int rc = stmt.executeUpdate();
logger.info("Deleted Address record " + a.toString() + " for InstitutionalId: " + instId + " rc=" + rc);
stmt.close();
}
catch (Exception e) {
conn.rollback();
if (stmt != null) {
stmt.close();
}
logger.fatal(e.getMessage(), e);
throw new SQLException(e.getMessage());
}
}
/**
* Updates a single Address row from the T_ADDRESS table. Uses the msgCategory,
* msgObject, msgRelease and instId parameters passed in as well as the Address type associated
* to the Address object passed in as the update criteria.
* <P>
* @param conn a pre-established database connection. Since an Address is only ever
* updated as part of a larger transaction (BasicPerson-Update) this
* update must occur within that same transaction, therefore, this method does not
* commit the transaction.
* @param msgCategory the 'messageCategory' attribute extracted from the
* ControlAreaRequest of the enterprise message. Example: 'com.any-erp-vendor.Person'.
* @param msgObject the 'messageObject' attribute extracted from the
* ControlAreaRequest of the enterprise message. Example: 'BasicPerson'.
* @param msgRelease the 'messageRelease' attribute extracted from the
* ControlAreaRequest of the enterprise message. Example: '1.1'.
* @param instId associated to the person we're updating an address for.
* @param a the Address Java object that was pulled from the BasicPerson object that was
* built from the enterprise message passed in.
* @throws SQLException if errors occur updating the Address from the database.
**/
protected void updateAddress(java.sql.Connection conn, String msgCategory, String msgObject, String msgRelease, String instId, Address a) throws SQLException {
PreparedStatement stmt = null;
String sqlString = "UPDATE T_ADDRESS SET STREET1=?, STREET2=?, " +
"STREET3=?, CITY=?, STATE_CODE=?, ZIP_CODE=?, EFFECTIVE_DATE=?, " +
"MOD_DATE=?, MOD_USER=? " +
"WHERE INST_ID=? AND MESSAGE_CATEGORY=? AND MESSAGE_OBJECT=? AND " +
"MESSAGE_RELEASE=? AND ADDR_TYPE=?";
try {
stmt = conn.prepareStatement(sqlString);
stmt.clearParameters();
stmt.setString(1, a.getStreet1(getAppName()));
stmt.setString(2, a.getStreet2(getAppName()));
stmt.setString(3, a.getStreet3(getAppName()));
stmt.setString(4, a.getCityOrLocality(getAppName()));
stmt.setString(5, a.getStateOrProvince(getAppName()));
stmt.setString(6, a.getZipOrPostalCode(getAppName()));
String sEffDate = "";
if (a.getEffectiveDate().isEmpty() == false) {
sEffDate = a.getEffectiveDate().getMonth() + "/" +
a.getEffectiveDate().getDay() + "/" +
a.getEffectiveDate().getYear();
java.util.Date d = new java.util.Date();
java.text.SimpleDateFormat formatter = new java.text.SimpleDateFormat( "MM/dd/yyyy" );
d = formatter.parse(sEffDate);
stmt.setDate(7, new java.sql.Date(d.getTime()));
}
else {
stmt.setDate(7, null);
}
stmt.setTimestamp(8, new java.sql.Timestamp(System.currentTimeMillis()));
stmt.setString(9, conn.getMetaData().getUserName());
stmt.setString(10, instId);
stmt.setString(11, msgCategory);
stmt.setString(12, msgObject);
stmt.setString(13, msgRelease);
stmt.setString(14, a.getType(getAppName()));
logger.info("Attempting to update Address record " + a.toString() + " for InstitutionalId: " + instId);
int rc = stmt.executeUpdate();
logger.info("Updated Address record " + a.toString() + " for InstitutionalId: " + instId + " rc=" + rc);
stmt.close();
}
catch (Exception e) {
if (stmt != null) {
stmt.close();
}
logger.fatal(e.getMessage(), e);
throw new SQLException(e.getMessage());
}
}
/**
* Creates a single Address row in the T_ADDRESS table. Uses the msgCategory,
* msgObject, msgRelease and instId parameters passed in as well as the Address type associated
* to the Address object passed in as the data to create.
* <P>
* @param conn a pre-established database connection. Since an Address is only ever
* created as part of a larger transaction (BasicPerson-Create or Update) this
* insert must occur within that same transaction, therefore, this method does not
* commit the transaction.
* @param msgCategory the 'messageCategory' attribute extracted from the
* ControlAreaRequest of the enterprise message. Example: 'com.any-erp-vendor.Person'.
* @param msgObject the 'messageObject' attribute extracted from the
* ControlAreaRequest of the enterprise message. Example: 'BasicPerson'.
* @param msgRelease the 'messageRelease' attribute extracted from the
* ControlAreaRequest of the enterprise message. Example: '1.1'.
* @param instId associated to the person we're creating an address for.
* @param a the Address Java object that was pulled from the BasicPerson object that was
* built from the enterprise message passed.
* @throws SQLException if errors occur creating the Address in the database.
**/
protected void createAddress(java.sql.Connection conn, String msgCategory, String msgObject, String msgRelease, String instId, Address a) throws SQLException {
PreparedStatement insertStmt = null;
String insertString = "INSERT INTO T_ADDRESS (INST_ID, MESSAGE_CATEGORY, " +
"MESSAGE_OBJECT, MESSAGE_RELEASE, ADDR_TYPE, STREET1, " +
"STREET2, STREET3, CITY, STATE_CODE, ZIP_CODE, EFFECTIVE_DATE, " +
"CREATE_DATE, CREATE_USER, MOD_DATE, MOD_USER) " +
"VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)";
try {
insertStmt = conn.prepareStatement(insertString);
insertStmt.clearParameters();
insertStmt.setString(1, instId);
insertStmt.setString(2, msgCategory);
insertStmt.setString(3, msgObject);
insertStmt.setString(4, msgRelease);
insertStmt.setString(5, a.getType(getAppName()));
insertStmt.setString(6, a.getStreet1(getAppName()));
insertStmt.setString(7, a.getStreet2(getAppName()));
insertStmt.setString(8, a.getStreet3(getAppName()));
insertStmt.setString(9, a.getCityOrLocality(getAppName()));
insertStmt.setString(10, a.getStateOrProvince(getAppName()));
insertStmt.setString(11, a.getZipOrPostalCode(getAppName()));
String sEffDate = "";
if (a.getEffectiveDate().isEmpty() == false) {
sEffDate = a.getEffectiveDate().getMonth() + "/" +
a.getEffectiveDate().getDay() + "/" +
a.getEffectiveDate().getYear();
java.util.Date d = new java.util.Date();
java.text.SimpleDateFormat formatter = new java.text.SimpleDateFormat( "MM/dd/yyyy" );
d = formatter.parse(sEffDate);
insertStmt.setDate(12, new java.sql.Date(d.getTime()));
}
else {
insertStmt.setDate(12, null);
}
insertStmt.setTimestamp(13, new java.sql.Timestamp(System.currentTimeMillis()));
insertStmt.setString(14, conn.getMetaData().getUserName());
insertStmt.setTimestamp(15, new java.sql.Timestamp(System.currentTimeMillis()));
insertStmt.setString(16, conn.getMetaData().getUserName());
logger.info("Attempting to insert Address record " + a.toString() + " for InstitutionalId: " + instId);
int insertRc = insertStmt.executeUpdate();
logger.info("Inserted Address record " + a.toString() + " for InstitutionalId: " + instId);
insertStmt.close();
}
catch (Exception e) {
if (insertStmt != null) {
insertStmt.close();
}
logger.fatal(e.getMessage(), e);
throw new SQLException(e.getMessage());
}
}
/**
* Deletes a single Phone row from the T_PHONE table. Uses the msgCategory,
* msgObject, msgRelease and instId parameters passed in as well as the Phone type associated
* to the Phone object passed in as the delete criteria.
* <P>
* @param conn a pre-established database connection. Since an Address is only ever
* deleted as part of a larger transaction (BasicPerson-Delete or Update) this
* delete must occur within that same transaction, therefore, this method does not
* commit the transaction.
* @param msgCategory the 'messageCategory' attribute extracted from the
* ControlAreaRequest of the enterprise message. Example: 'com.any-erp-vendor.Person'.
* @param msgObject the 'messageObject' attribute extracted from the
* ControlAreaRequest of the enterprise message. Example: 'BasicPerson'.
* @param msgRelease the 'messageRelease' attribute extracted from the
* ControlAreaRequest of the enterprise message. Example: '1.1'.
* @param instId associated to the person we're deleting an address for.
* @param p the Phone Java object that was pulled from the BasicPerson object that was
* built from the enterprise message passed.
* @throws SQLException if errors occur deleting the Address from the database.
**/
protected void deletePhone(java.sql.Connection conn, String msgCategory, String msgObject, String msgRelease, String instId, Phone p) throws SQLException {
PreparedStatement stmt = null;
String sqlString = "delete from T_PHONE " +
"where inst_id=? and MESSAGE_CATEGORY=? AND " +
"MESSAGE_OBJECT=? AND MESSAGE_RELEASE=? AND " +
"PHONE_TYPE=?";
try {
// delete the individual address record passed in
stmt = conn.prepareStatement(sqlString);
stmt.clearParameters();
stmt.setString(1, instId);
stmt.setString(2, msgCategory);
stmt.setString(3, msgObject);
stmt.setString(4, msgRelease);
stmt.setString(5, p.getType(getAppName()));
logger.info("Attempting to delete Phone record " + p.toString() + " for InstitutionalId: " + instId);
int rc = stmt.executeUpdate();
logger.info("Deleted Phone record " + p.toString() + " for InstitutionalId: " + instId + " rc=" + rc);
stmt.close();
}
catch (Exception e) {
conn.rollback();
if (stmt != null) {
stmt.close();
}
logger.fatal(e.getMessage(), e);
throw new SQLException(e.getMessage());
}
}
/**
* Updates a single Phone row from the T_ADDRESS table. Uses the msgCategory,
* msgObject, msgRelease and instId parameters passed in as well as the Phone type associated
* to the Phone object passed in as the update criteria.
* <P>
* @param conn a pre-established database connection. Since an Phone is only ever
* updated as part of a larger transaction (BasicPerson-Update) this
* update must occur within that same transaction, therefore, this method does not
* commit the transaction.
* @param msgCategory the 'messageCategory' attribute extracted from the
* ControlAreaRequest of the enterprise message. Example: 'com.any-erp-vendor.Person'.
* @param msgObject the 'messageObject' attribute extracted from the
* ControlAreaRequest of the enterprise message. Example: 'BasicPerson'.
* @param msgRelease the 'messageRelease' attribute extracted from the
* ControlAreaRequest of the enterprise message. Example: '1.1'.
* @param instId associated to the person we're updating an address for.
* @param p the Phone Java object that was pulled from the BasicPerson object that was
* built from the enterprise message passed in.
* @throws SQLException if errors occur updating the Phone from the database.
**/
protected void updatePhone(java.sql.Connection conn, String msgCategory, String msgObject, String msgRelease, String instId, Phone p) throws SQLException {
PreparedStatement stmt = null;
String sqlString = "UPDATE T_PHONE SET PHONE_AREA=?, " +
"PHONE_NUMBER=?, MOD_DATE=?, MOD_USER=? " +
"WHERE INST_ID=? AND MESSAGE_CATEGORY=? AND " +
"MESSAGE_OBJECT=? AND MESSAGE_RELEASE=? AND PHONE_TYPE=?";
try {
stmt = conn.prepareStatement(sqlString);
stmt.clearParameters();
stmt.setString(1, p.getPhoneArea());
stmt.setString(2, p.getPhoneNumber());
stmt.setTimestamp(3, new java.sql.Timestamp(System.currentTimeMillis()));
stmt.setString(4, conn.getMetaData().getUserName());
stmt.setString(5, instId);
stmt.setString(6, msgCategory);
stmt.setString(7, msgObject);
stmt.setString(8, msgRelease);
stmt.setString(9, p.getType(getAppName()));
logger.info("Attempting to update Phone record " + p.toString() + " for InstitutionalId: " + instId);
int rc = stmt.executeUpdate();
logger.info("Updated Phone record " + p.toString() + " for InstitutionalId: " + instId + " rc=" + rc);
stmt.close();
}
catch (Exception e) {
if (stmt != null) {
stmt.close();
}
logger.fatal(e.getMessage(), e);
throw new SQLException(e.getMessage());
}
}
/**
* Creates a single Phone row in the T_PHONE table. Uses the msgCategory,
* msgObject, msgRelease and instId parameters passed in as well as the Phone type associated
* to the Phone object passed in as the data to create.
* <P>
* @param conn a pre-established database connection. Since a Phone is only ever
* created as part of a larger transaction (BasicPerson-Create or Update) this
* insert must occur within that same transaction, therefore, this method does not
* commit the transaction.
* @param msgCategory the 'messageCategory' attribute extracted from the
* ControlAreaRequest of the enterprise message. Example: 'com.any-erp-vendor.Person'.
* @param msgObject the 'messageObject' attribute extracted from the
* ControlAreaRequest of the enterprise message. Example: 'BasicPerson'.
* @param msgRelease the 'messageRelease' attribute extracted from the
* ControlAreaRequest of the enterprise message. Example: '1.1'.
* @param instId associated to the person we're creating an address for.
* @param p the Phone Java object that was pulled from the BasicPerson object that was
* built from the enterprise message passed.
* @throws SQLException if errors occur creating the Phone in the database.
**/
protected void createPhone(java.sql.Connection conn, String msgCategory, String msgObject, String msgRelease, String instId, Phone p) throws SQLException {
PreparedStatement insertStmt = null;
String insertString = "INSERT INTO T_PHONE (INST_ID, MESSAGE_CATEGORY, " +
"MESSAGE_OBJECT, MESSAGE_RELEASE, PHONE_TYPE, PHONE_AREA, " +
"PHONE_NUMBER, " +
"CREATE_DATE, CREATE_USER, MOD_DATE, MOD_USER) " +
"VALUES (?,?,?,?,?,?,?,?,?,?,?)";
try {
insertStmt = conn.prepareStatement(insertString);
insertStmt.clearParameters();
insertStmt.setString(1, instId);
insertStmt.setString(2, msgCategory);
insertStmt.setString(3, msgObject);
insertStmt.setString(4, msgRelease);
insertStmt.setString(5, p.getType(getAppName()));
insertStmt.setString(6, p.getPhoneArea());
insertStmt.setString(7, p.getPhoneNumber());
insertStmt.setTimestamp(8, new java.sql.Timestamp(System.currentTimeMillis()));
insertStmt.setString(9, conn.getMetaData().getUserName());
insertStmt.setTimestamp(10, new java.sql.Timestamp(System.currentTimeMillis()));
insertStmt.setString(11, conn.getMetaData().getUserName());
logger.info("Attempting to insert Phone record " + p.toString() + " for InstitutionalId: " + instId);
int insertRc = insertStmt.executeUpdate();
logger.info("Inserted Phone record " + p.toString() + " for InstitutionalId: " + instId);
insertStmt.close();
}
catch (Exception e) {
if (insertStmt != null) {
insertStmt.close();
}
logger.fatal(e.getMessage(), e);
throw new SQLException(e.getMessage());
}
}
final private ArrayList logErrors(String errNumber, String errMessage, Throwable e, Document inDoc) {
logger.fatal(errMessage, e);
logger.fatal("Message sent in is: \n" + getMessageBody(inDoc));
ArrayList errors = new ArrayList();
errors.add(buildError("application", errNumber, errMessage));
return errors;
}
final private ArrayList logErrors(String errNumber, String errMessage, Document inDoc) {
logger.fatal(errMessage);
logger.fatal("Message sent in is: \n" + getMessageBody(inDoc));
ArrayList errors = new ArrayList();
errors.add(buildError("application", errNumber, errMessage));
return errors;
}
}