// Created Apr 28, 2005 10:40:50 AM

/********************************************************************
 * Copyright © 2005 VHA. All rights reserved
 ********************************************************************/

package gov.va.med.fw.service.trigger;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import gov.va.med.fw.security.SecurityContextHelper;
import gov.va.med.fw.service.AbstractComponent;
import gov.va.med.fw.service.ServiceException;
import gov.va.med.fw.service.jms.JMSServiceException;
import gov.va.med.fw.service.jms.TopicMessageProducer;
import gov.va.med.fw.util.InvalidConfigurationException;

/**
 * Handles publishing messages contains TriggerEvent information.
 * 
 * @author Venky Kullampalle
 */
public class TopicPublishTriggerableServiceImpl extends AbstractComponent implements
		PublishTriggerableService {
	private TopicMessageProducer messageProducer;

	protected Log logger = LogFactory.getLog(getClass());

	public void trigger(TriggerEvent triggerEvent) throws ServiceException {
		publishMessage(triggerEvent);
	}

	protected void publishMessage(TriggerEvent triggerEvent)
			throws ServiceException {
		if (logger.isDebugEnabled())
			logger.debug("creating async message for TriggerEvent: "
					+ triggerEvent);
		// ensure valid TriggerEvent
		if (triggerEvent.getTriggerIdentity() == null
				|| triggerEvent.getTriggerIdentity().getDestinationType() == null) {
			throw new IllegalStateException(
					"A TriggerEvent must have a non-null getTriggerIdentity().getDestinationType()");
		}

		// set the initiater of this event (if not already set)
		if (triggerEvent.getInitiater() == null) {
			try {
				triggerEvent.setInitiater(SecurityContextHelper
						.getSecurityContext().getUserPrincipal()
						.getUserCredentials());
			} catch (Exception e) {
				logger
						.warn(
								"At publish time, unable to set TriggerEvent.initiater, most likely because the user is no longer logged in.",
								e);
			}
		}

		if (logger.isInfoEnabled()) {
			logger.info("Publishing TriggerEvent context: " + triggerEvent.getTriggerContext() +
					" for TriggerEvent identity: " + triggerEvent.getTriggerIdentity());
		}		
		
		try {
			messageProducer.publish(triggerEvent, triggerEvent.getRoutingProperties());
		} catch (JMSServiceException e) {
			logger.error("!! Unable to publish TriggerEvent [" + triggerEvent
					+ "].");
			throw e;
		}
	}

	/**
	 * @return Returns the messageProducer.
	 */
	public TopicMessageProducer getMessageProducer() {
		return messageProducer;
	}

	/**
	 * @param messageProducer
	 *            The messageProducer to set.
	 */
	public void setMessageProducer(TopicMessageProducer messageProducer) {
		this.messageProducer = messageProducer;
	}

	public void afterPropertiesSet() {
		if (messageProducer == null)
			throw new InvalidConfigurationException(
					"MessageProducer must be set on " + getClass().getName());
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see gov.va.med.fw.service.trigger.PublishTriggerableService#publishTriggerEvent(gov.va.med.fw.service.trigger.TriggerEvent)
	 */
	public void publishTriggerEvent(TriggerEvent triggerEvent)
			throws ServiceException {
		publishMessage(triggerEvent);
	}
}
