Package org.goobi.production.flow.statistics.hibernate

Source Code of org.goobi.production.flow.statistics.hibernate.StatQuestThroughput$DataTableComparator

package org.goobi.production.flow.statistics.hibernate;

/**
* This file is part of the Goobi Application - a Workflow tool for the support of mass digitization.
*
* Visit the websites for more information.
*         - http://www.goobi.org
*         - http://launchpad.net/goobi-production
*         - http://gdz.sub.uni-goettingen.de
*       - http://www.intranda.com
*       - http://digiverso.com
*
* This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free
* Software Foundation; either version 2 of the License, or (at your option) any later version.
*
* 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59
* Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* Linking this library statically or dynamically with other modules is making a combined work based on this library. Thus, the terms and conditions
* of the GNU General Public License cover the whole combination. As a special exception, the copyright holders of this library give you permission to
* link this library with independent modules to produce an executable, regardless of the license terms of these independent modules, and to copy and
* distribute the resulting executable under terms of your choice, provided that you also meet, for each linked independent module, the terms and
* conditions of the license of that module. An independent module is a module which is not derived from or based on this library. If you modify this
* library, you may extend this exception to your version of the library, but you are not obliged to do so. If you do not wish to do so, delete this
* exception statement from your version.
*/

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.Date;
import java.util.List;

import org.apache.log4j.Logger;
import org.goobi.production.flow.statistics.IDataSource;
import org.goobi.production.flow.statistics.IStatisticalQuestion;
import org.goobi.production.flow.statistics.IStatisticalQuestionLimitedTimeframe;
import org.goobi.production.flow.statistics.enums.CalculationUnit;
import org.goobi.production.flow.statistics.enums.StatisticsMode;
import org.goobi.production.flow.statistics.enums.TimeUnit;
import org.hibernate.SQLQuery;
import org.hibernate.Session;
import org.hibernate.type.StandardBasicTypes;

import de.intranda.commons.chart.renderer.ChartRenderer;
import de.intranda.commons.chart.renderer.IRenderer;
import de.intranda.commons.chart.results.DataRow;
import de.intranda.commons.chart.results.DataTable;
import de.sub.goobi.helper.Helper;
import de.sub.goobi.helper.enums.HistoryEventType;

/*****************************************************************************
* Imlpementation of {@link IStatisticalQuestion}. Statistical Request with
* predefined Values in data Table
*
* @author Wulf Riebensahm
****************************************************************************/
public class StatQuestThroughput implements IStatisticalQuestionLimitedTimeframe {

  private Date timeFilterFrom;
  private TimeUnit timeGrouping;
  private Date timeFilterTo;
  private List<Integer> myIDlist;
  private Boolean flagIncludeLoops = false;

  /**
   * loops included means that all step open all stepdone are considered loops
   * not included means that only min(date) or max(date) - depending on option
   * in
   *
   * @see historyEventType
   *
   * @return status of loops included or not
   */
  public Boolean getIncludeLoops() {
    return this.flagIncludeLoops;
  }

  /**
   * Set status of loops included
   *
   * @param includeLoops
   */
  public void setIncludeLoops(Boolean includeLoops) {
    this.flagIncludeLoops = includeLoops;
  }

  final private Logger myLogger = Logger.getLogger(StatQuestThroughput.class);

  /*
   * (non-Javadoc)
   *
   * @see
   * org.goobi.production.flow.statistics.IStatisticalQuestion#setTimeUnit
   * (org.goobi.production.flow.statistics.enums.TimeUnit)
   */
  @Override
  public void setTimeUnit(TimeUnit timeGrouping) {
    this.timeGrouping = timeGrouping;
  }

  /*
   * (non-Javadoc)
   *
   * @see
   * org.goobi.production.flow.statistics.IStatisticalQuestion#getDataTables
   * (org.goobi.production.flow.statistics.IDataSource)
   */
  @Override
  public List<DataTable> getDataTables(IDataSource dataSource) {

    List<DataTable> allTables = new ArrayList<DataTable>();

    IEvaluableFilter originalFilter;

    if (dataSource instanceof IEvaluableFilter) {
      originalFilter = (IEvaluableFilter) dataSource;
    } else {
      throw new UnsupportedOperationException("This implementation of IStatisticalQuestion needs an IDataSource for method getDataSets()");
    }

    // gathering IDs from the filter passed by dataSource
    try {
      this.myIDlist = originalFilter.getIDList();
    } catch (UnsupportedOperationException e) {
    }

    if (myIDlist == null || myIDlist.size() == 0) {
      return null;
    }
    /*
     * ======================================================================
     * ==============
     */

    // a list of DataTables is expected as return Object, even if there is
    // only one
    // Data Table as it is here in this implementation
    DataTable tableStepOpenAndDone = getAllSteps(HistoryEventType.stepOpen);
    tableStepOpenAndDone.setUnitLabel(Helper.getTranslation(this.timeGrouping.getSingularTitle()));
    tableStepOpenAndDone.setName(StatisticsMode.getByClassName(this.getClass()).getTitle() + " (" + Helper.getTranslation("openSteps") + ")");
    tableStepOpenAndDone = tableStepOpenAndDone.getDataTableInverted();
    tableStepOpenAndDone = tableStepOpenAndDone.getDataTableInverted();
    tableStepOpenAndDone.setShowableInChart(false);
    allTables.add(tableStepOpenAndDone);

    tableStepOpenAndDone = getAllSteps(HistoryEventType.stepDone);
    tableStepOpenAndDone.setUnitLabel(Helper.getTranslation(this.timeGrouping.getSingularTitle()));
    tableStepOpenAndDone.setName(StatisticsMode.getByClassName(this.getClass()).getTitle() + " (" + Helper.getTranslation("doneSteps") + ")");
    tableStepOpenAndDone.setShowableInChart(false);
    tableStepOpenAndDone = tableStepOpenAndDone.getDataTableInverted();
    tableStepOpenAndDone = tableStepOpenAndDone.getDataTableInverted();
    allTables.add(tableStepOpenAndDone);

    /*
     * ======================================================================
     * ==============
     */

    // what do we do here?
    // okay ... first we find out how many steps the selected set has
    // finding lowest step and highest step (no step name discrimination)
    Integer uBound;
    Integer uBoundOpen = getMaxStepCount(HistoryEventType.stepOpen);
    Integer uBoundDone = getMaxStepCount(HistoryEventType.stepDone);
    if (uBoundOpen < uBoundDone) {
      uBound = uBoundDone;
    } else {
      uBound = uBoundOpen;
    }

    Integer lBound;
    Integer lBoundOpen = getMinStepCount(HistoryEventType.stepOpen);
    Integer lBoundDone = getMinStepCount(HistoryEventType.stepDone);

    if (lBoundOpen < lBoundDone) {
      lBound = lBoundDone;
    } else {
      lBound = lBoundOpen;
    }

    // then for each step we get both the open and the done count within the
    // selected intervalls and merge it within one table
    for (Integer i = lBound; i <= uBound; i++) {

      DataTable tableStepOpen;
      tableStepOpen = getSpecificSteps(i, HistoryEventType.stepOpen);
     
      tableStepOpen.setShowableInTable(true);

      DataTable tableStepDone;
      tableStepDone = getSpecificSteps(i, HistoryEventType.stepDone);
     
      tableStepDone.setShowableInTable(true);

      // to merge we just take each table and dump the entire content in a
      // row for the open step
      DataRow rowOpenSteps = new DataRow(Helper.getTranslation("openSteps") + " " + i.toString());
      for (DataRow dtr : tableStepOpen.getDataRows()) {
        rowOpenSteps.addValue(dtr.getName(), dtr.getValue(0));
      }

      // adding the first row
      String title = "";
      if (tableStepOpen.getName().length() > 0) {
        title = tableStepOpen.getName();
      } else {
        title = tableStepDone.getName();
      }

      tableStepOpenAndDone = new DataTable(Helper.getTranslation("throughput") + " " + Helper.getTranslation("steps") + " " + title);
      tableStepOpenAndDone.addDataRow(rowOpenSteps);

      // row for the done step
      rowOpenSteps = new DataRow(Helper.getTranslation("doneSteps") + " " + i.toString());
      for (DataRow dtr : tableStepDone.getDataRows()) {
        rowOpenSteps.addValue(dtr.getName(), dtr.getValue(0));
      }

      // adding that row
      tableStepOpenAndDone.addDataRow(rowOpenSteps);

      // turning off table rendering
      tableStepOpenAndDone.setShowableInTable(false);

      // inverting the orientation
      tableStepOpenAndDone = tableStepOpenAndDone.getDataTableInverted();
      tableStepOpenAndDone.setUnitLabel(Helper.getTranslation(this.timeGrouping.getSingularTitle()));

      // Dates may not be all in the right order because of it's
      // composition from 2 tables
      List<DataRow> allTempRows = tableStepOpenAndDone.getDataRows();
      // this fixes the sorting problem
      Collections.sort(allTempRows, new DataTableComparator());

      allTables.add(tableStepOpenAndDone);

    }

    return allTables;
  }

  private static class DataTableComparator implements Comparator<DataRow> {
    @Override
    public int compare(DataRow o1, DataRow o2) {
      return o1.getName().compareTo(o2.getName());
    }
  }

  /*
   * (non-Javadoc)
   *
   * @see
   * org.goobi.production.flow.statistics.IStatisticalQuestion#setCalculationUnit
   * (org.goobi.production.flow.statistics.enums.CalculationUnit)
   */
  @Override
  public void setCalculationUnit(CalculationUnit cu) {
  }

  /*
   * (non-Javadoc)
   *
   * @see
   * org.goobi.production.flow.statistics.IStatisticalQuestionLimitedTimeframe
   * #setTimeFrame(java.util.Date, java.util.Date)
   */
  @Override
  public void setTimeFrame(Date timeFrom, Date timeTo) {
    this.timeFilterFrom = timeFrom;
    this.timeFilterTo = timeTo;

  }

  /*
   * (non-Javadoc)
   *
   * @see
   * org.goobi.production.flow.statistics.IStatisticalQuestion#isRendererInverted
   * (de.intranda.commons.chart.renderer.IRenderer)
   */
  @Override
  public Boolean isRendererInverted(IRenderer inRenderer) {
    return inRenderer instanceof ChartRenderer;
  }

  /*
   * (non-Javadoc)
   *
   * @see org.goobi.production.flow.statistics.IStatisticalQuestion#
   * getNumberFormatPattern()
   */
  @Override
  public String getNumberFormatPattern() {
    return "#";
  }

  /**
   * returns a DataTable populated with the specified events
   *
   * @param requestedType
   * @return
   */
  private DataTable getAllSteps(HistoryEventType requestedType) {

    // adding time restrictions
    String natSQL = new SQLStepRequestsImprovedDiscrimination(this.timeFilterFrom, this.timeFilterTo, this.timeGrouping, this.myIDlist).getSQL(requestedType, null,
        true, this.flagIncludeLoops);

    // this one is supposed to make sure, that all possible headers will be
    // thrown out in the first row to build header columns
    String headerFromSQL = new SQLStepRequestsImprovedDiscrimination(this.timeFilterFrom, this.timeFilterTo, null, this.myIDlist).getSQL(requestedType, null,
        true, true);

    this.myLogger.trace(natSQL);
    this.myLogger.trace(headerFromSQL);

    return buildDataTableFromSQL(natSQL, headerFromSQL);
  }

  /**
   * returns a DataTable populated with the specified events
   *
   * @param step
   * @param requestedType
   * @return
   */

  private DataTable getSpecificSteps(Integer step, HistoryEventType requestedType) {

    // adding time restrictions
    String natSQL = new SQLStepRequests(this.timeFilterFrom, this.timeFilterTo, this.timeGrouping, this.myIDlist).getSQL(requestedType, step, true, this.flagIncludeLoops);

    this.myLogger.trace(natSQL);

    return buildDataTableFromSQL(natSQL, null);
  }

  /**
   * Method generates a DataTable based on the input SQL. Methods success is
   * depending on a very specific data structure ... so don't use it if you
   * don't exactly understand it
   *
   *
   * @param natSQL
   *            , headerFromSQL -> to be used, if headers need to be read in
   *            first in order to get a certain sorting
   * @return DataTable
   */

  // TODO Remove redundant code
  private DataTable buildDataTableFromSQL(String natSQL, String headerFromSQL) {
    Session session = Helper.getHibernateSession();

    // creating header row from headerSQL (gets all columns in one row
    DataRow headerRow = null;
    if (headerFromSQL != null) {
      headerRow = new DataRow(null);
      SQLQuery headerQuery = session.createSQLQuery(headerFromSQL);

      // needs to be there otherwise an exception is thrown
      headerQuery.addScalar("stepCount", StandardBasicTypes.DOUBLE);
      headerQuery.addScalar("stepName", StandardBasicTypes.STRING);
      headerQuery.addScalar("stepOrder", StandardBasicTypes.DOUBLE);
      headerQuery.addScalar("intervall", StandardBasicTypes.STRING);

      @SuppressWarnings("rawtypes")
      List headerList = headerQuery.list();
      for (Object obj : headerList) {
        Object[] objArr = (Object[]) obj;
        try {
          headerRow.setName(new Converter(objArr[3]).getString() + "");
          headerRow.addValue(new Converter(new Converter(objArr[2]).getInteger()).getString() + " (" + new Converter(objArr[1]).getString()
              + ")", (new Converter(objArr[0]).getDouble()));

        } catch (Exception e) {
          headerRow.addValue(e.getMessage(), new Double(0));
        }
      }

    }

    SQLQuery query = session.createSQLQuery(natSQL);

    // needs to be there otherwise an exception is thrown
    query.addScalar("stepCount", StandardBasicTypes.DOUBLE);
    query.addScalar("stepName", StandardBasicTypes.STRING);
    query.addScalar("stepOrder", StandardBasicTypes.DOUBLE);
    query.addScalar("intervall", StandardBasicTypes.STRING);

    @SuppressWarnings("rawtypes")
    List list = query.list();

    DataTable dtbl = new DataTable("");

    // if headerRow is set then add it to the DataTable to set columns
    // needs to be removed later
    if (headerRow != null) {
      dtbl.addDataRow(headerRow);
    }

    DataRow dataRow = null;

    // each data row comes out as an Array of Objects
    // the only way to extract the data is by knowing
    // in which order they come out

    // checks if intervall has changed which then triggers the start for a
    // new row
    // intervall here is the timeGroup Expression (e.g. "2006/05" or
    // "2006-10-05")
    String observeIntervall = "";

    for (Object obj : list) {
      Object[] objArr = (Object[]) obj;
      try {
        // objArr[3]
        if (!observeIntervall.equals(new Converter(objArr[3]).getString())) {
          observeIntervall = new Converter(objArr[3]).getString();

          // row cannot be added before it is filled because the add
          // process triggers
          // a testing for header alignement -- this is where we add
          // it after iterating it first
          if (dataRow != null) {
            dtbl.addDataRow(dataRow);
          }

          dataRow = new DataRow(null);
          // setting row name with localized time group and the
          // date/time extraction based on the group
          dataRow.setName(new Converter(objArr[3]).getString() + "");
        }
        dataRow.addValue(
            new Converter(new Converter(objArr[2]).getInteger()).getString() + " (" + new Converter(objArr[1]).getString() + ")",
            (new Converter(objArr[0]).getDouble()));

      } catch (Exception e) {
        dataRow.addValue(e.getMessage(), new Double(0));
      }
    }
    // to add the last row
    if (dataRow != null) {
      dtbl.addDataRow(dataRow);
    }

    // now removing headerRow
    if (headerRow != null) {
      dtbl.removeDataRow(headerRow);
   
    }

    return dtbl;
  }

  /**
   * method retrieves the highest step order in the requested history range
   *
   * @param requestedType
   */
  private Integer getMaxStepCount(HistoryEventType requestedType) {

    // adding time restrictions
    String natSQL = new SQLStepRequestsImprovedDiscrimination(this.timeFilterFrom, this.timeFilterTo, this.timeGrouping, this.myIDlist)
        .SQLMaxStepOrder(requestedType);

    Session session = Helper.getHibernateSession();
    SQLQuery query = session.createSQLQuery(natSQL);

    // needs to be there otherwise an exception is thrown
    query.addScalar("maxStep", StandardBasicTypes.DOUBLE);

    @SuppressWarnings("rawtypes")
    List list = query.list();

    if (list != null && list.size() > 0 && list.get(0) != null) {
      return new Converter(list.get(0)).getInteger();
    } else {
      return 0;
    }

  }

  /**
   * method retrieves the lowest step order in the requested history range
   *
   * @param requestedType
   */
  private Integer getMinStepCount(HistoryEventType requestedType) {
    // adding time restrictions
    String natSQL = new SQLStepRequestsImprovedDiscrimination(this.timeFilterFrom, this.timeFilterTo, this.timeGrouping, this.myIDlist)
        .SQLMinStepOrder(requestedType);

    Session session = Helper.getHibernateSession();
    SQLQuery query = session.createSQLQuery(natSQL);

    // needs to be there otherwise an exception is thrown
    query.addScalar("minStep", StandardBasicTypes.DOUBLE);

    @SuppressWarnings("rawtypes")
    List list = query.list();

    if (list != null && list.size() > 0 && list.get(0) != null) {
      return new Converter(list.get(0)).getInteger();
    } else {
      return 0;
    }

  }

}
TOP

Related Classes of org.goobi.production.flow.statistics.hibernate.StatQuestThroughput$DataTableComparator

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.