Package net.sf.jasperreports.engine.data

Source Code of net.sf.jasperreports.engine.data.JRHibernateAbstractDataSource$FieldReader

/*
* JasperReports - Free Java Reporting Library.
* Copyright (C) 2001 - 2009 Jaspersoft Corporation. All rights reserved.
* http://www.jaspersoft.com
*
* Unless you have purchased a commercial license agreement from Jaspersoft,
* the following license terms apply:
*
* This program is part of JasperReports.
*
* JasperReports 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 3 of the License, or
* (at your option) any later version.
*
* JasperReports 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 JasperReports. If not, see <http://www.gnu.org/licenses/>.
*/
package net.sf.jasperreports.engine.data;

import java.util.HashMap;
import java.util.Map;

import net.sf.jasperreports.engine.JRDataSource;
import net.sf.jasperreports.engine.JRException;
import net.sf.jasperreports.engine.JRField;
import net.sf.jasperreports.engine.JRRuntimeException;
import net.sf.jasperreports.engine.query.JRHibernateQueryExecuter;

import org.apache.commons.beanutils.PropertyUtils;
import org.hibernate.type.Type;

/**
* Base abstract Hibernate data source.
*
* @author Lucian Chirita (lucianc@users.sourceforge.net)
* @version $Id: JRHibernateAbstractDataSource.java 3659 2010-03-31 10:20:49Z shertage $
*/
public abstract class JRHibernateAbstractDataSource implements JRDataSource
{
  private final boolean useFieldDescription;
  private final Map fieldReaders;
  protected final JRHibernateQueryExecuter queryExecuter;
  private Object currentReturnValue;
 
 
  /**
   * Creates a Hibernate data source.
   *
   * @param queryExecuter the query executer
   * @param useFieldDescription whether to use field descriptions for fields to results mapping
   * @param useIndexOnSingleReturn whether to use indexed addressing even when the query has only one return column
   */
  protected JRHibernateAbstractDataSource(JRHibernateQueryExecuter queryExecuter, boolean useFieldDescription, boolean useIndexOnSingleReturn)
  {
    this.useFieldDescription = useFieldDescription;
   
    this.queryExecuter = queryExecuter;

    fieldReaders = assignReaders(useIndexOnSingleReturn);
  }
 
  /**
   * Assigns field readers to report fields.
   *
   * @param useIndexOnSingleReturn  whether to use indexed addressing even when the query has only one return column
   * @return a report field name to field reader mapping
   * @see FieldReader
   */
  protected Map assignReaders(boolean useIndexOnSingleReturn)
  {
    Map readers = new HashMap();
   
    JRField[] fields = queryExecuter.getDataset().getFields();
    Type[] returnTypes = queryExecuter.getReturnTypes();
    String[] aliases = queryExecuter.getReturnAliases();
   
    Map aliasesMap = new HashMap();
    if (aliases != null)
    {
      for (int i = 0; i < aliases.length; i++)
      {
        aliasesMap.put(aliases[i], Integer.valueOf(i));
      }
    }
   
    if (returnTypes.length == 1)
    {
      if (returnTypes[0].isEntityType() || returnTypes[0].isComponentType())
      {
        for (int i = 0; i < fields.length; i++)
        {
          JRField field = fields[i];
          readers.put(field.getName(), getFieldReaderSingleReturn(aliasesMap, field, useIndexOnSingleReturn));
        }
      }
      else
      {
        if (fields.length > 1)
        {
          throw new JRRuntimeException("The HQL query returns only one non-entity and non-component result but there are more than one fields.");
        }
       
        if (fields.length == 1)
        {
          JRField field = fields[0];
          if (useIndexOnSingleReturn)
          {
            readers.put(field.getName(), new IndexFieldReader(0));
          }
          else
          {
            readers.put(field.getName(), new IdentityFieldReader());
          }
        }
      }
    }
    else
    {
      for (int i = 0; i < fields.length; i++)
      {
        JRField field = fields[i];
        readers.put(field.getName(), getFieldReader(returnTypes, aliasesMap, field));       
      }
    }

    return readers;
  }

  protected FieldReader getFieldReaderSingleReturn(Map aliasesMap, JRField field, boolean useIndex)
  {
    FieldReader reader;
   
    String fieldMapping = getFieldMapping(field);
    if (aliasesMap.containsKey(fieldMapping))
    {
      if (useIndex)
      {
        reader = new IndexFieldReader(0);
      }
      else
      {
        reader = new IdentityFieldReader();
      }
    }
    else
    {
      int firstNestedIdx = fieldMapping.indexOf(PropertyUtils.NESTED_DELIM);

      if (firstNestedIdx >= 0 && aliasesMap.containsKey(fieldMapping.substring(0, firstNestedIdx)))
      {
        fieldMapping = fieldMapping.substring(firstNestedIdx + 1);
      }

      if (useIndex)
      {
        reader = new IndexPropertyFieldReader(0, fieldMapping);
      }
      else
      {
        reader = new PropertyFieldReader(fieldMapping);
      }
    }
   
    return reader;
  }

  protected FieldReader getFieldReader(Type[] returnTypes, Map aliasesMap, JRField field)
  {
    FieldReader reader;
   
    String fieldMapping = getFieldMapping(field);
    Integer fieldIdx = (Integer) aliasesMap.get(fieldMapping);
    if (fieldIdx == null)
    {
      int firstNestedIdx = fieldMapping.indexOf(PropertyUtils.NESTED_DELIM);
     
      if (firstNestedIdx < 0)
      {
        throw new JRRuntimeException("Unknown HQL return alias \"" + fieldMapping + "\".");
      }
     
      String fieldAlias = fieldMapping.substring(0, firstNestedIdx);
      String fieldProperty = fieldMapping.substring(firstNestedIdx + 1);
     
      fieldIdx = (Integer) aliasesMap.get(fieldAlias);
      if (fieldIdx == null)
      {
        throw new JRRuntimeException("The HQL query does not have a \"" + fieldAlias + "\" alias.");
      }
     
      Type type = returnTypes[fieldIdx.intValue()];
      if (!type.isEntityType() && !type.isComponentType())
      {
        throw new JRRuntimeException("The HQL query does not have a \"" + fieldAlias + "\" alias.");
      }
     
      reader = new IndexPropertyFieldReader(fieldIdx.intValue(), fieldProperty);
    }
    else
    {
      reader = new IndexFieldReader(fieldIdx.intValue());
    }
   
    return reader;
  }

 
  /**
   * Sets the current row of the query result.
   *
   * @param currentReturnValue the current row value
   */
  protected void setCurrentRowValue(Object currentReturnValue)
  {
    this.currentReturnValue = currentReturnValue;
  }
 
 
  public Object getFieldValue(JRField jrField) throws JRException
  {
    FieldReader reader = (FieldReader) fieldReaders.get(jrField.getName());
    if (reader == null)
    {
      throw new JRRuntimeException("No filed reader for " + jrField.getName());
    }
    return reader.getFieldValue(currentReturnValue);
  }

 
  protected String getFieldMapping(JRField field)
  {
    return (useFieldDescription ?
          JRAbstractBeanDataSource.FIELD_DESCRIPTION_PROPERTY_NAME_PROVIDER :
          JRAbstractBeanDataSource.FIELD_NAME_PROPERTY_NAME_PROVIDER)
        .getPropertyName(field);
  }
 
 
  /**
   * Interface used to get the value of a report field from a result row.
   */
  protected static interface FieldReader
  {
    Object getFieldValue(Object resultValue) throws JRException;
  }
 
  protected static class IdentityFieldReader implements FieldReader
  {
    public Object getFieldValue(Object resultValue)
    {
      return resultValue;
   
  }
 
  protected static class IndexFieldReader implements FieldReader
  {
    private final int idx;

    protected IndexFieldReader(int idx)
    {
      this.idx = idx;
    }
   
    public Object getFieldValue(Object resultValue)
    {
      return ((Object[]) resultValue)[idx];
    }
  }
 
  protected static class PropertyFieldReader implements FieldReader
  {
    private final String property;

    protected PropertyFieldReader(String property)
    {
      this.property = property;
    }
   
    public Object getFieldValue(Object resultValue) throws JRException
    {
      return JRAbstractBeanDataSource.getBeanProperty(resultValue, property);
    }
  }
 
  protected static class IndexPropertyFieldReader implements FieldReader
  {
    private final int idx;
    private final String property;

    protected IndexPropertyFieldReader(int idx, String property)
    {
      this.idx = idx;
      this.property = property;
    }
   
    public Object getFieldValue(Object resultValue) throws JRException
    {
      return JRAbstractBeanDataSource.getBeanProperty(((Object[]) resultValue)[idx], property);
    }
  }
}
TOP

Related Classes of net.sf.jasperreports.engine.data.JRHibernateAbstractDataSource$FieldReader

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.