AdminSessionEJB.ejb
001 package com.bea.medrec.controller;
002 
003 import com.bea.medrec.entities.*;
004 import com.bea.medrec.exceptions.DuplicateAccountException;
005 import com.bea.medrec.exceptions.MedRecException;
006 import com.bea.medrec.utils.ErrorConstants;
007 import com.bea.medrec.utils.MedRecConstants;
008 import com.bea.medrec.utils.MedRecLog4jFactory;
009 import com.bea.medrec.utils.MedRecUtils;
010 import com.bea.medrec.value.*;
011 import java.rmi.RemoteException;
012 import java.util.ArrayList;
013 import java.util.Collection;
014 import java.util.Iterator;
015 import java.util.List;
016 import javax.ejb.*;
017 import javax.jms.*;
018 import javax.naming.NamingException;
019 import org.apache.log4j.Logger;
020 import weblogic.ejb.GenericSessionBean;
021 import weblogic.ejbgen.*;
022 import weblogic.ejbgen.Session;
023 
024 /**
025  <p>Session facade for all MedRec adminstrator functionality.</p>
026  *
027  @author Copyright (c) 2006 by BEA Systems. All Rights Reserved.
028  */
029 @EjbLocalRefs({
030     @EjbLocalRef(name = "ejb/local/group",
031                  home = "com.bea.medrec.entities.GroupLocalHome",
032                  local = "com.bea.medrec.entities.GroupLocal",
033                  type = Constants.RefType.ENTITY,
034                  link = "GroupEJB"),
035     @EjbLocalRef(name = "ejb/local/patient",
036                  home = "com.bea.medrec.entities.PatientLocalHome",
037                  local = "com.bea.medrec.entities.PatientLocal",
038                  type = Constants.RefType.ENTITY,
039                  link = "PatientEJB"),
040     @EjbLocalRef(name = "ejb/local/prescription",
041                  home = "com.bea.medrec.entities.PrescriptionLocalHome",
042                  local = "com.bea.medrec.entities.PrescriptionLocal",
043                  type = Constants.RefType.ENTITY,
044                  link = "PrescriptionEJB"),
045     @EjbLocalRef(name = "ejb/local/record",
046                  home = "com.bea.medrec.entities.RecordLocalHome",
047                  local = "com.bea.medrec.entities.RecordLocal",
048                  type = Constants.RefType.ENTITY,
049                  link = "RecordEJB"),
050     @EjbLocalRef(name = "ejb/local/user",
051                  home = "com.bea.medrec.entities.UserLocalHome",
052                  local = "com.bea.medrec.entities.UserLocal",
053                  type = Constants.RefType.ENTITY,
054                  link = "UserEJB")
055 })
056 @FileGeneration(remoteClass = Constants.Bool.TRUE,
057                 remoteHome = Constants.Bool.TRUE)
058 @JndiName(remote = "AdminSessionEJB.AdminSessionHome")
059 @ResourceRefs({
060     @ResourceRef(name = "jms/MedRecQueueConnectionFactory",
061                  type = "javax.jms.QueueConnectionFactory",
062                  auth = ResourceRef.Auth.APPLICATION,
063                  sharingScope = ResourceRef.SharingScope.SHAREABLE,
064                  jndiName = "jms/MedRecQueueConnectionFactory")
065 })
066 @ResourceEnvRefs({
067     @ResourceEnvRef(name = "jms/REGISTRATION_MDB_QUEUE",
068                     type = "javax.jms.Queue",
069                     jndiName = "jms/REGISTRATION_MDB_QUEUE"),
070     @ResourceEnvRef(name = "jms/XML_UPLOAD_MDB_QUEUE",
071                     type = "javax.jms.Queue",
072                     jndiName = "jms/XML_UPLOAD_MDB_QUEUE")
073 })
074 @Session(maxBeansInFreePool = "1000",
075          initialBeansInFreePool = "0",
076          transTimeoutSeconds = "0",
077          type = Session.SessionType.STATELESS,
078          defaultTransaction = Constants.TransactionAttribute.REQUIRED,
079          enableCallByReference = Constants.Bool.TRUE,
080          ejbName = "AdminSessionEJB")
081 
082 public class AdminSessionEJB extends GenericSessionBean {
083   private static Logger logger =
084     MedRecLog4jFactory.getLogger(AdminSessionEJB.class.getName());
085 
086 // Member variables
087   private SessionContext ctx;
088   private GroupLocalHome groupHome;
089   private MailSession mailSession;
090   private PatientLocalHome patientHome;
091   private PrescriptionLocalHome prescriptionHome;
092   private RecordLocalHome recordHome;
093   private UserLocalHome userHome;
094   private QueueConnectionFactory qcFactory;
095   private QueueSession qSession;
096   private QueueConnection qConnection;
097   private QueueSender qSender;
098   private Queue queReg;
099   private Queue queXml;
100 
101   /**
102   <p>Sets the session context.  Get handles for all
103   * session and entity and JMS connections used throughout
104   * this session bean.</p>
105   *
106   @param ctx  SessionContext Context for session
107   */
108   public void setSessionContext(SessionContext ctx) {
109     this.ctx = ctx;
110     try {
111       // Session bean homes.
112       mailSession = JNDILookupUtils.getMailSession();
113       // Entity bean homes.
114       groupHome = JNDILookupUtils.getGroupLocalHome();
115       patientHome = JNDILookupUtils.getPatientLocalHome();
116       recordHome = JNDILookupUtils.getRecordLocalHome();
117       prescriptionHome = JNDILookupUtils.getPrescriptionLocalHome();
118       userHome = JNDILookupUtils.getUserLocalHome();
119       // JMS connections and queues.
120       queReg = JNDILookupUtils.getRegQueue();
121       queXml = JNDILookupUtils.getXMLQueue();
122       qcFactory = JNDILookupUtils.getQCFactory();
123       qConnection = qcFactory.createQueueConnection();
124       qSession = qConnection.createQueueSession(false, 0);
125       qConnection.start();
126     catch (JMSException jmse) {
127       throw new EJBException(jmse);
128     catch (NamingException ne) {
129       throw new EJBException(ne);
130     }
131   }
132 
133     //  A C T I V A T E   A C C O U N T   S T A T U S
134   /**
135   <p>Activates a patients account for general access. A email notification
136   * is sent to the patients.</p>
137   *
138   @param pUsername    Username of account to be approved.
139   @exception MedRecException
140   @exception Exception
141   */
142   @RemoteMethod()
143   public void activateAccountStatus(String pUsername, Mail pMail)
144       throws MedRecException, Exception {
145     // Declare local variables.
146     User user = null;
147 
148     // Update account status. Set status to active.
149     updateAccountStatus(pUsername, MedRecConstants.USER_ACTIVE);
150 
151     // Set from email.
152     pMail.setFrom(MedRecConstants.MEDREC_CUSTOMER_SUPPORT);
153 
154     // Get password to be displayed in email.
155     user = getUserByUsername(pUsername);
156 
157     // Provide substituted message values.
158     Object[] arguments = {pMail.getTo(), user.getPassword()};
159 
160     // Send mail object to be processed.
161     mailSession.composeAndSendMail(pMail, arguments);
162   }
163 
164     //  A D D   P A T I E N T
165   /**
166   <p>Presists a new patient if patient does not already exist.</p>
167   *
168   @param pPatient    Patient value objects.
169   @return Integer
170   @exception NamingException
171   @exception RemoteException
172   @exception Exception
173   */
174   public Integer addPatient(Patient pPatient, UserLocal userLocal)
175       throws NamingException, RemoteException, Exception {
176     logger.debug("Add Patient: " +
177         pPatient.toString());
178 
179     // Declare local variables.
180     Integer patId = null;
181     PatientLocal patientLocal = null;
182     try {
183       // Check to see if user already exists.  Is so, return id.
184       patientLocal = patientHome.findByEmail(pPatient.getEmail());
185       patId = patientLocal.getId();
186       logger.debug("Patient exists, id: " +
187           patId);
188     catch (FinderException fe) {
189       logger.debug("Patient not found. Creating new patient.");
190       patientLocal = patientHome.create(pPatient.getFirstName(),
191           pPatient.getMiddleName(), pPatient.getLastName(),
192           pPatient.getDateOfBirth(), pPatient.getGender(),
193           pPatient.getSsn(), pPatient.getPhone(), pPatient.getEmail(),
194           pPatient.getAddress(), userLocal);
195       patId = patientLocal.getId();
196     }
197     return patId;
198   }
199 
200     //  A D D   R E C O R D
201   /**
202   <p>Presists a new record.</p>
203   *
204   @param pRecord    Patient value objects.
205   @return RecordLocal
206   @exception NamingException
207   @exception RemoteException
208   @exception Exception
209   */
210   public RecordLocal addRecord(Record pRecord)
211       throws NamingException, RemoteException, Exception {
212     logger.debug("Add Record: "+pRecord.toString());
213     RecordLocal recordLocal = recordHome.create(pRecord.getPatientId(),
214         pRecord.getDate(), pRecord.getSymptoms(), pRecord.getDiagnosis(),
215         pRecord.getNotes(), pRecord.getPhysician(), pRecord.getVitalSigns());
216     return recordLocal;
217   }
218 
219     //  A D D   R X
220   /**
221 <p>Presists a new prescription.</p>
222 *
223 @param pPrescription    Patient value objects.
224 @param pRecord   Record to be inserted.
225 @return Integer
226 @exception NamingException
227 @exception RemoteException
228 @exception Exception
229 */
230   public Integer addPrescription(Prescription pPrescription,
231                                  RecordLocal pRecord)
232       throws NamingException, RemoteException, Exception {
233     logger.debug("Add Prescription: "+pPrescription.toString());
234     // Declare local variables.
235     PrescriptionLocal prescriptionLocal = prescriptionHome.create(
236         pPrescription.getPatientId(), pPrescription.getDatePrescribed(),
237         pPrescription.getDrug(), pPrescription.getDosage(),
238         pPrescription.getFrequency(), pPrescription.getRefillsRemaining(),
239         pPrescription.getInstructions(), pRecord);
240     return prescriptionLocal.getId();
241   }
242 
243     //  A D D   U S E R
244   /**
245   <p>Creates new user account assign a temporary password.
246   * Used by the XML upload feature where passwords are not supplied.</p>
247   *
248   @param pUser    Patient value objects.
249   *
250   @exception NamingException
251   @exception RemoteException
252   @exception DuplicateAccountException
253   @exception Exception
254   */
255   public UserLocal addUser(User pUser)
256       throws NamingException, RemoteException, DuplicateAccountException,
257       Exception {
258     logger.debug("Add: "+pUser.toString());
259     // Declare local variables
260     UserLocal userLocal = null;
261     try {
262     // Check to see if user already exists.  Is so, return id.
263       userLocal = userHome.findByUsername(pUser.getUsername());
264       logger.warn("User " +
265           pUser.getUsername() +
266           " already exists");
267       throw new DuplicateAccountException("User " +
268           pUser.getUsername() +
269           " already exists");
270     catch (FinderException fe) {
271       logger.debug("User not found. Creating new user account.");
272       if (pUser.getPassword() == null)
273         pUser.setPassword(MedRecConstants.TEMP_PASSWORD);
274       pUser.setStatus(MedRecConstants.USER_NEW);
275       userLocal = userHome.create(pUser);
276       return userLocal;
277     }
278   }
279 
280     //  A S S I G N   G R O U P S
281   /**
282   <p>Assigns given groups for a given user.</p>
283   *
284   @param pUsername  Username
285   @param pGroupNames  Group name
286   @exception NamingException
287   @exception RemoteException
288   @exception Exception
289   */
290   @RemoteMethod()
291   public void assignGroups(String pUsername, String[] pGroupNames)
292       throws NamingException, RemoteException, Exception {
293     logger.debug("Assigning groups to user, "+pUsername);
294     for (int i = 0; i < pGroupNames.length; i++) {
295       try {
296         groupHome.create(pGroupNames[i], pUsername);
297       catch (DuplicateKeyException dupe) {
298         logger.debug("User "+pUsername+" already assign to group "+
299             pGroupNames[i]+".");
300       }
301     }
302   }
303 
304    //  A S S I G N   P A T I E N T   G R O U P S
305   /**
306   <p>Assigns given groups for a given user.</p>
307   *
308   @param pUsername  Username
309   @exception NamingException
310   @exception RemoteException
311   @exception Exception
312   */
313   @RemoteMethod()
314   public void assignPatientGroups(String pUsername)
315       throws NamingException, RemoteException, Exception {
316     String[] groupNames = MedRecUtils.getGroupArray(
317         MedRecConstants.PATIENT_GROUP_TYPE);
318     assignGroups(pUsername, groupNames);
319   }
320 
321   //  C R E A T E   P A T I E N T   &   L O G I N
322   /**
323   <p>Create new patient account, login and groups,
324   * and store revelent patient data.</p>
325   *
326   @param pPatient    Patient value objects.
327   @exception RemoteException
328   */
329   @RemoteMethod()
330   public Integer createPatientAccount(User pUser, Patient pPatient)
331       throws NamingException, RemoteException, DuplicateAccountException,
332       Exception {
333     logger.info("Creating new patient account- login and patient data.");
334 
335     // Declare local variables.
336     Integer patId = null;
337     UserLocal userLocal = null;
338 
339     // Add patient to users.  Assign patient groups.
340     userLocal = addUser(pUser);
341 
342     // Assign patient to groups.
343     assignPatientGroups(userLocal.getUsername());
344 
345     // Add patient.
346     patId = addPatient(pPatient, userLocal);
347     return patId;
348   }
349 
350     //  D E N Y   A C C O U N T   S T A T U S
351   /**
352   <p>Deny new user registration.  Sets account status to "DENY".</p>
353   *
354   @param pUsername    Username of account to be denied.
355   @exception MedRecException
356   @exception Exception
357   */
358   @RemoteMethod()
359   public void denyAccountStatus(String pUsername, Mail pMail)
360       throws MedRecException, Exception {
361     updateAccountStatus(pUsername, MedRecConstants.USER_DENIED);
362     pMail.setFrom(MedRecConstants.MEDREC_CUSTOMER_SUPPORT);
363     mailSession.composeAndSendMail(pMail);
364     // REVIEWME perhaps log user to approval list.
365     // mail notification here
366   }
367 
368     //  F I N D   A D M I N   B Y   S T A T U S
369   /**
370 <p>Finds patients by status "NEW".</p>
371 *
372 @return Collection  Collection of patient value objects.
373 @exception NamingException
374 @exception RemoteException
375 @exception Exception
376 */
377   @RemoteMethod()
378   public List findNewUsers()
379       throws NamingException, RemoteException, Exception {
380     List<Patient> patCol = new ArrayList<Patient>();
381     UserLocal userLocal = null;
382     List<UserLocal> userList = (List<UserLocal>userHome.findByStatus(
383         MedRecConstants.USER_NEW);
384     if (userList != null) {
385       Iterator itr = userList.iterator();
386       while (itr.hasNext()) {
387         userLocal = (UserLocalitr.next();
388         patCol.add(userLocal.getPatientObj());
389       }
390     }
391     return patCol;
392   }
393 
394     //  F I N D   P A T I E N T   B Y   I D
395   /**
396   <p>Find Patient by id.</p>
397   *
398   @param pId   Patient Id
399   @return Patient  Patient value object.
400   @exception NamingException
401   @exception RemoteException
402   @exception Exception
403   */
404   @RemoteMethod()
405   public Patient findPatientById(Integer pId)
406       throws NamingException, RemoteException, Exception {
407     // Declare local variables.
408     PatientLocal patientLocal = null;
409     Patient patient = null;
410     try {
411       patientLocal = patientHome.findByPrimaryKey(pId);
412       patient = patientLocal.getPatient();
413     catch (FinderException fe) {
414       logger.warn(fe.getClass().getName()+" - "+fe.getMessage());
415     }
416     return patient;
417   }
418 
419       //  F I N D   P A T I E N T   B Y   E M A I L
420   /**
421   <p>Find Patient by id.</p>
422   *
423   @param pEmail   Patient email
424   @return Patient  Patient value object.
425   @exception NamingException
426   @exception RemoteException
427   @exception Exception
428   */
429   @RemoteMethod()
430   public Patient findPatientByEmail(String pEmail)
431       throws NamingException, RemoteException, Exception {
432     // Declare local variables.
433     PatientLocal patientLocal = null;
434     Patient patient = null;
435     try {
436       patientLocal = patientHome.findByEmail(pEmail);
437       patient = patientLocal.getPatient();
438     catch (FinderException fe) {
439       logger.warn(fe.getClass().getName()+" - "+fe.getMessage());
440     }
441     return patient;
442   }
443 
444       //  F I N D   U S E R
445   /**
446   <p>Creates new user account assign a temporary password.
447   * Used by the XML upload feature where passwords are not supplied.</p>
448   *
449   @param pUsername    Patient value objects.
450   @return User
451   @exception NamingException
452   @exception RemoteException
453   @exception FinderException
454   */
455   @RemoteMethod()
456   public User getUserByUsername(String pUsername)
457       throws NamingException, RemoteException, FinderException {
458     logger.debug("User: "+pUsername);
459 
460     // Declare local values
461     UserLocal userLocal = null;
462 
463     // Find user entity
464     userLocal = userHome.findByUsername(pUsername);
465     return userLocal.getUser();
466   }
467 
468     //   I N S E R T   M E D I C A L   R E C O R D
469   /**
470   <p>Creates new patient account and stores associate records.
471   * Used by the XML upload feature where medical institutions
472   * pass all held record information for a particular patient.</p>
473   *
474   @param pMedRecCol
475   @exception CreateException
476   @exception NamingException
477   @exception RemoteException
478   @exception Exception
479   */
480   @RemoteMethod()
481   public void insertMedicalRecord(Collection pMedRecCol)
482       throws CreateException, NamingException, MedRecException, Exception {
483     logger.info("Insert medical record.");
484 
485     // Declare local variables.
486     Patient patient = null;
487     Integer physId = null;
488     Integer patId = null;
489     Collection<Record> recordCol = null;
490     User user = null;
491     Iterator itr = pMedRecCol.iterator();
492     while (itr.hasNext()) {
493       // Iterator thru medical collection.  Get physician id.
494       MedicalRecord medicalRecord = (MedicalRecorditr.next();
495 
496       // Get patient object.  Set status.
497       // Then create patient and patient login data.
498       patient = medicalRecord.getPatient();
499       user = medicalRecord.getUser();
500       try {
501         patId = createPatientAccount(user, patient);
502       catch (DuplicateAccountException dupe) {
503         logger.info("If user exists, continue processing.");
504         patId = findPatientByEmail(patient.getEmail()).getId();
505       }
506 
507       // Get collection of records to be inserted.
508       recordCol = medicalRecord.getRecords();
509       insertRecord(recordCol, patId);
510     }
511   }
512 
513     //   I N S E R T   R E C O R D
514   /**
515   <p>Iterates through a collection storing records.</p>
516   *
517   @param pMedRecCol
518   @param pPatId
519   @exception CreateException
520   @exception NamingException
521   @exception RemoteException
522   @exception Exception
523   */
524   @RemoteMethod()
525   public void insertRecord(Collection pMedRecCol, Integer pPatId)
526       throws CreateException, NamingException, MedRecException, Exception {
527     logger.info("Insert record.");
528 
529     // Declare local variables.
530     Record record = null;
531     RecordLocal recordLocal = null;
532     Iterator itr = pMedRecCol.iterator();
533     while (itr.hasNext()) {
534       // Iterator thru medical collection.  Get physician id.
535       record = (Recorditr.next();
536       record.setPatientId(pPatId);
537       recordLocal = addRecord(record);
538       insertPrescriptions(record.getPrescriptions(), recordLocal);
539     }
540   }
541 
542       //   I N S E R T   R E C O R D
543   /**
544   <p>Iterates through a collection storing prescriptions.</p>
545   *
546   @param pPrescriptionVOs Array of Prescription value objects
547   @param pRecordLocal Local Record interface
548   @exception CreateException
549   @exception NamingException
550   @exception RemoteException
551   @exception Exception
552   */
553   public void insertPrescriptions(Prescription[] pPrescriptionVOs,
554                                   RecordLocal pRecordLocal)
555       throws CreateException, NamingException, MedRecException, Exception {
556     logger.info("Insert prescriptions.");
557     if (pPrescriptionVOs != null && pPrescriptionVOs.length > 0) {
558       for (int i = 0; i < pPrescriptionVOs.length; i++) {
559         Prescription pPrescriptionVO = pPrescriptionVOs[i];
560         pPrescriptionVO.setRecordId(pRecordLocal.getId());
561         pPrescriptionVO.setPatientId(pRecordLocal.getPatientId());
562         addPrescription(pPrescriptionVO, pRecordLocal);
563       }
564     }
565   }
566 
567     //    P R O C E S S   R E G I S T R A T I O N
568   /**
569   <p>Start registration process by placing registration object on queue.
570   * The object is eventually picked up and acted upon.</p>
571   *
572   @param pReg    Registration value objects.
573   @exception NamingException
574   @exception Exception
575   */
576   @RemoteMethod()
577   public void processRegistration(Registration pRegthrows Exception {
578     logger.debug("Sending registration to queue");
579     qSender = qSession.createSender(queReg);
580     sendToQueue(pReg, qSender);
581   }
582 
583     //    P R O C E S S   R E G I S T R A T I O N
584   /**
585   <p>Start XML file upload process by placing filename on queue.
586   * The object is eventually picked up and acted upon.</p>
587   *
588   @param filename    Filename of XML file to be uploaded.
589   @exception Exception
590   */
591   @RemoteMethod()
592   public void processXMLUpload(String filenamethrows Exception {
593     logger.debug("Sending xml filename to queue");
594     qSender = qSession.createSender(queXml);
595     sendToQueue(filename, qSender);
596   }
597 
598     //   S E N D   T O   Q U E U E
599   /**
600   <p>Places new registration on registration
601   * queue for further processing.</p>
602   *
603   @param obj    Serializable object to be placed on que.
604   @param qSender
605   @exception Exception
606   */
607   @RemoteMethod()
608   public void sendToQueue(java.io.Serializable obj, QueueSender qSender)
609       throws Exception {
610     logger.debug("sendToQueue: "+obj.toString());
611     try {
612       ObjectMessage message = qSession.createObjectMessage(obj);
613       qSender.send(message);
614       logger.debug("Finished sending mnessage to queue");
615     catch (Exception e) {
616       logger.error(e.getLocalizedMessage(), e);
617       throw e;
618     }
619   }
620 
621     //  U P D A T E   A C C O U N T   S T A T U S
622   /**
623   <p>Update user account status to given status.</p>
624   *
625   @param pUsername    Patient value objects.
626   @param pStatus    Patient value objects.
627   @exception MedRecException
628   */
629   @RemoteMethod()
630   public void updateAccountStatus(String pUsername, String pStatus)
631       throws MedRecException, Exception {
632     logger.debug("Updating "+pUsername+" with account status "+pStatus);
633     UserLocal userLocal = null;
634     try {
635       userLocal = userHome.findByUsername(pUsername);
636       userLocal.setStatus(pStatus);
637     catch (FinderException fe) {
638       logger.warn(ErrorConstants.USER_NOT_FOUND+" "+pUsername);
639       throw new MedRecException(ErrorConstants.USER_NOT_FOUND+" "+pUsername);
640     catch (Exception e) {
641       logger.error(e.getMessage(), e);
642       throw e;
643     }
644   }
645 }