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

// Java classes
import java.util.ArrayList;
import java.util.Iterator;

// Library classes
import org.springframework.util.Assert;

// Framework classes
import gov.va.med.fw.service.AbstractComponent;
import gov.va.med.fw.service.ServiceException;

/**
 * A generic abstract service that contains a list of runnable tasks to be  
 * executed at a configurable time.  
 * 
 * Project: Framework
 * @author DNS   LEV
 * @version 1.0
 */
public abstract class AbstractRunnableService extends AbstractComponent implements Runnable {
    
    /**
     * A list of runnable services
     */
    private ArrayList services = null;

    /**
     * A default constructor 
     */
    protected AbstractRunnableService() {
        super();
    }

    /**
     * Returns a list of runnable services
     * @return Returns the services.
     */
    public ArrayList getServices() {
        return services;
    }
    
    /**
     * Sets a list of runnable services to execute
     * @param services The services to set.
     */
    public void setServices(ArrayList services) {
        this.services = services;
    }

    /**
     * @see org.springframework.beans.factory.InitializingBean#afterPropertiesSet()
     */
    public void afterPropertiesSet() throws Exception {
        super.afterPropertiesSet();
        Assert.notNull( getServices(), "Missing a required list of services to be executed");
        execute();
    }

    /**
     * Invokes a list of runnable services in a FIFO order
     */
    public void run() {

        for( Iterator i=services.iterator(); i.hasNext(); ) {
            try {
                Object service = i.next();
                if( service instanceof Runnable ) {
                    ((Runnable)service).run();
                }
            }
            catch( Exception e ) {
                logger.debug( "Exception in running a service ", e );
            }
        }
    }
    
    /** Delegates to a derived class to implement how a collection
     * of a runnable tasks is invoked.
     * 
     * @throws ServiceException Thrown if failed to execute.
     */
    protected abstract void execute() throws ServiceException;
}