/*******************************************************************************
 * Copyright © 2005 VHA. All rights reserved
 ******************************************************************************/
package gov.va.med.fw.service.trigger;

// Java Classes
import java.util.Iterator;
import java.util.Map;

// Framework Classes
import gov.va.med.fw.service.AbstractComponent;
import gov.va.med.fw.service.ServiceException;
import gov.va.med.fw.util.InvalidConfigurationException;

/**
 * This consumer gets invoked to process TriggerEvents from a JMS message. The trigger method will get invoked with a
 * passed in TriggerEvent parameter. This consumer will delegate to an alternate TriggerableService based on the the
 * type of TriggerIdentity found in the processed TriggerEvent (via the injected triggerableServices).
 *
 * @author Andrew Pach
 * @version 3.0
 */
public class TriggerEventConsumer extends AbstractComponent
{
    // Map of TriggerIdentity to TriggerableServices
    private Map triggerableServiceMap;

    /**
     * Process the Trigger Event that came from the JMS Queue.
     *
     * @param triggerEvent The trigger event
     *
     * @throws gov.va.med.fw.service.ServiceException If there were any problems encountered.
     */
    public void trigger(TriggerEvent triggerEvent) throws ServiceException
    {
        if (triggerEvent != null)
        {

            if (this.logger.isDebugEnabled())
            {
                this.logger.debug("Received a trigger event " + triggerEvent);
            }

            // Find the triggerable service for the trigger identity associated
            // with this trigger event
            TriggerableService triggerService = getTriggerableService(triggerEvent
                .getTriggerIdentity());

            // If a trigger service was found, delegate to it for message
            // processing.
            if (triggerService != null)
            {
                triggerService.trigger(triggerEvent);
            }
        }
    }

    /**
     * Verify that the required properties are set.
     */
    public void afterPropertiesSet()
    {
        if (triggerableServiceMap == null)
        {
            throw new InvalidConfigurationException("triggerableServiceMap must be set on " + getClass().getName());
        }
    }

    /**
     * Get a triggerable service based on a trigger identity.
     */
    protected TriggerableService getTriggerableService(TriggerIdentity triggerIdentity)
    {
        // Search the keys of the map for a trigger identity of the same class as
        // the passed in trigger identity.
        for (Iterator iterator = triggerableServiceMap.keySet().iterator(); iterator
            .hasNext();)
        {
            TriggerIdentity triggerIdentitySearch = (TriggerIdentity)iterator
                .next();
            if (triggerIdentitySearch.getClass()
                .equals(triggerIdentity.getClass()))
            {
                return (TriggerableService)triggerableServiceMap
                    .get(triggerIdentitySearch);
            }
        }

        // We didn't find a match so return null
        return null;
    }

    public Map getTriggerableServiceMap()
    {
        return triggerableServiceMap;
    }

    public void setTriggerableServiceMap(Map triggerableServiceMap)
    {
        this.triggerableServiceMap = triggerableServiceMap;
    }
}
