Package ar.com.fdvs.dj.core

Source Code of ar.com.fdvs.dj.core.DynamicJasperHelper

/*
* DynamicJasper: A library for creating reports dynamically by specifying
* columns, groups, styles, etc. at runtime. It also saves a lot of development
* time in many cases! (http://sourceforge.net/projects/dynamicjasper)
*
* Copyright (C) 2008  FDV Solutions (http://www.fdvsolutions.com)
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
*
* License as published by the Free Software Foundation; either
*
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
*
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
*
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
*
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
*
*
*/

package ar.com.fdvs.dj.core;

import java.io.File;
import java.io.IOException;
import java.io.OutputStream;
import java.net.URL;
import java.sql.Connection;
import java.sql.ResultSet;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.MissingResourceException;
import java.util.ResourceBundle;

import net.sf.jasperreports.engine.JRDataSource;
import net.sf.jasperreports.engine.JRException;
import net.sf.jasperreports.engine.JRResultSetDataSource;
import net.sf.jasperreports.engine.JasperCompileManager;
import net.sf.jasperreports.engine.JasperFillManager;
import net.sf.jasperreports.engine.JasperPrint;
import net.sf.jasperreports.engine.JasperReport;
import net.sf.jasperreports.engine.data.JRBeanCollectionDataSource;
import net.sf.jasperreports.engine.design.JRCompiler;
import net.sf.jasperreports.engine.design.JRDesignField;
import net.sf.jasperreports.engine.design.JRDesignGroup;
import net.sf.jasperreports.engine.design.JRDesignParameter;
import net.sf.jasperreports.engine.design.JasperDesign;
import net.sf.jasperreports.engine.util.JRProperties;
import net.sf.jasperreports.engine.xml.JRXmlLoader;
import net.sf.jasperreports.engine.xml.JRXmlWriter;

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

import ar.com.fdvs.dj.core.layout.LayoutManager;
import ar.com.fdvs.dj.core.registration.ColumnRegistrationManager;
import ar.com.fdvs.dj.core.registration.DJGroupVariableDefRegistrationManager;
import ar.com.fdvs.dj.core.registration.DJGroupRegistrationManager;
import ar.com.fdvs.dj.domain.ColumnProperty;
import ar.com.fdvs.dj.domain.DJCalculation;
import ar.com.fdvs.dj.domain.DynamicJasperDesign;
import ar.com.fdvs.dj.domain.DynamicReport;
import ar.com.fdvs.dj.domain.entities.DJGroup;
import ar.com.fdvs.dj.domain.entities.DJGroupVariableDef;
import ar.com.fdvs.dj.domain.entities.Parameter;
import ar.com.fdvs.dj.domain.entities.Subreport;
import ar.com.fdvs.dj.domain.entities.columns.AbstractColumn;
import ar.com.fdvs.dj.domain.entities.columns.PercentageColumn;
import ar.com.fdvs.dj.util.DJCompilerFactory;
import ar.com.fdvs.dj.util.LayoutUtils;

/**
* Helper class for running a report and some other DJ related stuff
*/
public class DynamicJasperHelper {

  private static final Log log = LogFactory.getLog(DynamicJasperHelper.class);
  public static final String DEFAULT_XML_ENCODING = "UTF-8";
  private static final String DJ_RESOURCE_BUNDLE ="dj-messages";

  private final static void registerEntities(DynamicJasperDesign jd, DynamicReport dr, LayoutManager layoutManager) {
    ColumnRegistrationManager columnRegistrationManager = new ColumnRegistrationManager(jd,dr,layoutManager);
    columnRegistrationManager.registerEntities(dr.getColumns());
   
    DJGroupRegistrationManager djGroupRegistrationManager = new DJGroupRegistrationManager(jd,dr,layoutManager);
    djGroupRegistrationManager.registerEntities(dr.getColumnsGroups());
   
    registerPercentageColumnsVariables(jd,dr,layoutManager);
    registerOtherFields(jd,dr.getFields());
    Locale locale = dr.getReportLocale() == null ? Locale.getDefault() : dr.getReportLocale();
    if (log.isDebugEnabled()){
      log.debug("Requested Locale = " + dr.getReportLocale() + ", Locale to use: "+ locale);
    }
    ResourceBundle messages = null;
    if (dr.getResourceBundle() != null ){
      try {
        messages =  ResourceBundle.getBundle(dr.getResourceBundle(), locale);
      } catch (MissingResourceException e){ log.warn(e.getMessage() + ", usign default (dj-messages)");}
    }

    if (messages == null) {
      try {
        messages =  ResourceBundle.getBundle(DJ_RESOURCE_BUNDLE, locale);
      } catch (MissingResourceException e){
        log.warn(e.getMessage() + ", usign default (dj-messages)");
        try {
          messages = ResourceBundle.getBundle(DJ_RESOURCE_BUNDLE, Locale.ENGLISH); //this cannot fail because is included in the DJ jar
        } catch (MissingResourceException e2) {
          log.error("Default messajes not found: " + DJ_RESOURCE_BUNDLE + ", " + e2.getMessage(), e2);
          throw new DJException("Default messajes file not found: "+ DJ_RESOURCE_BUNDLE + "en.properties",e2);
        }
      }
    }
    jd.getParametersWithValues().put(JRDesignParameter.REPORT_RESOURCE_BUNDLE, messages);
    jd.getParametersWithValues().put(JRDesignParameter.REPORT_LOCALE, locale);
//    JRDesignParameter.REPORT_RESOURCE_BUNDLE
//    report.
  }

  private static void registerPercentageColumnsVariables(DynamicJasperDesign jd, DynamicReport dr, LayoutManager layoutManager) {
    for (Iterator iterator = dr.getColumns().iterator(); iterator.hasNext();) {
      AbstractColumn column = (AbstractColumn) iterator.next();
//      if (column instanceof PercentageColumn) {
//        PercentageColumn percentageColumn = ((PercentageColumn) column);       
//        JRDesignGroup jrGroup = LayoutUtils.getJRDesignGroup(jd, layoutManager, percentageColumn.getGroup());
//        ColumnsGroupTemporalVariablesRegistrationManager variablesRM = new ColumnsGroupTemporalVariablesRegistrationManager(jd,dr,layoutManager, jrGroup);
//        DJGroupTemporalVariable variable = new DJGroupTemporalVariable(percentageColumn.getGroupVariableName(), percentageColumn.getPercentageColumn(), DJCalculation.SUM);
//        Collection entities = new ArrayList();
//        entities.add(variable);
//        variablesRM.registerEntities(entities);
//      }
     
      /**
       * Group should not be needed in the percentage column. There should be a variable for each group, using
       * parent group as "rest group"
       */
      if (column instanceof PercentageColumn) {
        PercentageColumn percentageColumn = ((PercentageColumn) column);       
        for (Iterator iterator2 = dr.getColumnsGroups().iterator(); iterator2.hasNext();) {
          DJGroup djGroup = (DJGroup) iterator2.next();
          JRDesignGroup jrGroup = LayoutUtils.getJRDesignGroup(jd, layoutManager, djGroup);
          DJGroupVariableDefRegistrationManager variablesRM = new DJGroupVariableDefRegistrationManager(jd,dr,layoutManager, jrGroup);
          DJGroupVariableDef variable = new DJGroupVariableDef(percentageColumn.getGroupVariableName(djGroup), percentageColumn.getPercentageColumn(), DJCalculation.SUM);
          Collection entities = new ArrayList();
          entities.add(variable);
          variablesRM.registerEntities(entities);
        }
      }     
    }
  }
 
 
  private static void registerOtherFields(DynamicJasperDesign jd, List fields) {
    for (Iterator iter = fields.iterator(); iter.hasNext();) {
      ColumnProperty element = (ColumnProperty) iter.next();
      JRDesignField field = new JRDesignField();
      field.setValueClassName(element.getValueClassName());
      field.setName(element.getProperty());
      try {
        jd.addField(field);
      } catch (JRException e) {
//        e.printStackTrace();
        //if the field is already registered, it's not a problem
        log.warn(e.getMessage());
      }
    }

  }


  protected static DynamicJasperDesign generateJasperDesign(DynamicReport dr) throws CoreException {
    DynamicJasperDesign jd = null;
    try {
      if (dr.getTemplateFileName() != null) {
        log.info("about to load template file: "+dr.getTemplateFileName() + ", Attemping to find the file directly in the file system.");
        File file = new File(dr.getTemplateFileName());
        if (file.exists()){
          JasperDesign jdesign = JRXmlLoader.load(file);
          jd = DJJRDesignHelper.downCast(jdesign,dr);
        } else {
          log.info("Not found: Attemping to find the file in the classpath...");
          URL url = DynamicJasperHelper.class.getClassLoader().getResource(dr.getTemplateFileName());
          JasperDesign jdesign = JRXmlLoader.load(url.openStream());
          jd = DJJRDesignHelper.downCast(jdesign,dr);
        }
        DJJRDesignHelper.populateReportOptionsFromDesign(jd,dr);

      } else {
        //Create new JasperDesign from the scratch
        jd = DJJRDesignHelper.getNewDesign(dr);
      }
      jd.setScriptletClass(DJDefaultScriptlet.class.getName()); //Set up scripttlet so that custom expressions can do their magic
      registerParameters(jd,dr);
    } catch (JRException e) {
      throw new CoreException(e.getMessage(),e);
    } catch (IOException e) {
      throw new CoreException(e.getMessage(),e);
    }
    return jd;
  }

  protected static void registerParameters(DynamicJasperDesign jd, DynamicReport dr) {
    for (Iterator iterator = dr.getParameters().iterator(); iterator.hasNext();) {
      Parameter param= (Parameter) iterator.next();
      JRDesignParameter jrparam = new JRDesignParameter();
      jrparam.setName(param.getName());
      jrparam.setValueClassName(param.getClassName());

      try {
        jd.addParameter(jrparam);
      } catch (JRException e) {
        throw new CoreException(e.getMessage(),e);
      }
    }

  }

  public static JasperPrint generateJasperPrint(DynamicReport dr, LayoutManager layoutManager, JRDataSource ds) throws JRException {
        return generateJasperPrint(dr, layoutManager, ds, new HashMap());
    }

  public static JasperPrint generateJasperPrint(DynamicReport dr, LayoutManager layoutManager, Collection collection) throws JRException {
    JRDataSource ds = new JRBeanCollectionDataSource(collection);
    return generateJasperPrint(dr, layoutManager, ds, new HashMap());
  }

  public static JasperPrint generateJasperPrint(DynamicReport dr, LayoutManager layoutManager, ResultSet resultSet) throws JRException {
    JRDataSource ds = new JRResultSetDataSource(resultSet);
    return generateJasperPrint(dr, layoutManager, ds, new HashMap());
  }

  /**
   * Compiles and fills the reports design.
   *
   * @param dr the DynamicReport
   * @param layoutManager the object in charge of doing the layout
   * @param ds The datasource
   * @param _parameters Map with parameters that the report may need
   * @return
   * @throws JRException
   */
    public static JasperPrint generateJasperPrint(DynamicReport dr, LayoutManager layoutManager, JRDataSource ds, Map _parameters) throws JRException {
    log.info("generating JasperPrint");
    JasperPrint jp = null;

//      if (_parameters == null)
//        _parameters = new HashMap();
//
//      visitSubreports(dr, _parameters);
//      compileOrLoadSubreports(dr, _parameters);
//
//      DynamicJasperDesign jd = generateJasperDesign(dr);
//      Map params = new HashMap();
//      if (!_parameters.isEmpty()){
//        registerParams(jd,_parameters);
//        params.putAll(_parameters);
//      }
//
//      registerEntities(jd, dr);
//      layoutManager.applyLayout(jd, dr);
//            JRProperties.setProperty(JRProperties.COMPILER_CLASS, DJCompilerFactory.getCompilerClassName());
//
//            JasperReport jr = JasperCompileManager.compileReport(jd);
//            params.putAll(jd.getParametersWithValues());

            JasperReport jr = DynamicJasperHelper.generateJasperReport(dr, layoutManager, _parameters);
            jp = JasperFillManager.fillReport(jr, _parameters, ds);

            return jp;
  }

    /**
     * For running queries embebed in the report design
     * @param dr
     * @param layoutManager
     * @param con
     * @param _parameters
     * @return
     * @throws JRException
     */
    public static JasperPrint generateJasperPrint(DynamicReport dr, LayoutManager layoutManager, Connection con, Map _parameters) throws JRException {
      log.info("generating JasperPrint");
      JasperPrint jp = null;

      if (_parameters == null)
        _parameters = new HashMap();

      visitSubreports(dr, _parameters);
      compileOrLoadSubreports(dr, _parameters);

      DynamicJasperDesign jd = generateJasperDesign(dr);
      Map params = new HashMap();
      if (!_parameters.isEmpty()){
        registerParams(jd,_parameters);
        params.putAll(_parameters);
      }
      registerEntities(jd, dr, layoutManager);
      layoutManager.applyLayout(jd, dr);
      JRProperties.setProperty(JRCompiler.COMPILER_PREFIX, DJCompilerFactory.getCompilerClassName());
      JasperReport jr = JasperCompileManager.compileReport(jd);
      params.putAll(jd.getParametersWithValues());
      jp = JasperFillManager.fillReport(jr, params, con);

      return jp;
    }


    /**
     * For compiling and filling reports whose datasource is passed as parameter (e.g. Hibernate, Mondrean, etc.)
     * @param dr
     * @param layoutManager
     * @param _parameters
     * @return
     * @throws JRException
     */
    public static JasperPrint generateJasperPrint(DynamicReport dr, LayoutManager layoutManager, Map _parameters) throws JRException {
      log.info("generating JasperPrint");
      JasperPrint jp = null;

      if (_parameters == null)
        _parameters = new HashMap();

      visitSubreports(dr, _parameters);
      compileOrLoadSubreports(dr, _parameters);

      DynamicJasperDesign jd = generateJasperDesign(dr);
      Map params = new HashMap();
      if (!_parameters.isEmpty()){
        registerParams(jd,_parameters);
        params.putAll(_parameters);
      }
      registerEntities(jd, dr, layoutManager);
      layoutManager.applyLayout(jd, dr);
//      JRProperties.setProperty(JRProperties.COMPILER_CLASS, DJCompilerFactory.getCompilerClassName());
      JRProperties.setProperty(JRCompiler.COMPILER_PREFIX, DJCompilerFactory.getCompilerClassName());
      JasperReport jr = JasperCompileManager.compileReport(jd);
      params.putAll(jd.getParametersWithValues());
      jp = JasperFillManager.fillReport(jr, params);

      return jp;
    }

  /**
   * Creates a jrxml file
   * @param dr
   * @param layoutManager
   * @param _parameters
   * @param xmlEncoding (default is UTF-8 )
   * @return
   * @throws JRException
   */
    public static String generateJRXML(DynamicReport dr, LayoutManager layoutManager, Map _parameters, String xmlEncoding) throws JRException {
      JasperReport jr = generateJasperReport(dr, layoutManager, _parameters);
      if (xmlEncoding == null)
        xmlEncoding = DEFAULT_XML_ENCODING;
      return JRXmlWriter.writeReport(jr, xmlEncoding);
    }

    /**
     * Creates a jrxml file
     * @param dr
     * @param layoutManager
     * @param _parameters
     * @param xmlEncoding  (default is UTF-8 )
     * @param outputStream
     * @throws JRException
     */
    public static void generateJRXML(DynamicReport dr, LayoutManager layoutManager, Map _parameters, String xmlEncoding, OutputStream outputStream) throws JRException {
      JasperReport jr = generateJasperReport(dr, layoutManager, _parameters);
      if (xmlEncoding == null)
        xmlEncoding = DEFAULT_XML_ENCODING;
       JRXmlWriter.writeReport(jr, outputStream, xmlEncoding);
    }

    /**
     * Creates a jrxml file
     * @param dr
     * @param layoutManager
     * @param _parameters
     * @param xmlEncoding  (default is UTF-8 )
     * @param filename the path to the destination file
     * @throws JRException
     */
    public static void generateJRXML(DynamicReport dr, LayoutManager layoutManager, Map _parameters, String xmlEncoding, String filename) throws JRException {
      JasperReport jr = generateJasperReport(dr, layoutManager, _parameters);
      if (xmlEncoding == null)
        xmlEncoding = DEFAULT_XML_ENCODING;
     
      ensurePath(filename);
     
      JRXmlWriter.writeReport(jr, filename, xmlEncoding);
    }

    public static void generateJRXML(JasperReport jr, String xmlEncoding, String filename) throws JRException {
      if (xmlEncoding == null)
        xmlEncoding = DEFAULT_XML_ENCODING;
     
    ensurePath(filename);
     
      JRXmlWriter.writeReport(jr, filename, xmlEncoding);
    }

  private static void ensurePath(String filename) {
    File outputFile = new File(filename);
    File parentFile = outputFile.getParentFile();
    if (parentFile != null)
      parentFile.mkdirs();
  }

    protected static void compileOrLoadSubreports(DynamicReport dr, Map _parameters) throws JRException {
      for (Iterator iterator = dr.getColumnsGroups().iterator(); iterator.hasNext();) {
      DJGroup group = (DJGroup) iterator.next();

      //Header Subreports
      for (Iterator iterator2 = group.getHeaderSubreports().iterator(); iterator2.hasNext();) {
        Subreport subreport = (Subreport) iterator2.next();

        if (subreport.getDynamicReport() != null){
           compileOrLoadSubreports(subreport.getDynamicReport(),_parameters);
           JasperReport jp = generateJasperReport(subreport.getDynamicReport(), subreport.getLayoutManager(), _parameters);
           _parameters.put(jp.toString(), jp);
           subreport.setReport(jp);
        }

      }

      //Footer Subreports
      for (Iterator iterator2 = group.getFooterSubreports().iterator(); iterator2.hasNext();) {
        Subreport subreport = (Subreport) iterator2.next();

        if (subreport.getDynamicReport() != null){
          compileOrLoadSubreports(subreport.getDynamicReport(),_parameters);
          JasperReport jp = generateJasperReport(subreport.getDynamicReport(), subreport.getLayoutManager(), _parameters);
          _parameters.put(jp.toString(), jp);
          subreport.setReport(jp);
        }

      }
    }
  }

  /**
     * For every String key, it registers the object as a parameter to make it available
     * in the report.
     * @param jd
     * @param _parameters
     */
  public static void registerParams(DynamicJasperDesign jd, Map _parameters) {
    for (Iterator iterator = _parameters.keySet().iterator(); iterator.hasNext();) {
      Object key = iterator.next();
      if (key instanceof String){
        try {
          if (jd.getParametersMap().get(key) != null){
            log.warn("Parameter \"" + key + "\" already registered, skipping this one.");
            continue;
          }

          JRDesignParameter parameter = new JRDesignParameter();
          Object value = _parameters.get(key);

          if (value == null) //There are some Map implementations that allows nulls values, just go on
            continue;

//          parameter.setValueClassName(value.getClass().getCanonicalName());
          Class clazz = value.getClass().getComponentType();
          if (clazz == null)
            clazz = value.getClass();
          parameter.setValueClass(clazz); //NOTE this is very strange
          //when using an array as subreport-data-source, I must pass the parameter class name like this: value.getClass().getComponentType()
          parameter.setName((String)key);
          jd.addParameter(parameter);
        } catch (JRException e) {
          //nothing to do
        }
      }

    }

  }

  /**
   * Compiles the report and applies the layout. <b>generatedParams</b> MUST NOT BE NULL
   * All the key objects from the generatedParams map that are String, will be registered as parameters of the report.
   * @param dr
   * @param layoutManager
   * @param generatedParams
   * @return
   * @throws JRException
   */
  public final static JasperReport generateJasperReport(DynamicReport dr, LayoutManager layoutManager, Map generatedParams) throws JRException {
    log.info("generating JasperReport");
    JasperReport jr = null;
      if (generatedParams == null)
        generatedParams = new HashMap();

      visitSubreports(dr, generatedParams);
      compileOrLoadSubreports(dr, generatedParams);

      DynamicJasperDesign jd = generateJasperDesign(dr);
      registerEntities(jd, dr, layoutManager);

      registerParams(jd, generatedParams); //if we have parameters from the outside, we register them

      layoutManager.applyLayout(jd, dr);
      JRProperties.setProperty(JRCompiler.COMPILER_PREFIX, "ar.com.fdvs.dj.util.DJJRJdtCompiler");     
      jr = JasperCompileManager.compileReport(jd);
      generatedParams.putAll(jd.getParametersWithValues());
    return jr;
  }

/**
* Performs any needed operation on subreports after they are built like ensuring proper subreport with
* if "fitToParentPrintableArea" flag is set to true
* @param dr
* @param _parameters
* @throws JRException
*/
  protected static void visitSubreports(DynamicReport dr, Map _parameters) throws JRException{
      for (Iterator iterator = dr.getColumnsGroups().iterator(); iterator.hasNext();) {
      DJGroup group = (DJGroup) iterator.next();

      //Header Subreports
      for (Iterator iterator2 = group.getHeaderSubreports().iterator(); iterator2.hasNext();) {
        Subreport subreport = (Subreport) iterator2.next();

        if (subreport.getDynamicReport() != null){
          visitSubreport(dr,subreport,_parameters);
          visitSubreports(subreport.getDynamicReport(),_parameters);
        }

      }

      //Footer Subreports
      for (Iterator iterator2 = group.getFooterSubreports().iterator(); iterator2.hasNext();) {
        Subreport subreport = (Subreport) iterator2.next();

        if (subreport.getDynamicReport() != null){
          visitSubreport(dr,subreport,_parameters);
          visitSubreports(subreport.getDynamicReport(),_parameters);
        }

      }
    }

  }

  protected static void visitSubreport(DynamicReport parentDr, Subreport subreport, Map _parameters) {
    DynamicReport childDr = subreport.getDynamicReport();
    if (subreport.isFitToParentPrintableArea()){
      childDr.getOptions().setPage(parentDr.getOptions().getPage());
      childDr.getOptions().setLeftMargin(parentDr.getOptions().getLeftMargin());
      childDr.getOptions().setRightMargin(parentDr.getOptions().getRightMargin());
    }
  }

}
TOP

Related Classes of ar.com.fdvs.dj.core.DynamicJasperHelper

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.