PatientSessionEJB.ejb
001 package com.bea.medrec.controller;
002 
003 import com.bea.medrec.entities.AddressLocal;
004 import com.bea.medrec.entities.PatientLocal;
005 import com.bea.medrec.entities.PatientLocalHome;
006 import com.bea.medrec.exceptions.DuplicateAccountException;
007 import com.bea.medrec.utils.JNDINames;
008 import com.bea.medrec.utils.MedRecConstants;
009 import com.bea.medrec.utils.MedRecLog4jFactory;
010 import com.bea.medrec.utils.MedRecUtils;
011 import com.bea.medrec.value.Address;
012 import com.bea.medrec.value.Patient;
013 import com.bea.medrec.value.Registration;
014 import com.bea.medrec.value.User;
015 import java.rmi.RemoteException;
016 import java.sql.Connection;
017 import java.sql.Date;
018 import java.util.ArrayList;
019 import java.util.Calendar;
020 import java.util.GregorianCalendar;
021 import java.util.List;
022 import javax.ejb.EJBException;
023 import javax.ejb.FinderException;
024 import javax.ejb.SessionContext;
025 import javax.naming.NamingException;
026 import org.apache.log4j.Logger;
027 import weblogic.ejb.GenericSessionBean;
028 import weblogic.ejbgen.*;
029 import weblogic.jdbc.rowset.RowSetFactory;
030 import weblogic.jdbc.rowset.WLCachedRowSet;
031 
032 /**
033  <p>Session facade for all MedRec patient functionality.</p>
034  *
035  @author Copyright (c) 2006 by BEA Systems. All Rights Reserved.
036  */
037 @EjbLocalRefs({
038     @EjbLocalRef(name = "ejb/local/address",
039                  home = "com.bea.medrec.entities.AddressLocalHome",
040                  local = "com.bea.medrec.entities.AddressLocal",
041                  type = Constants.RefType.ENTITY,
042                  link = "AddressEJB"),
043     @EjbLocalRef(name = "ejb/local/group",
044                  home = "com.bea.medrec.entities.GroupLocalHome",
045                  local = "com.bea.medrec.entities.GroupLocal",
046                  type = Constants.RefType.ENTITY,
047                  link = "GroupEJB"),
048     @EjbLocalRef(name = "ejb/local/patient",
049                  home = "com.bea.medrec.entities.PatientLocalHome",
050                  local = "com.bea.medrec.entities.PatientLocal",
051                  type = Constants.RefType.ENTITY,
052                  link = "PatientEJB"),
053     @EjbLocalRef(name = "ejb/local/user",
054                  home = "com.bea.medrec.entities.UserLocalHome",
055                  local = "com.bea.medrec.entities.UserLocal",
056                  type = Constants.RefType.ENTITY,
057                  link = "UserEJB")
058 })
059 @FileGeneration(remoteClass = Constants.Bool.TRUE,
060                 remoteHome = Constants.Bool.TRUE)
061 @JndiName(remote = "PatientSessionEJB.PatientSessionHome")
062 @ResourceRefs({
063     @ResourceRef(name = "jms/MedRecQueueConnectionFactory",
064                  type = "javax.jms.QueueConnectionFactory",
065                  auth = ResourceRef.Auth.APPLICATION,
066                  sharingScope = ResourceRef.SharingScope.SHAREABLE,
067                  jndiName = "jms/MedRecQueueConnectionFactory"),
068     @ResourceRef(name = "jdbc/MedRecTxDataSource",
069                  type = "javax.sql.DataSource",
070                  auth = ResourceRef.Auth.APPLICATION,
071                  jndiName = "jdbc/MedRecTxDataSource")
072 })
073 @Session(maxBeansInFreePool = "1000",
074          initialBeansInFreePool = "0",
075          transTimeoutSeconds = "0",
076          type = Session.SessionType.STATELESS,
077          defaultTransaction = Constants.TransactionAttribute.REQUIRED,
078          enableCallByReference = Constants.Bool.TRUE,
079          ejbName = "PatientSessionEJB")
080 
081 public class PatientSessionEJB extends GenericSessionBean {
082   private static Logger logger =
083     MedRecLog4jFactory.getLogger(PatientSessionEJB.class.getName());
084 
085   // Member variables
086   private SessionContext ctx;
087   private AdminSession adminSession;
088   private PatientLocalHome patientHome;
089 
090  /**
091  <p>Sets the session context.  Get handles for all
092  * session and entity and JMS connections used throughout
093  * this session bean.</p>
094  *
095  @param ctx SessionContext Context for session
096  */
097   public void setSessionContext(SessionContext ctx) {
098     this.ctx = ctx;
099     try {
100       // Session bean homes.
101       adminSession = JNDILookupUtils.getAdminSession();
102       // Entity bean homes.
103       patientHome = JNDILookupUtils.getPatientLocalHome();
104     catch (NamingException ne) {
105       throw new EJBException(ne);
106     }
107   }
108 
109   //   P U B L I C   M E T H O D S
110 
111   //  F I N D   P A T I E N T   B Y   E M A I L
112  /**
113  <p/>Finds MedRec patient by email.</p>
114  *
115  @param pEmail Patient email
116  @return Patient  Patient value object.
117  @throws NamingException
118  @throws RemoteException
119  @throws Exception
120  */
121   @RemoteMethod()
122   public Patient findPatientByEmail(String pEmail)
123       throws NamingException, RemoteException, Exception {
124     logger.debug("Email: "+pEmail);
125 
126     // Declare local variables.
127     PatientLocal patientLocal = null;
128     Patient patientVO = null;
129     try {
130       patientLocal = patientHome.findByEmail(pEmail);
131       patientVO = patientLocal.getPatient();
132       logger.debug(patientVO.toString());
133     catch (FinderException fe) {
134       logger.warn(fe.getClass().getName()+" - "+fe.getMessage());
135     }
136     return patientVO;
137   }
138 
139   //  F I N D   P A T I E N T   B Y   I D
140   /**
141  <p>Find Patient by id.</p>
142  *
143  @param pPatientId Patient Id
144  @return Patient  Patient value object.
145  @throws NamingException
146  @throws RemoteException
147  @throws Exception
148  */
149   @RemoteMethod()
150   public Patient findPatientById(Integer pPatientId)
151       throws NamingException, RemoteException, Exception {
152   // Declare local variables.
153     PatientLocal patientLocal = null;
154     Patient patientVO = null;
155     try {
156       patientLocal = patientHome.findByPrimaryKey(pPatientId);
157       patientVO = patientLocal.getPatient();
158     catch (FinderException fe) {
159       logger.warn(fe.getClass().getName()+" - "+fe.getMessage());
160     }
161     return patientVO;
162   }
163 
164     //  F I N D   P A T I E N T   B Y   L A S T N A M E   W I L D
165   /**
166  <p/>
167  * Find patient by last name.  Wild card search- %lastName%.
168  </p>
169  *
170  @param pLastName Last name substring
171  @return Patient[] Array of Patient value objects.
172  @throws NamingException
173  @throws RemoteException
174  @throws Exception
175  */
176   @RemoteMethod()
177   public Patient[] findPatientByLastNameWild(String pLastName)
178       throws NamingException, RemoteException, Exception {
179     logger.info("Finding patient by wildcard last name.");
180     logger.debug("Patient last name: "+pLastName);
181 
182     // Declare local variables.
183     List<Object> patientList = new ArrayList<Object>();
184     String sql = "SELECT "+
185         "p.id as patientId, "+
186         "p.address_id , "+
187         "p.first_name as firstName, "+
188         "p.middle_name as middleName, "+
189         "p.last_name as lastName, "+
190         "p.dob as dateOfBirth, "+
191         "p.ssn as ssn, "+
192         "p.email as email, "+
193         "p.gender as gender, "+
194         "p.phone as phone, "+
195         "a.id as addressId, "+
196         "a.city as city, "+
197         "a.country as country, "+
198         "a.state as state, "+
199         "a.street1 as streetName1, "+
200         "a.street2 as streetName2, "+
201         "a.zip as zipCode "+
202         "FROM patient p LEFT OUTER JOIN address a ON p.address_id = a.id "+
203         "WHERE ( ( UPPER( p.last_name ) LIKE UPPER( '%"+
204         pLastName+
205         "%' ) ) ) "+
206         "ORDER BY p.last_name";
207     try {
208       logger.debug(sql);
209       WLCachedRowSet rs = RowSetFactory.newInstance().newCachedRowSet();
210       rs.setCommand(sql);
211       rs.setDataSourceName(JNDINames.CATALOG_HOME+JNDINames.MEDREC_TX_DATASOURCE);
212       rs.setTransactionIsolation(Connection.TRANSACTION_READ_COMMITTED);
213       rs.execute();
214       rs.beforeFirst();
215       while (rs.next()) {
216         Address addrVO = new Address();
217         addrVO.setId(rs.getInt("addressId"));
218         addrVO.setStreetName1(rs.getString("streetName1"));
219         addrVO.setStreetName2(rs.getString("streetName2"));
220         addrVO.setCity(rs.getString("city"));
221         addrVO.setState(rs.getString("state"));
222         addrVO.setZipCode(rs.getString("zipCode"));
223         addrVO.setCountry(rs.getString("country"));
224         Patient patientVO = new Patient();
225         patientVO.setId(rs.getInt("patientId"));
226         patientVO.setFirstName(rs.getString("firstName"));
227         patientVO.setMiddleName(rs.getString("middleName"));
228         patientVO.setLastName(rs.getString("lastName"));
229         patientVO.setGender(rs.getString("gender"));
230         Calendar cal = GregorianCalendar.getInstance();
231         cal.setTime(rs.getDate("dateOfBirth"));
232         patientVO.setDateOfBirth(cal);
233         patientVO.setEmail(rs.getString("email"));
234         patientVO.setPhone(rs.getString("phone"));
235         patientVO.setSsn(rs.getString("ssn"));
236         patientVO.setAddress(addrVO);
237         patientList.add(patientVO);
238       }
239       logger.debug("Num of patients found: "+
240           patientList.size());
241     catch (Exception ex) {
242       logger.error(ex);
243       throw new EJBException(ex);
244     }
245     return (Patient[]) patientList.toArray(new Patient[0]);
246   }
247 
248   //  F I N D   P A T I E N T   B Y   S S N
249   /**
250   <p/>
251   * Finds MedRec patient by social security number.
252   </p>
253   *
254   @param pSsn Patient SSN
255   @return Patient  Patient value object.
256   @throws NamingException
257   @throws RemoteException
258   @throws Exception
259   */
260   @RemoteMethod()
261   public Patient findPatientBySsn(String pSsn)
262       throws NamingException, RemoteException, Exception {
263       logger.debug("Paient SSN: "+pSsn);
264 
265     // Declare local variables.
266     PatientLocal patientLocal = null;
267     Patient patientVO = null;
268     try {
269       patientLocal = patientHome.findBySsn(pSsn);
270       patientVO = patientLocal.getPatient();
271       logger.debug(patientVO.toString());
272     catch (FinderException fe) {
273       logger.warn(fe.getClass().getName()+" - "+fe.getMessage());
274     }
275     return patientVO;
276   }
277 
278   //  P R O C E S S   A C T I V E   R E G I S T R A T I O N
279   /**
280   <p>Registers new patient account assigning status to ACTIVE.
281   * This registration process is used to bypass administration
282   * workflow which approves/denys new patient accounts.
283   <p/>
284   * Typically this functionality is used by "affiliated" organizations
285   * who register new patients thru MedRec's web services features.  These
286   * organizations are trusted; therefore, no adminstration approval is needed.</p>
287   *
288   @param pPatient Patient value objects.
289   @return Patient
290   @throws NamingException
291   @throws RemoteException
292   @throws Exception
293   */
294   @RemoteMethod()
295   public Patient processActiveRegistration(Patient pPatient, String pPassword)
296       throws NamingException, RemoteException, Exception {
297     // Declare local variables.
298     Registration regVO = null;
299     User userVO = null;
300     regVO = new Registration();
301     regVO.setPatient(pPatient);
302     userVO = new User();
303     userVO.setUsername(pPatient.getEmail());
304     userVO.setPassword(pPassword);
305     userVO.setStatus(MedRecConstants.USER_ACTIVE);
306     regVO.setUser(userVO);
307     // Call process registration worker.
308     return processRegistration(regVO);
309   }
310 
311   //    P R O C E S S   N E W   R E G I S T R A T I O N
312   /**
313   <p>Registers new patient account assign status to NEW.
314   * Typically this functionality is used by online registrants that must
315   * go through a MedRec adminstration approval process.</p>
316   *
317   @param pReg Patient value objects.
318   */
319   @RemoteMethod()
320       public void processNewRegistration(Registration pReg) {
321     try {
322       // Assign account status to NEW.
323       pReg.getUser().setStatus(MedRecConstants.USER_NEW);
324       processRegistration(pReg);
325     catch (DuplicateAccountException dupe) {
326       logger.error("Unable to register the following user: \n"+
327           pReg.toString()+" due to "+dupe.getMessage());
328       // Send mail to notifying user of existing registration.
329     catch (Throwable th) {
330       logger.error("Unable to register the following user: \n"+
331           pReg.toString()+" due to "+th.getMessage());
332       // Send registration to MedRec admintration for manual processing.
333     }
334   }
335 
336 //   P R O C E S S   R E G I S T R A T I O N
337   /**
338   <p>Main patient registration process method.  This method creates a
339   * login account, assigns patient designated groups, and stores
340   * pertinent patient data such as name, dob, ssn, etc.
341   * This method acts as the worker to different types of registration.</p>
342   *
343   @param registration Registration value objects.
344   @return Patient
345   @throws NamingException
346   @throws RemoteException
347   @throws Exception
348   */
349   @RemoteMethod()
350   public Patient processRegistration(Registration registrationthrows Exception {
351     logger.debug("Registering Patient: "+
352         registration.getPatient().toStringLite());
353 
354     // Declare local variables.
355     User userVO = null;
356     Patient patientVO = null;
357     Integer patientId = null;
358 
359     // Get user and patient objects.
360     userVO = registration.getUser();
361     patientVO = registration.getPatient();
362 
363     // Create user, groups and patient information.
364     patientId = adminSession.createPatientAccount(userVO, patientVO);
365     logger.debug("Registration successful.");
366     logger.debug("Retrieving new patient.");
367     return findPatientById(patientId);
368   }
369 
370 //  U P D A T E   P A T I E N T
371   /**
372   <p/>
373   * Updates a patient by calling the appropriate entity beans.
374   </p>
375   *
376   @param pPatient Patient value objects.
377   @return Patient
378   @throws NamingException
379   @throws RemoteException
380   @throws Exception
381   */
382   @RemoteMethod()
383   public Patient updatePatient(Patient pPatient)
384       throws NamingException, RemoteException, Exception {
385       logger.debug("Updating Patient: "+pPatient.toString());
386 
387     // Declare local variables.
388     PatientLocal selectedPatient = null;
389     AddressLocal selectedAddress = null;
390     Address addressVO = null;
391     try {
392       selectedPatient = patientHome.findByPrimaryKey(pPatient.getId());
393 
394       // Patient info
395       selectedPatient.setFirstName(pPatient.getFirstName());
396       selectedPatient.setMiddleName(pPatient.getMiddleName());
397       selectedPatient.setLastName(pPatient.getLastName());
398       Date date = MedRecUtils.getDate(pPatient.getDateOfBirth());
399       selectedPatient.setDateOfBirth(date);
400       selectedPatient.setGender(pPatient.getGender());
401       selectedPatient.setSsn(pPatient.getSsn());
402       selectedPatient.setPhone(pPatient.getPhone());
403 
404       // Address info
405       selectedAddress = selectedPatient.getAddress();
406       addressVO = pPatient.getAddress();
407       selectedAddress.setStreetName1(addressVO.getStreetName1());
408       selectedAddress.setStreetName2(addressVO.getStreetName2());
409       selectedAddress.setCity(addressVO.getCity());
410       selectedAddress.setState(addressVO.getState());
411       selectedAddress.setZipCode(addressVO.getZipCode());
412       selectedAddress.setCountry(addressVO.getCountry());
413     catch (Exception e) {
414       logger.error(e);
415       throw new EJBException(e);
416     }
417     return selectedPatient.getPatient();
418   }
419 }