org.akaza.openclinica.ws.EventEndpoint.java Source code

Java tutorial

Introduction

Here is the source code for org.akaza.openclinica.ws.EventEndpoint.java

Source

/*
 * OpenClinica is distributed under the
 * GNU Lesser General Public License (GNU LGPL).
 * For details see: http://www.openclinica.org/license
 *
 * Copyright 2003-2009 Akaza Research
 */
package org.akaza.openclinica.ws;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.Locale;

import javax.sql.DataSource;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.transform.Source;
import javax.xml.transform.dom.DOMSource;

import org.akaza.openclinica.bean.login.UserAccountBean;
import org.akaza.openclinica.dao.login.UserAccountDAO;
import org.akaza.openclinica.exception.OpenClinicaSystemException;
import org.akaza.openclinica.i18n.util.ResourceBundleProvider;
import org.akaza.openclinica.service.EventServiceInterface;
import org.akaza.openclinica.ws.bean.StudyEventTransferBean;
import org.akaza.openclinica.ws.validator.StudyEventTransferValidator;
import org.apache.commons.lang.exception.ExceptionUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.MessageSource;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.support.TransactionCallback;
import org.springframework.transaction.support.TransactionTemplate;
import org.springframework.util.xml.DomUtils;
import org.springframework.validation.DataBinder;
import org.springframework.validation.Errors;
import org.springframework.validation.ObjectError;
import org.springframework.ws.server.endpoint.annotation.Endpoint;
import org.springframework.ws.server.endpoint.annotation.PayloadRoot;
import org.springframework.ws.server.endpoint.annotation.XPathParam;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;

/**
 * @author Krikor Krumlian
 * 
 */
@Endpoint
public class EventEndpoint {

    protected final Logger logger = LoggerFactory.getLogger(getClass().getName());
    private final String NAMESPACE_URI_V1 = "http://openclinica.org/ws/event/v1";
    private String dateFormat;

    private final EventServiceInterface eventService;
    private final MessageSource messages;
    private final DataSource dataSource;
    Locale locale;

    private TransactionTemplate transactionTemplate;

    /**
     * Constructor
     * 
     * @param subjectService
     * @param cctsService
     */
    public EventEndpoint(EventServiceInterface eventService, DataSource dataSource, MessageSource messages) {
        this.eventService = eventService;
        this.messages = messages;
        this.dataSource = dataSource;
        this.locale = new Locale("en_US");
    }

    /**
     * if NAMESPACE_URI_V1:scheduleRequest execute this method
     * 
     */
    @PayloadRoot(localPart = "scheduleRequest", namespace = NAMESPACE_URI_V1)
    public Source scheduleEvent(@XPathParam("//e:event") final NodeList event) throws Exception {

        return getTransactionTemplate().execute(new TransactionCallback<Source>() {
            public Source doInTransaction(TransactionStatus status) {
                Source result = null;
                try {
                    result = scheduleEventInTransaction(event);
                    assert (result != null);
                } catch (Throwable t) {
                    logger.error(t.getMessage());
                    logger.error(ExceptionUtils.getStackTrace(t));
                    throw new RuntimeException("Error processing schedule event request", t);
                }
                return result;
            }
        });
    }

    protected Source scheduleEventInTransaction(NodeList event) throws Exception {
        ResourceBundleProvider.updateLocale(new Locale("en_US"));
        Element eventElement = (Element) event.item(0);
        StudyEventTransferBean studyEventTransferBean = unMarshallToEventTransfer(eventElement);

        DataBinder dataBinder = new DataBinder((studyEventTransferBean));
        Errors errors = dataBinder.getBindingResult();
        StudyEventTransferValidator studyEventTransferValidator = new StudyEventTransferValidator(dataSource);
        studyEventTransferValidator.validate((studyEventTransferBean), errors);

        if (!errors.hasErrors()) {

            try {
                HashMap<String, String> h = getEventService().scheduleEvent(studyEventTransferBean.getUser(),
                        studyEventTransferBean.getStartDateTime(), studyEventTransferBean.getEndDateTime(),
                        studyEventTransferBean.getLocation(), studyEventTransferBean.getStudyUniqueId(),
                        studyEventTransferBean.getSiteUniqueId(), studyEventTransferBean.getEventDefinitionOID(),
                        studyEventTransferBean.getSubjectLabel());
                return new DOMSource(mapSuccessConfirmation(h));
            } catch (OpenClinicaSystemException ose) {
                errors.reject("eventEndpoint.cannot_schedule", "Cannot schedule an event for this Subject.");
                return new DOMSource(mapFailConfirmation(errors));
            } catch (Exception e) {
                logger.error(e.getMessage());
                logger.error(ExceptionUtils.getStackTrace(e));
                throw e;
            }
        } else {

            return new DOMSource(mapFailConfirmation(errors));
        }
    }

    /**
     * Create Success Response
     * 
     * @param confirmation
     * @return
     * @throws Exception
     */
    private Element mapSuccessConfirmation(HashMap<String, String> confirmation) throws Exception {
        DocumentBuilderFactory dbfac = DocumentBuilderFactory.newInstance();
        DocumentBuilder docBuilder = dbfac.newDocumentBuilder();
        Document document = docBuilder.newDocument();

        Element responseElement = document.createElementNS(NAMESPACE_URI_V1, "scheduleResponse");
        Element resultElement = document.createElementNS(NAMESPACE_URI_V1, "result");
        Element eventDefinitionOID = document.createElementNS(NAMESPACE_URI_V1, "eventDefinitionOID");
        Element studySubjectOID = document.createElementNS(NAMESPACE_URI_V1, "studySubjectOID");
        Element eventOrdinal = document.createElementNS(NAMESPACE_URI_V1, "studyEventOrdinal");
        resultElement.setTextContent(messages.getMessage("eventEndpoint.success", null, "Success", locale));
        eventDefinitionOID.setTextContent(confirmation.get("eventDefinitionOID"));
        studySubjectOID.setTextContent(confirmation.get("studySubjectOID"));
        eventOrdinal.setTextContent(confirmation.get("studyEventOrdinal"));
        responseElement.appendChild(resultElement);
        responseElement.appendChild(eventDefinitionOID);
        responseElement.appendChild(studySubjectOID);
        responseElement.appendChild(eventOrdinal);
        return responseElement;

    }

    /**
     * Process createEvent request by creating StudyEventTransferBean from received payload.
     * 
     * @param subjectElement
     * @return SubjectTransferBean
     * @throws ParseException
     */
    private StudyEventTransferBean unMarshallToEventTransfer(Element eventElement) throws ParseException {

        Element eventDefinitionOidElement = DomUtils.getChildElementByTagName(eventElement, "eventDefinitionOID");
        Element locationElement = DomUtils.getChildElementByTagName(eventElement, "location");
        Element startDateElement = DomUtils.getChildElementByTagName(eventElement, "startDate");
        Element endDateElement = DomUtils.getChildElementByTagName(eventElement, "endDate");
        Element startTimeElement = DomUtils.getChildElementByTagName(eventElement, "startTime");
        Element endTimeElement = DomUtils.getChildElementByTagName(eventElement, "endTime");

        Element subjectRefElement = DomUtils.getChildElementByTagName(eventElement, "studySubjectRef");
        Element labelElement = DomUtils.getChildElementByTagName(subjectRefElement, "label");

        Element studyRefElement = DomUtils.getChildElementByTagName(eventElement, "studyRef");
        Element studyIdentifierElement = DomUtils.getChildElementByTagName(studyRefElement, "identifier");
        Element siteRef = DomUtils.getChildElementByTagName(studyRefElement, "siteRef");
        Element siteIdentifierElement = siteRef == null ? null
                : DomUtils.getChildElementByTagName(siteRef, "identifier");

        String studySubjectId = DomUtils.getTextValue(labelElement).trim();
        String eventDefinitionOID = DomUtils.getTextValue(eventDefinitionOidElement).trim();
        String studyIdentifier = DomUtils.getTextValue(studyIdentifierElement).trim();
        String siteIdentifier = siteIdentifierElement == null ? null
                : DomUtils.getTextValue(siteIdentifierElement).trim();
        String location = locationElement == null ? null : DomUtils.getTextValue(locationElement).trim();
        String startDate = DomUtils.getTextValue(startDateElement).trim();
        String startTime = startTimeElement == null ? null : DomUtils.getTextValue(startTimeElement).trim();
        String endDate = endDateElement == null ? null : DomUtils.getTextValue(endDateElement).trim();
        String endTime = endTimeElement == null ? null : DomUtils.getTextValue(endTimeElement).trim();

        StudyEventTransferBean studyEventTransferBean = new StudyEventTransferBean(studySubjectId, studyIdentifier,
                siteIdentifier, eventDefinitionOID, location, getDate(startDate, startTime),
                getDate(endDate, endTime), getUserAccount());
        return studyEventTransferBean;
    }

    /**
     * Create Error Response
     * 
     * @param confirmation
     * @return
     * @throws Exception
     */
    private Element mapFailConfirmation(Errors errors) throws Exception {
        DocumentBuilderFactory dbfac = DocumentBuilderFactory.newInstance();
        DocumentBuilder docBuilder = dbfac.newDocumentBuilder();
        Document document = docBuilder.newDocument();

        Element responseElement = document.createElementNS(NAMESPACE_URI_V1, "scheduleResponse");
        Element resultElement = document.createElementNS(NAMESPACE_URI_V1, "result");
        resultElement.setTextContent(messages.getMessage("eventEndpoint.fail", null, "Fail", locale));
        responseElement.appendChild(resultElement);
        for (ObjectError error : errors.getAllErrors()) {
            Element errorElement = document.createElementNS(NAMESPACE_URI_V1, "error");
            String theMessage = messages.getMessage(error.getCode(), error.getArguments(), locale);
            errorElement.setTextContent(theMessage);
            responseElement.appendChild(errorElement);
        }
        return responseElement;

    }

    /**
     * Helper Method to resolve dates
     * 
     * @param dateAsString
     * @return
     * @throws ParseException
     */
    private Date getDate(String dateAsString, String hourMinuteAsString) throws ParseException {
        Date d = null;
        if (dateAsString != null && dateAsString.length() != 0) {
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm");
            dateAsString += hourMinuteAsString == null ? " 00:00" : " " + hourMinuteAsString;
            d = sdf.parse(dateAsString);
            if (!sdf.format(d).equals(dateAsString)) {
                throw new OpenClinicaSystemException("Date not parseable");
            }
            return sdf.parse(dateAsString);
        } else {
            return null;
        }

    }

    /**
     * Helper Method to get the user account
     * 
     * @return UserAccountBean
     */
    private UserAccountBean getUserAccount() {
        Object principal = SecurityContextHolder.getContext().getAuthentication().getPrincipal();
        String username = null;
        if (principal instanceof UserDetails) {
            username = ((UserDetails) principal).getUsername();
        } else {
            username = principal.toString();
        }
        UserAccountDAO userAccountDao = new UserAccountDAO(dataSource);
        return (UserAccountBean) userAccountDao.findByUserName(username);
    }

    /**
     * @return
     */
    public String getDateFormat() {
        return dateFormat;
    }

    /**
     * @param dateFormat
     */
    public void setDateFormat(String dateFormat) {
        this.dateFormat = dateFormat;
    }

    public EventServiceInterface getEventService() {
        return eventService;
    }

    public TransactionTemplate getTransactionTemplate() {
        return transactionTemplate;
    }

    public void setTransactionTemplate(TransactionTemplate transactionTemplate) {
        this.transactionTemplate = transactionTemplate;
    }

}