Package net.sf.jasperreports.engine.fill

Source Code of net.sf.jasperreports.engine.fill.DatasetSortUtil

/*
* 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.fill;

import java.text.Collator;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
import java.util.Locale;
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.JRParameter;
import net.sf.jasperreports.engine.JRRuntimeException;
import net.sf.jasperreports.engine.JRScriptletException;
import net.sf.jasperreports.engine.JRSortField;
import net.sf.jasperreports.engine.JRVariable;
import net.sf.jasperreports.engine.data.ListOfArrayDataSource;
import net.sf.jasperreports.engine.design.JRDesignDatasetRun;
import net.sf.jasperreports.engine.type.SortFieldTypeEnum;
import net.sf.jasperreports.engine.type.SortOrderEnum;


/**
* @author Teodor Danciu (teodord@users.sourceforge.net)
* @version $Id: DatasetSortUtil.java 4194 2011-02-21 08:34:39Z teodord $
*/
public class DatasetSortUtil
{


  /**
   * Returns all current sort field criteria, including the dynamic ones provided as report parameter.
   */
  public static JRSortField[] getAllSortFields(JRFillDataset dataset)
  {
    List allSortFields = new ArrayList();
   
    JRSortField[] staticSortFields = dataset.getSortFields();
    if (staticSortFields != null)
    {
      allSortFields.addAll(Arrays.asList(staticSortFields));
    }

    List dynamicSortFields = (List)dataset.getParameterValue(JRParameter.SORT_FIELDS, true);
    if (dynamicSortFields != null)
    {
      allSortFields.addAll(dynamicSortFields);
    }

    return (JRSortField[]) allSortFields.toArray(new JRSortField[allSortFields.size()]);
  }


  /**
   *
   */
  public static boolean needSorting(JRFillDataset dataset)
  {
    JRSortField[] staticSortFields = dataset.getSortFields();
    List dynamicSortFields = (List)dataset.getParameterValue(JRParameter.SORT_FIELDS, true);
   
    return
      (staticSortFields != null
      && staticSortFields.length > 0)
      || (dynamicSortFields != null
      && dynamicSortFields.size() > 0);
  }


  /**
   *
   */
  public static JRDataSource getSortedDataSource(
    JRBaseFiller filler,
    JRFillDataset dataset,
    Locale locale
    ) throws JRException
  {
    SortInfo sortInfo = createSortInfo(dataset);
   
    SortFillDatasetRun sortDatasetRun = new SortFillDatasetRun(filler, dataset, sortInfo);
   
    List records = sortDatasetRun.sort();
   
    /*   */
    Collections.sort(
      records,
      new DataSourceComparator(
        sortInfo.sortFieldInfo,
        locale
        )
      );
   
    return new ListOfArrayDataSource(records, (String[]) sortInfo.fieldNames.toArray(new String[sortInfo.fieldNames.size()]));
  }


  /**
   *
   */
  private static SortInfo createSortInfo(JRFillDataset dataset) throws JRException
  {
    SortInfo sortInfo = new SortInfo();

    Map fieldsMap = new HashMap();
    Map fieldIndexMap = new HashMap();
    JRField[] fields = dataset.getFields();
    if (fields != null)
    {
      for(int i = 0; i < fields.length; i++)
      {
        JRField field = fields[i];
        fieldsMap.put(field.getName(), field);
        fieldIndexMap.put(field.getName(), Integer.valueOf(i));
        sortInfo.fieldNames.add(field.getName());
      }
    }

    Map variablesMap = new HashMap();
    JRVariable[] variables = dataset.getVariables();
    if (variables != null)
    {
      for(int i = 0; i < variables.length; i++)
      {
        variablesMap.put(variables[i].getName(), variables[i]);
      }
    }

    JRSortField[] sortFields = getAllSortFields(dataset);
    if (sortFields != null)
    {
      sortInfo.sortFieldInfo = new SortFieldInfo[sortFields.length];

      for(int i = 0; i < sortFields.length; i++)
      {
        JRSortField sortField = sortFields[i];

        String sortFieldName = sortField.getName();
       
        SortFieldInfo info = new SortFieldInfo();
       
        info.name = sortFieldName;
        info.isVariable = sortField.getType() == SortFieldTypeEnum.VARIABLE;
        info.order = (SortOrderEnum.ASCENDING == sortField.getOrderValue() ? 1 : -1);

        Integer index;
        if (info.isVariable)
        {
          JRVariable variable = (JRVariable)variablesMap.get(sortFieldName);
          if (variable == null)
          {
            throw new JRRuntimeException("Sort variable \"" + sortFieldName + "\" not found in dataset.");
          }
         
          index = new Integer(sortInfo.fieldNames.size());
          info.collatorFlag = String.class.getName().equals(variable.getValueClassName());
         
          sortInfo.fieldNames.add(variable.getName());
        }
        else
        {
          JRField field = (JRField)fieldsMap.get(sortFieldName);
          if (field == null)
          {
            throw new JRRuntimeException("Sort field \"" + sortFieldName + "\" not found in dataset.");
          }
         
          index = (Integer)fieldIndexMap.get(sortField.getName());

          info.collatorFlag = String.class.getName().equals(field.getValueClassName());
        }
        info.index = index.intValue();

        sortInfo.sortFieldInfo[i] = info;
      }
    }
   
    return sortInfo;
  }

 
}


/**
*
*/
class DataSourceComparator implements Comparator
{
  Collator collator;
  SortFieldInfo[] sortFieldInfo;

  public DataSourceComparator(SortFieldInfo[] sortFieldInfo, Locale locale)
  {
    this.collator = Collator.getInstance(locale);
    this.sortFieldInfo = sortFieldInfo;
  }

  public int compare(Object arg1, Object arg2)
  {
    Object[] record1 = (Object[])arg1;
    Object[] record2 = (Object[])arg2;

    int ret = 0;

    for(int i = 0; i < sortFieldInfo.length; i++)
    {
      SortFieldInfo info = sortFieldInfo[i];
     
      Comparable field1 = (Comparable)record1[info.index];
      Comparable field2 = (Comparable)record2[info.index];

      if (field1 == null)
      {
        ret = (field2 == null) ? 0 : -1;
      }
      else if (field2 == null)
      {
        ret = 1;
      }
      else
      {
        if (info.collatorFlag)
        {
          ret = collator.compare(field1, field2);
        }
        else
        {
          ret = field1.compareTo(field2);
        }
      }

      ret = ret * info.order;

      if (ret != 0)
      {
        return ret;
      }
    }

    return ret;
  }
}


/**
*
*/
class SortInfo
{
  public List fieldNames = new ArrayList();
  public SortFieldInfo[] sortFieldInfo;
}


/**
*
*/
class SortFieldInfo
{
  public String name;
  public boolean isVariable;
  public int order;
  public int index;
  public boolean collatorFlag;
}


/**
* Used to iterate on a subdataset and create a sorted data source.
*
* @author Teodor Danciu (teodord@users.sourceforge.net)
* @version $Id: DatasetSortUtil.java 4194 2011-02-21 08:34:39Z teodord $
*/
class SortFillDatasetRun extends JRFillDatasetRun
{

  private JRSortField[] allSortFields;
  private SortInfo sortInfo;
  private List records;

 
  public SortFillDatasetRun(JRBaseFiller filler, JRFillDataset dataset, SortInfo sortInfo) throws JRException
  {
    super(
      filler,
      new JRDesignDatasetRun(), //we don't need anything from a dataset run. just avoid NPEs down the call
      dataset
      );
   
    allSortFields = DatasetSortUtil.getAllSortFields(dataset);

    this.sortInfo = sortInfo;
  }

 
  public List sort() throws JRException
  {
    records = new ArrayList();

    try
    {
      //all parameters are already set onto the dataset by the main fill process

      iterate();
    }
    finally
    {
      dataset.closeDatasource();
    }
   
    return records;
  }

 
  @Override
  protected void detail() throws JRScriptletException, JRException
  {
    super.detail();
   
    JRField[] fields = dataset.getFields();
    Object[] record = new Object[sortInfo.fieldNames.size()];
    for(int i = 0; i < fields.length; i++)
    {
      record[i] = dataset.getFieldValue(fields[i].getName());
    }
    for(int i = 0; i < allSortFields.length; i++)
    {
      JRSortField sortField = allSortFields[i];
      if (sortField.getType() == SortFieldTypeEnum.VARIABLE)
      {
        record[sortInfo.sortFieldInfo[i].index] = dataset.getVariableValue(sortField.getName());
      }
    }
    records.add(record);
  }
}
TOP

Related Classes of net.sf.jasperreports.engine.fill.DatasetSortUtil

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.