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

// Java classes
import java.util.Map;

// Library classes
import org.apache.commons.lang.Validate;

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

/**
 * Uses cache strategy to cache pre-compiled templates for faster retrieval.
 * A concrete cache strategy implementation used to cache a report is an EHCacheStrategy  
 *
 * Project: Framework</br>
 * Created on: 4:03:08 PM </br>
 *
 * @author DNS   LEV
 */
public abstract class AbstractReportTemplate extends AbstractComponent implements ReportTemplate {

	/**
	 * An instance of serialVersionUID
	 */
	private static final long serialVersionUID = 1034654168494467907L;

	/**
	 * An instance of templates
	 */
	private Map templates = null;
	
	/**
	 * An instance of cache
	 */
	private CacheStrategy templateCache = null;
	
	/**
	 * An instance of nameResolver
	 */
	private ReportNameResolver nameResolver = null;
	
	/**
	 * An indicator to pre compile jasper report template at startup
	 */
	private boolean preCompiled = false;
	
	/**
	 * A default constructor
	 */
	protected AbstractReportTemplate() {
		super();
	}

	/**
	 * @return Returns the preCompile.
	 */
	public boolean isPreCompiled() {
		return preCompiled;
	}

	/**
	 * @param preCompile The preCompile to set.
	 */
	public void setPreCompiled(boolean preCompile) {
		this.preCompiled = preCompile;
	}

	/**
	 * @param templates The templates to set.
	 */
	public void setTemplates(Map templates) {
		this.templates = templates;
	}

	/**
	 * @param nameResolver The nameResolver to set.
	 */
	public void setNameResolver( ReportNameResolver nameResolver) {
		this.nameResolver = nameResolver;
	}

	/** Sets a concrete implementation of a caching strategy
	 * @param tempalteCache The templateCache to set.
	 */
	public void setTemplateCache( CacheStrategy cache ) {
		this.templateCache = cache;
	}

	/** Returns a cache strategy that provides concrete implementation of caching
	 * @return CacheStrategy A concrete implementation of a strategy
	 */
	public CacheStrategy getTemplateCache() {
		return this.templateCache;
	}

	/**
	 * @see gov.va.med.fw.report.ReportTemplate#getCompiledTemplate(gov.va.med.fw.report.ReportConfiguration)
	 */
	public Object getCompiledTemplate( ReportConfiguration config ) throws InvalidTemplateException {
		String name = this.nameResolver.getReportName( config );
		
		if( !this.isPreCompiled() ) {
			compileTemplates( this.templates );
		}

		
		return this.getTemplateCache().getItem( name );
	}

	/**
	 * @see gov.va.med.fw.service.AbstractComponent#afterPropertiesSet()
	 */
	public void afterPropertiesSet() throws Exception {
		if( this.nameResolver == null ) {
			this.nameResolver = new SimpleReportNameResolver();
		}
		Validate.notNull( this.templateCache, "A template cache is required" );
		Validate.notEmpty( this.templates, "A map of report templates must be configured");
		if( this.isPreCompiled() ) {
			compileTemplates( this.templates );
		}
	}
	
	protected abstract void compileTemplates( Map templates ) throws InvalidTemplateException;
}