package net.sf.jasperreports.engine.xml;

import java.io.BufferedInputStream;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import net.sf.jasperreports.engine.JRException;
import net.sf.jasperreports.engine.JRRuntimeException;
import net.sf.jasperreports.engine.JRTemplate;
import net.sf.jasperreports.engine.util.JRLoader;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.xml.sax.SAXException;

public class JRXmlTemplateLoader {
  private static final Log log = LogFactory.getLog(JRXmlTemplateLoader.class);
  
  public static JRTemplate load(String location) throws JRException {
    byte[] data = JRLoader.loadBytesFromLocation(location);
    return load(new ByteArrayInputStream(data));
  }
  
  public static JRTemplate load(File file) {
    BufferedInputStream fileIn;
    try {
      fileIn = new BufferedInputStream(new FileInputStream(file));
    } catch (FileNotFoundException e) {
      throw new JRRuntimeException("Template XML file not found", e);
    } 
    try {
      return load(fileIn);
    } finally {
      try {
        fileIn.close();
      } catch (IOException e) {
        log.warn("Error closing XML file", e);
      } 
    } 
  }
  
  public static JRTemplate load(URL url) {
    InputStream input;
    try {
      input = url.openStream();
    } catch (IOException e) {
      throw new JRRuntimeException("Error opening connection to template URL " + url, e);
    } 
    try {
      return load(input);
    } finally {
      try {
        input.close();
      } catch (IOException e) {
        log.warn("Error closing connection to template URL " + url, e);
      } 
    } 
  }
  
  public static JRTemplate load(InputStream data) {
    JRXmlTemplateLoader loader = new JRXmlTemplateLoader();
    return loader.loadTemplate(data);
  }
  
  protected JRTemplate loadTemplate(InputStream data) {
    JRXmlDigester digester = JRXmlTemplateDigesterFactory.instance().createDigester();
    try {
      JRTemplate template = (JRTemplate)digester.parse(data);
      return template;
    } catch (IOException e) {
      throw new JRRuntimeException("Error reading template XML", e);
    } catch (SAXException e) {
      throw new JRRuntimeException("Error parsing template XML", e);
    } 
  }
}
