Package org.pentaho.reporting.engine.classic.extensions.datasources.openerp

Source Code of org.pentaho.reporting.engine.classic.extensions.datasources.openerp.OpenERPDataFactory

/*
* This program is free software; you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License, version 2.1 as published by the Free Software
* Foundation.
*
* You should have received a copy of the GNU Lesser General Public License along with this
* program; if not, you can obtain a copy at http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html
* or from the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
* This program 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.
*
* Copyright (c) 2011 - 2012 De Bortoli Wines Pty Limited (Australia). All Rights Reserved.
*/

package org.pentaho.reporting.engine.classic.extensions.datasources.openerp;

import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import javax.swing.table.TableModel;

import com.debortoliwines.openerp.api.Field.FieldType;
import com.debortoliwines.openerp.reporting.di.OpenERPConfiguration;
import com.debortoliwines.openerp.reporting.di.OpenERPFieldInfo;
import com.debortoliwines.openerp.reporting.di.OpenERPFilterInfo;
import com.debortoliwines.openerp.reporting.di.OpenERPHelper;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.ws.commons.util.Base64;
import org.apache.ws.commons.util.Base64.DecodingException;
import org.pentaho.reporting.engine.classic.core.AbstractDataFactory;
import org.pentaho.reporting.engine.classic.core.DataRow;
import org.pentaho.reporting.engine.classic.core.ReportDataFactoryException;
import org.pentaho.reporting.engine.classic.core.util.PropertyLookupParser;
import org.pentaho.reporting.engine.classic.core.util.TypedTableModel;

/**
* @author Pieter van der Merwe
*/
public class OpenERPDataFactory extends AbstractDataFactory
{
  private static final long serialVersionUID = -6235833289788633577L;
  private static final Log logger = LogFactory.getLog(OpenERPDataFactory.class);

  private OpenERPConfiguration config;
  private String queryName;

  public OpenERPDataFactory()
  {
  }

  /**
   * Checks whether the query would be executable by this datafactory. This performs a rough check, not a full query.
   *
   * @param query
   * @param parameters
   * @return
   */
  public boolean isQueryExecutable(final String query, final DataRow parameters)
  {
    return queryName.equals(query);
  }

  public String[] getQueryNames()
  {
    return new String[]{queryName};
  }

  /**
   * Queries a datasource. The string 'query' defines the name of the query. The Parameterset given here may contain
   * more data than actually needed.
   * <p/>
   * The dataset may change between two calls, do not assume anything!
   *
   * @param query
   * @param parameters
   * @return
   */
  public synchronized TableModel queryData(final String query, final DataRow parameters)
      throws ReportDataFactoryException
  {

    /// TODO: Add more validation Here
    if (config == null)
    {
      throw new ReportDataFactoryException("Configuration is empty."); //$NON-NLS-1$
    }

    final TypedTableModel resultSet = new TypedTableModel();

    final int queryLimit = calculateQueryLimit(parameters);
    final OpenERPHelper helper = new OpenERPHelper();
    final OpenERPConfiguration targetConfig = config.clone();
    final ArrayList<OpenERPFilterInfo> configFilters = targetConfig.getFilters();

    // Build a hashmap to pass all parameters as a dictionary to a custom OpenERP procedure
    final HashMap<String, Object> openERPParams = new HashMap<String, Object>();
    for (final String paramName : parameters.getColumnNames())
    {
      Object value = parameters.get(paramName);
      if (value == null)
      {
        value = false;
      }

      openERPParams.put(paramName, value);
    }

    // Can't get selected fields from config, because we may be calling a custom function
    ArrayList<OpenERPFieldInfo> selectedFields = null;
    try
    {
      selectedFields = helper.getFields(targetConfig, openERPParams);
    }
    catch (Exception e1)
    {
      throw new ReportDataFactoryException("Failed to select field", e1);
    }

    // Build a field list
    for (final OpenERPFieldInfo selectedFld : selectedFields)
    {
      resultSet.addColumn(selectedFld.getRenamedFieldName(), convertFieldType(selectedFld.getFieldType()));
    }

    // Called by the designer to get column layout, return a empty resultSet with columns already set
    if (queryLimit == 1)
    {
      return resultSet;
    }

    // Parameter parser to replace parameters in strings
    final PropertyLookupParser parameterParser = new PropertyLookupParser()
    {
      private static final long serialVersionUID = -7264648195698966110L;

      @Override
      protected String lookupVariable(final String property)
      {
        return parameters.get(property).toString();
      }
    };

    // Replace parameterized filters with values from parameters
    if (configFilters != null)
    {
      for (final OpenERPFilterInfo filter : configFilters)
      {
        // You could have set a filter without using the Designer.  Then the filter could be any data type that should not be converted to a String.
        if (filter.getValue() instanceof String)
        {
          try
          {
            final String realFilterValue = filter.getValue().toString();

            // If you specify the filter on its own, try in get the object value
            // Not all parameter values are a string.  Could be an Object[] of ids for example in a multi-select parameter
            final Object filterValue;
            if (realFilterValue.length() >= 4
                && realFilterValue.substring(0, 2).equals("${")
                && realFilterValue.endsWith("}"))
            {

              final String parameterName = realFilterValue.substring(2, realFilterValue.length() - 1);
              filterValue = parameters.get(parameterName);
            }
            // Cater for cases where users specify compound filer: "name" "like" "some${post_fix}"
            else
            {
              filterValue = parameterParser.translateAndLookup(realFilterValue, parameters);
            }

            // If the value is null, this may be a dependent query and it is waiting for a parameter.
            // just return and wait
            if (filterValue == null)
            {
              return resultSet;
            }

            filter.setValue(filterValue);
          }
          catch (Exception e)
          {
            throw new ReportDataFactoryException(e.getMessage(), e);
          }
        }
      }
    }

    // Get the data
    final Object[][] rows;
    try
    {
      rows = helper.getData(targetConfig, openERPParams);
    }
    catch (Exception e)
    {
      throw new ReportDataFactoryException(e.getMessage(), e);
    }

    // Add data to resultSet and do some data transformations
    for (int row = 0; row < rows.length; row++)
    {
      final Object[] rowData = rows[row];

      for (int column = 0; column < selectedFields.size(); column++)
      {
        final OpenERPFieldInfo fld = selectedFields.get(column);

        // Base64 Decode Binary
        if (fld.getFieldType() == FieldType.BINARY
            && rowData[column] != null)
        {
          try
          {
            rowData[column] = Base64.decode(rowData[column].toString());
          }
          catch (DecodingException e)
          {
            rowData[column] = "Unable to decode string";
          }
          catch (Exception e)
          {
            logger.debug("Failed to decode string on query-result: Row=" + row + " Col=" + column, e);
          }
        }

        // Only return integer part (exclude name) from many2one field
        if (fld.getFieldType() == FieldType.MANY2ONE
            && rowData[column] instanceof Object[])
        {
          final Object[] value = (Object[]) rowData[column];
          rowData[column] = Integer.parseInt(String.valueOf(value[0]));
        }

        // make many2many and one2many a comma separated list of values
        if ((fld.getFieldType() == FieldType.MANY2MANY || fld.getFieldType() == FieldType.ONE2MANY)
            && rowData[column] instanceof Object[])
        {

          final StringBuilder stringValue = new StringBuilder();
          final Object[] mcolumn = (Object[]) rowData[column];
          for (int x = 0; x < mcolumn.length; x += 1)
          {
            if (x != 0)
            {
              stringValue.append(',');
            }
            stringValue.append(mcolumn[x]);
          }

          rowData[column] = stringValue.toString();
        }
      }

      resultSet.addRow(rowData);
    }
    return resultSet;
  }

  private Class<?> convertFieldType(final FieldType fieldType)
  {
    switch (fieldType)
    {
      case BINARY:
        return Byte[].class;
      case BOOLEAN:
        return Boolean.class;
      case INTEGER:
        return Integer.class;
      case FLOAT:
        return Float.class;
      case DATETIME:
      case DATE:
        return Date.class;
      case MANY2ONE:
        return Integer.class;
      case ONE2MANY:
      case MANY2MANY:
      case CHAR:
      case TEXT:
      default:
        return String.class;
    }
  }

  public void setConfig(final OpenERPConfiguration config)
  {
    this.config = config;
  }

  public String getQueryName()
  {
    return queryName;
  }

  public void setQueryName(final String queryName)
  {
    this.queryName = queryName;
  }

  public void close()
  {
  }

  public OpenERPDataFactory clone()
  {
    final OpenERPDataFactory dataFactory = (OpenERPDataFactory) super.clone();
    if (this.config != null)
    {
      dataFactory.config = this.config.clone();
    }
    return dataFactory;
  }

  public OpenERPConfiguration getConfig()
  {
    return config;
  }
}
TOP

Related Classes of org.pentaho.reporting.engine.classic.extensions.datasources.openerp.OpenERPDataFactory

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.