Package com.willowit.reporting

Source Code of com.willowit.reporting.PentahoRenderer

package com.willowit.reporting;

import java.io.ByteArrayOutputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Hashtable;

import org.apache.commons.lang3.exception.ExceptionUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.pentaho.reporting.engine.classic.core.AbstractReportDefinition;
import org.pentaho.reporting.engine.classic.core.ClassicEngineBoot;
import org.pentaho.reporting.engine.classic.core.CompoundDataFactory;
import org.pentaho.reporting.engine.classic.core.DataFactory;
import org.pentaho.reporting.engine.classic.core.MasterReport;
import org.pentaho.reporting.engine.classic.core.ReportElement;
import org.pentaho.reporting.engine.classic.core.RootLevelBand;
import org.pentaho.reporting.engine.classic.core.Section;
import org.pentaho.reporting.engine.classic.core.SubReport;
import org.pentaho.reporting.engine.classic.core.modules.misc.datafactory.sql.DriverConnectionProvider;
import org.pentaho.reporting.engine.classic.core.modules.misc.datafactory.sql.SQLReportDataFactory;
import org.pentaho.reporting.engine.classic.core.modules.output.pageable.pdf.PdfReportUtil;
import org.pentaho.reporting.engine.classic.core.modules.output.pageable.plaintext.PlainTextReportUtil;
import org.pentaho.reporting.engine.classic.core.modules.output.table.csv.CSVReportUtil;
import org.pentaho.reporting.engine.classic.core.modules.output.table.html.HtmlReportUtil;
import org.pentaho.reporting.engine.classic.core.modules.output.table.rtf.RTFReportUtil;
import org.pentaho.reporting.engine.classic.core.modules.output.table.xls.ExcelReportUtil;
import org.pentaho.reporting.engine.classic.core.parameters.DefaultParameterContext;
import org.pentaho.reporting.engine.classic.core.parameters.ListParameter;
import org.pentaho.reporting.engine.classic.core.parameters.ParameterAttributeNames;
import org.pentaho.reporting.engine.classic.core.parameters.ParameterDefinitionEntry;
import org.pentaho.reporting.engine.classic.core.parameters.ParameterValues;
import org.pentaho.reporting.engine.classic.core.parameters.ReportParameterDefinition;
import org.pentaho.reporting.engine.classic.core.parameters.ReportParameterValidator;
import org.pentaho.reporting.engine.classic.core.parameters.ValidationMessage;
import org.pentaho.reporting.engine.classic.core.parameters.ValidationResult;
import org.pentaho.reporting.engine.classic.core.util.ReportParameterValues;
import org.pentaho.reporting.engine.classic.extensions.datasources.openerp.OpenERPDataFactory;
import org.pentaho.reporting.libraries.fonts.LibFontBoot;
import org.pentaho.reporting.libraries.resourceloader.LibLoaderBoot;
import org.pentaho.reporting.libraries.resourceloader.Resource;
import org.pentaho.reporting.libraries.resourceloader.ResourceManager;

import com.debortoliwines.openerp.reporting.di.OpenERPFilterInfo;

public class PentahoRenderer {
  private static Log logger = LogFactory.getLog(PentahoRenderer.class);

  //One common manager instance to be initialised on startup
  private static ResourceManager manager;

  //Common method
  public static Exception bootPentaho() {
    Exception exception = null;
    if(ClassicEngineBoot.getInstance().isBootDone() == false) {
      LibLoaderBoot.getInstance().start();
      LibFontBoot.getInstance().start();
      ClassicEngineBoot.getInstance().start();

      exception = ClassicEngineBoot.getInstance().getBootFailureReason();
    }

    return exception;
  }

  public PentahoRenderer() {
    if(manager == null) {
      manager = new ResourceManager();
      manager.registerDefaults();
    }
  }

  //Internal functions
  //DBW
  private void fixOpenERPDataFactoryConfiguration(OpenERPDataFactory factory, HashMap<String, String> openerp_settings, HashMap<String, ?> parameters, Section section) {
    String selected_query_name = ((AbstractReportDefinition) section).getQuery();

    //Fix up connection parameters
    if(openerp_settings != null) {
      String openerp_host = openerp_settings.get("host");
      String openerp_port = openerp_settings.get("port");
      String openerp_db = openerp_settings.get("db");
      String openerp_login = openerp_settings.get("login");
      String openerp_password = openerp_settings.get("password");

      if(openerp_host != null)
        factory.getConfig().setHostName(openerp_host);
      if(openerp_port != null)
        factory.getConfig().setPortNumber(Integer.parseInt(openerp_port));
      if(openerp_db != null)
        factory.getConfig().setDatabaseName(openerp_db);
      if(openerp_login != null)
        factory.getConfig().setUserName(openerp_login);
      if(openerp_password != null)
        factory.getConfig().setPassword(openerp_password);
    }

    //Fix up filters for the main query on the main report
    //Skip subreports because it should join up with specific filters to the main report query
    if(parameters != null && parameters.get("ids") != null && section instanceof MasterReport && factory.getQueryName().equals(selected_query_name)) {
      String model_path = "[" + factory.getConfig().getModelName() + "]";
      boolean has_filters = false;
      ArrayList<OpenERPFilterInfo> filters = factory.getConfig().getFilters();

      for(OpenERPFilterInfo filter : filters) {
        if (filter.getModelPath().equals(model_path)) {
          has_filters = true;
          break;
        }
      }

      if(has_filters == false)
        filters.add(new OpenERPFilterInfo(model_path, 1, "", "id", "in", parameters.get("ids")));
    }
  }

  private SQLReportDataFactory fixSQLDataFactoryConfiguration(SQLReportDataFactory factory, HashMap<String, String> postgres_settings) throws Exception {
    SQLReportDataFactory new_factory;
    DriverConnectionProvider new_settings;

    String postgres_host = postgres_settings.get("host");
    String postgres_port = postgres_settings.get("port");
    String postgres_db = postgres_settings.get("db");
    String postgres_login = postgres_settings.get("login");
    String postgres_password = postgres_settings.get("password");

    if(postgres_host == null || postgres_db == null)
      throw new Exception("Invalid JDBC data source settings passed: PostgreS server's hostname (or IP address) and the database name must be set if specifying custom connection settings.");

    if(postgres_login == null)
      postgres_login = factory.getUserField();

    if(postgres_password == null)
      postgres_password = factory.getPasswordField();

    if(postgres_port == null)
      postgres_port = "5432";

    String jdbc_url = "jdbc:postgresql://" + postgres_host + ":" + postgres_port + "/" + postgres_db;

    new_settings = new DriverConnectionProvider();
    new_settings.setDriver("org.postgresql.Driver");
    new_settings.setUrl(jdbc_url);
    new_settings.setProperty("user", postgres_login);
    new_settings.setProperty("password", postgres_password);

    //The following may not be necessary since we set the JDBC URL
    new_settings.setProperty("::pentaho-reporting::name", "Custom PostgreS datasource");
    new_settings.setProperty("::pentaho-reporting::hostname", postgres_host);
    new_settings.setProperty("::pentaho-reporting::port", postgres_port);
    new_settings.setProperty("::pentaho-reporting::database-name", postgres_db);
    new_settings.setProperty("::pentaho-reporting::database-type", "POSTGRESQL");

    new_factory = new SQLReportDataFactory(new_settings);
    new_factory.setUserField(postgres_login);
    new_factory.setPasswordField(postgres_password);
    new_factory.setGlobalScriptLanguage(factory.getGlobalScriptLanguage());
    new_factory.setGlobalScript(factory.getGlobalScript());

    for(String one_query_name : factory.getQueryNames())
      new_factory.setQuery(one_query_name, factory.getQuery(one_query_name), factory.getScriptingLanguage(one_query_name), factory.getScript(one_query_name));

    return new_factory;
  }

  private void fixConfiguration(Section section, HashMap<String, String> openerp_settings, HashMap<String, String> postgres_settings, HashMap<String, ?> parameters) throws Exception {
    //If one of the datasources is an OpenERP datasource, reset the connection to the passed parameters
    if(section instanceof AbstractReportDefinition) {

      CompoundDataFactory factories = (CompoundDataFactory) ((AbstractReportDefinition) section).getDataFactory();
      for(int j = 0; j < factories.size(); j++) {
        DataFactory data_factory = factories.getReference(j);
        if(data_factory instanceof OpenERPDataFactory)
          fixOpenERPDataFactoryConfiguration((OpenERPDataFactory) data_factory, openerp_settings, parameters, section);
        else if(data_factory instanceof SQLReportDataFactory && postgres_settings != null) {
          String[] postgres_setting_names = {"host", "port", "db", "login", "password"};

          boolean custom_settings = false;
          for(String custom_setting_name : postgres_setting_names)
            custom_settings |= (postgres_settings.get(custom_setting_name) != null);

          if(custom_settings)
            factories.set(j, fixSQLDataFactoryConfiguration((SQLReportDataFactory) data_factory, postgres_settings));
        }
      }
    }

    //Go through all children and fix up their datasources too
    for(int i = 0; i < section.getElementCount(); i++) {
      ReportElement e = section.getElement(i);

      if(e instanceof Section)
        fixConfiguration((Section) e, openerp_settings, postgres_settings, parameters);
     
      // Fix subreports
      if (e instanceof RootLevelBand){
        for (SubReport sub : ((RootLevelBand) e).getSubReports()) 
          fixConfiguration((Section) sub, openerp_settings, postgres_settings, parameters);
      }
    }
  }

  //Checks the validity of parameters values set earlier
  //Not used at the moment
  private void checkParameters(MasterReport report) throws Exception {
    DefaultParameterContext param_context = new DefaultParameterContext(report);
    ReportParameterDefinition param_def = report.getParameterDefinition();
    ReportParameterValidator validator = param_def.getValidator();
    ValidationResult validation_result = validator.validate(new ValidationResult(), param_def, param_context);

    for(int i = 0; i < param_def.getParameterCount(); i++)
      for(ValidationMessage msg : validation_result.getErrors(param_def.getParameterDefinition(i).getName()))
        logger.info("Parameter Error: " + msg.getMessage());
  }

  //Helper functions
  private HashMap<String, Object> getParametersTypes(MasterReport report) throws Exception {
    ReportParameterDefinition param_def = report.getParameterDefinition();
    ParameterDefinitionEntry[] param_def_entries = param_def.getParameterDefinitions();

    HashMap<String, Object> name_to_type = new HashMap<String, Object>();

    for(ParameterDefinitionEntry param_def_entry : param_def_entries)
      name_to_type.put(param_def_entry.getName(), param_def_entry.getValueType());

    return name_to_type;
  }

  private void typeCastAndStore(ReportParameterValues target, String parameter_type, String parameter_name, Object parameter_value) {
    if(parameter_type.equals("java.lang.Long"))
      target.put(parameter_name, new Long(((Integer) parameter_value)));
    else if(parameter_type.equals("java.lang.Short"))
      target.put(parameter_name, ((Integer) parameter_value).shortValue());
    else if(parameter_type.equals("java.math.BigInteger"))
      target.put(parameter_name, java.math.BigInteger.valueOf(((Integer) parameter_value)));
    else if(parameter_type.equals("java.lang.Float"))
      target.put(parameter_name, ((Double) parameter_value).floatValue());
    else if(parameter_type.equals("java.math.BigDecimal"))
      target.put(parameter_name, java.math.BigDecimal.valueOf(((Double) parameter_value)));
    else if(parameter_type.equals("java.sql.Date"))
      target.put(parameter_name, new java.sql.Date(((java.util.Date) parameter_value).getTime()));
    else if(parameter_type.equals("java.sql.Time"))
      target.put(parameter_name, new java.sql.Time(((java.util.Date) parameter_value).getTime()));
    else if(parameter_type.equals("java.sql.Timestamp"))
      target.put(parameter_name, new java.sql.Timestamp(((java.util.Date) parameter_value).getTime()));
    else
      target.put(parameter_name, parameter_value);
  }

  private byte[] renderReport(MasterReport report, String output_type) throws Exception {
    //Create the report output stream
    ByteArrayOutputStream report_bin_out = new ByteArrayOutputStream();

    if(output_type.equals("pdf"))
      PdfReportUtil.createPDF(report, report_bin_out);
    else if(output_type.equals("xls"))
      ExcelReportUtil.createXLS(report, report_bin_out);
    else if(output_type.equals("xlsx"))
      ExcelReportUtil.createXLSX(report, report_bin_out);
    else if(output_type.equals("csv"))
      CSVReportUtil.createCSV(report, report_bin_out, null);
    else if(output_type.equals("rtf"))
      RTFReportUtil.createRTF(report, report_bin_out);
    else if(output_type.equals("html"))
      HtmlReportUtil.createStreamHTML(report, report_bin_out);
    else if(output_type.equals("txt"))
      PlainTextReportUtil.createPlainText(report, report_bin_out);

    return report_bin_out.toByteArray();
  }

  //Exported methods
  @SuppressWarnings("unchecked")
  public ArrayList<HashMap<String, ?>> getParameterInfo(Hashtable<String, ?> args) throws Exception {
    ArrayList<HashMap<String, ?>> ret_val = new ArrayList<HashMap<String, ?>>();

    //FIXME: redundant code
    HashMap<String, Object> parameters = new HashMap<String, Object>();
    HashMap<String, HashMap<String, ?>> connection_settings = new HashMap<String, HashMap<String, ?>>();
    HashMap<String, String> openerp_settings = new HashMap<String, String>();
    HashMap<String, String> postgres_settings = new HashMap<String, String>();

    try {
      byte[] prpt_file_content = (byte[]) args.get("prpt_file_content");

      if(prpt_file_content == null)
        throw new Exception("No report content sent!");   

      //FIXME: redundant code
      connection_settings = (HashMap<String, HashMap<String, ?>>) args.get("connection_settings");
      parameters = (HashMap<String, Object>) args.get("report_parameters");
      openerp_settings = (HashMap<String, String>) connection_settings.get("openerp");
      postgres_settings = (HashMap<String, String>) connection_settings.get("postgres");

      Resource res = manager.createDirectly(prpt_file_content, MasterReport.class);
      MasterReport report = (MasterReport) res.getResource();

      fixConfiguration(report, openerp_settings, postgres_settings, parameters);
     
      if (parameters != null){
        HashMap<String, Object> parameters_types = getParametersTypes(report);
        // Set parameters available
        ReportParameterValues values = report.getParameterValues();
        for(String parameter_name : parameters.keySet()) {
          Object parameter_value = parameters.get(parameter_name);
 
          if(parameters_types.get(parameter_name) != null){
            typeCastAndStore(values, ((Class<?>) parameters_types.get(parameter_name)).getName(), parameter_name, parameter_value);
          }
        }
      }

      //New stuff
      ReportParameterDefinition param_def = report.getParameterDefinition();
      ParameterDefinitionEntry[] param_def_entries = param_def.getParameterDefinitions();
      DefaultParameterContext param_context = new DefaultParameterContext(report);
      for(ParameterDefinitionEntry param_def_entry : param_def_entries) {
        HashMap<String, Object> one_param_info = new HashMap<String, Object>();
        HashMap<String, Object> core_namespace_attributes = new HashMap<String, Object>();

        one_param_info.put("name", param_def_entry.getName());
        one_param_info.put("value_type", param_def_entry.getValueType().getName());
        one_param_info.put("is_mandatory", param_def_entry.isMandatory());

        Object default_value = param_def_entry.getDefaultValue(param_context);
        if(default_value != null) {
          String param_def_entry_type = param_def_entry.getValueType().getName();

          if(param_def_entry_type.equals("java.lang.Long"))
            default_value = ((Long) default_value).intValue();
          else if(param_def_entry_type.equals("java.lang.Short"))
            default_value = ((java.lang.Short) default_value).intValue();
          else if(param_def_entry_type.equals("java.math.BigInteger"))
            default_value = ((java.math.BigInteger) default_value).intValue();
          else if(param_def_entry_type.equals("java.lang.Number"))
            default_value = ((Number) default_value).doubleValue();
          else if(param_def_entry_type.equals("java.lang.Float"))
            default_value = ((Float) default_value).doubleValue();
          else if(param_def_entry_type.equals("java.math.BigDecimal"))
            default_value = ((java.math.BigDecimal) default_value).doubleValue();

          one_param_info.put("default_value", default_value);
        }
        one_param_info.put("attributes", core_namespace_attributes);

        String[] param_attr_names = param_def_entry.getParameterAttributeNames(ParameterAttributeNames.Core.NAMESPACE);
        for(String param_attr_name : param_attr_names) {
          String param_attr = param_def_entry.getParameterAttribute(ParameterAttributeNames.Core.NAMESPACE, param_attr_name, param_context);
          core_namespace_attributes.put(param_attr_name, param_attr);
          logger.debug("Attribute: " + param_attr_name + " = " + param_attr);
        }

        if(param_def_entry instanceof ListParameter) {
          ParameterValues param_vals = ((ListParameter) param_def_entry).getValues(param_context);
          int num_options = param_vals.getRowCount();
          ArrayList<ArrayList<Object>> selection_options = new ArrayList<ArrayList<Object>>(num_options);

          for(int i = 0; i < num_options; i++) {
            ArrayList<Object> one_option = new ArrayList<Object>();

            one_option.add(param_vals.getKeyValue(i));
            one_option.add(param_vals.getTextValue(i));

            selection_options.add(one_option);
            logger.debug("Selection option: {" + param_vals.getKeyValue(i) + ": " + param_vals.getTextValue(i) + "}");
          }

          one_param_info.put("selection_options", selection_options);
        }

        ret_val.add(one_param_info);
      }

      return ret_val;
    } catch(Exception exception) {
      logger.error(exception.getMessage());
      logger.error(ExceptionUtils.getStackTrace(exception));

      throw exception;
    }
  }

  @SuppressWarnings("unchecked")
  public byte[] execute(Hashtable<String, ?> args) throws Exception {
    byte[] prpt_file_content = null;
    String output_type = null;

    HashMap<String, Object> parameters = new HashMap<String, Object>();
    HashMap<String, HashMap<String, ?>> connection_settings = new HashMap<String, HashMap<String, ?>>();
    HashMap<String, String> openerp_settings = new HashMap<String, String>();
    HashMap<String, String> postgres_settings = new HashMap<String, String>();

    logger.debug(args);

    try {
      prpt_file_content = (byte[]) args.get("prpt_file_content");
      output_type = (String) args.get("output_type");

      if(prpt_file_content == null)
        throw new Exception("No report content sent!");   

      if(output_type == null)
        output_type = "pdf";

      connection_settings = (HashMap<String, HashMap<String, ?>>) args.get("connection_settings");
      parameters = (HashMap<String, Object>) args.get("report_parameters");
      openerp_settings = (HashMap<String, String>) connection_settings.get("openerp");
      postgres_settings = (HashMap<String, String>) connection_settings.get("postgres");

      //Load the report (we may be overriding Pentaho's caching mechanisms by doing this
      Resource res = manager.createDirectly(prpt_file_content, MasterReport.class);
      MasterReport report = (MasterReport) res.getResource();
      HashMap<String, Object> parameters_types = getParametersTypes(report);

      //Fix up data sources specified by parameters passed in
      fixConfiguration(report, openerp_settings, postgres_settings, parameters);

      //Pass through other parameters
      ReportParameterValues values = report.getParameterValues();
      for(String parameter_name : parameters.keySet()) {
        Object parameter_value = parameters.get(parameter_name);

        if(parameters_types.get(parameter_name) != null)
          typeCastAndStore(values, ((Class<?>) parameters_types.get(parameter_name)).getName(), parameter_name, parameter_value);
      }

      return renderReport(report, output_type);
    } catch(Exception exception) {
      logger.error(exception.getMessage());
      logger.error(ExceptionUtils.getStackTrace(exception));

      throw exception;
    }
  }
}
TOP

Related Classes of com.willowit.reporting.PentahoRenderer

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.