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


import java.util.List;

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

import gov.va.med.fw.service.AbstractComponent;

/**
 * The default implementation of ConversionService. In this implementation the conversion task
 * is delegated to the BeanConverter which calls the preProcessConvert and postProcessConvert methods
 * before and after performing the conversion. 
 * 
 * @see For limitations of this default implementation, please refer to the BeanConverter javadoc.
 * 
 * @author Muddaiah Ranga
 * @version 3.0 
 */
public class ConversionServiceImpl extends AbstractComponent implements ConversionService 
{
	protected List mappingFile; 
	
	protected transient Log log = LogFactory.getLog(getClass());
	
	/**
	 * Getter for the source property mapping.
	 */
	public List getMappingFile() 
	{
		return mappingFile;
	}

	/**
	 * Setter for the source property mapping.
	 */
	public void setMappingFile(List mappingFile)
	{
		this.mappingFile = mappingFile;
	}
    
	/**
	 * Call back method called by the BeanConverter before performing the conversion. The
	 * default implementation does nothing.
	 * 
	 * @param source the source object
	 * @param target the target object
	 * 
	 * @throws ConversionServiceException when aay error occured during converting.
	 */
	public void preProcessConvert(Object source, Object target)
	throws ConversionServiceException
	{
		log.trace("preProcessConvert() is called.");
	}
	
	/**
	 * The main method where actual conversion happens. The default implementation delegates the
	 * conversion task to the BeanConverter. The preProcessConvert and postProcessConvert methods 
	 * are called by the BeanConverter. If the convert method is overriden, these methods will not be called.
	 * 
	 * @param source the source object
	 * @param target the target object
	 * 
	 * @throws ConversionServiceException when aay error occured during converting.
	 */
	public void convert(Object source, Object target)
	throws ConversionServiceException
	{
		try
		{
			log.trace("Before calling the preProcessConvert().");
			preProcessConvert(source,target);
			log.trace("After calling the preProcessConvert().");
			
			//Call the overidable convertBean method.
			convertBean(source,target);
			
			log.trace("Before calling the postProcessConvert().");
			postProcessConvert(source,target);
			log.trace("After calling the postProcessConvert().");
		}
		catch(ConversionServiceException convEx) 
		{
			throw convEx;
		}
		catch(Exception ex)
		{
			throw new ConversionServiceException("Error while performing the conversion",ex);
		}
	}
	
	/**
	 * The main method where actual conversion happens. A new target object will be created
	 * 
	 * @param source the source object
	 * @param targetClass the class object of the target
	 * 
	 * @throws ConversionServiceException when aay error occured during converting.
	 */
	public Object convert(Object source, Class targetClass)
	throws ConversionServiceException
	{
		Object target = null;
		try
		{
			log.trace("Before calling the preProcessConvert().");
			preProcessConvert(source,null);
			log.trace("After calling the preProcessConvert().");
			
			//Call the overidable convertBean method.
			target = convertBean(source,targetClass);
			
			log.trace("Before calling the postProcessConvert().");
			postProcessConvert(source,target);
			log.trace("After calling the postProcessConvert().");
		}
		catch(ConversionServiceException convEx) 
		{
			throw convEx;
		}
		catch(Exception ex)
		{
			throw new ConversionServiceException("Error while performing the conversion",ex);
		}
		return target;
	}
	
	/**
	 * Call back method called by the BeanConverter after performing the conversion. The
	 * default implementation does nothing.
	 * 
	 * @param source the source object
	 * @param target the target object
	 * 
	 * @throws ConversionServiceException when aay error occured during converting.
	 */
	public void postProcessConvert(Object source, Object target)
	throws ConversionServiceException
	{
		log.trace("postProcessConvert() is called.");
	}

	/**
	 * The main method where actual conversion happens. The default implementation delegates the
	 * conversion task to the BeanConverter. The preProcessConvert and postProcessConvert methods 
	 * are called before and after this method call respectively.
	 * 
	 * @see For limitation please refer to BeanConverter javadoc.
	 * 
	 * @param source the source object
	 * @param target the target object
	 * 
	 * @throws ConversionServiceException when aay error occured during converting.
	 */
	protected void convertBean(Object source, Object target) 
	throws ConversionServiceException
	{
	}
	
	/**
	 * The main method where actual conversion happens. The default implementation delegates the
	 * conversion task to the BeanConverter. The preProcessConvert and postProcessConvert methods 
	 * are called before and after this method call respectively.
	 * 
	 * @see For limitation please refer to BeanConverter javadoc.
	 * 
	 * @param source the source object
	 * @param target the target class object
	 * 
	 * @throws ConversionServiceException when aay error occured during converting.
	 */
	protected Object convertBean(Object source, Class targetClass) 
	throws ConversionServiceException
	{
	    return null;
	}
	
	/**
	 * The merge logic implemented.
	 * 
	 * @see For limitation please refer to BeanConverter javadoc.
	 * 
	 * @param source the source object
	 * @param target the target object
	 * 
	 */
	public void merge(Object source, Object target) throws Exception 
	{
	}

}
