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 = (UserLocal) itr.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 = (MedicalRecord) itr.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 = (Record) itr.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 pReg) throws 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 filename) throws 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 }
|