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


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

import org.springframework.beans.BeansException;

import gov.va.med.fw.hl7.builder.JMSMetaData;
import gov.va.med.fw.service.AbstractComponent;
import gov.va.med.fw.service.ServiceDescriptor;
import gov.va.med.fw.service.ServiceException;
import gov.va.med.fw.service.trigger.TriggerEvent;
import gov.va.med.fw.service.trigger.TriggerableService;
import gov.va.med.fw.util.Reflector;
import gov.va.med.fw.util.builder.BuilderException;

/**
 * Initial javadoc for class SynchronousTriggerableService.
 * TODO - Add content here
 * 
 * Created Feb 23, 2007 4:20:58 PM
 * @author DNS   BOHMEG
 */
public class SynchronousTriggerableService extends AbstractComponent implements TriggerableService {

	/* (non-Javadoc)
	 * @see gov.va.med.fw.service.trigger.TriggerableService#trigger(gov.va.med.fw.service.trigger.TriggerEvent)
	 */
	public void trigger(TriggerEvent triggerEvent) throws ServiceException {
		// 1) get ServiceDescriptor
		ServiceDescriptor desc = null;
		String consumerRoutingKey = triggerEvent.getConsumerRoutingKey();
		try {
			desc = (ServiceDescriptor) this.getApplicationContext().getBean(consumerRoutingKey);
		} catch(BeansException e) {
			logger.error("Unable to find ServiceDescriptor for " + consumerRoutingKey +
					" - perhaps that Spring context is not loaded...ignoring that TriggerEvent");
			return;
		}
				
		try {
			// 2) build from (JMS) Message (can't assume it is just TriggerEvent passed to Builder)
			Object builtObject = desc.getBuilder().build(new JMSMetaData(new SimpleTriggerEventMessage(triggerEvent)));
			
			// 3) invoke service/method from ServiceDescriptor
			Object[] params = null;
			if (builtObject instanceof Object[]) {
				params = (Object[]) builtObject;
			}
			else {
				params = new Object[] { builtObject };
			}			
			String serviceName = desc.getServiceName();
			String methodName = desc.getMethodName();

			Object service = this.getApplicationContext().getBean(serviceName);			
			Reflector.invoke(service, methodName, params);
		} catch(BuilderException e) {
			throw new ServiceException("Unable to build from TriggerEvent", e); 
		}					
		catch (Exception e) {
			throw new ServiceException("Unable to execute service for TriggerEvent", e);
		}			
	}
}



