Package org.goobi.production.flow.statistics

Source Code of org.goobi.production.flow.statistics.StatisticsManager

package org.goobi.production.flow.statistics;

/**
* 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.io.Serializable;
import java.text.DateFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import java.util.Locale;

import org.apache.commons.lang.StringUtils;
import org.apache.log4j.Logger;
import org.goobi.production.flow.statistics.enums.CalculationUnit;
import org.goobi.production.flow.statistics.enums.ResultOutput;
import org.goobi.production.flow.statistics.enums.StatisticsMode;
import org.goobi.production.flow.statistics.enums.TimeUnit;
import org.goobi.production.flow.statistics.hibernate.StatQuestThroughput;
import org.jfree.data.general.Dataset;
import org.jfree.data.general.DefaultValueDataset;

import de.intranda.commons.chart.results.DataRow;
import de.intranda.commons.chart.results.DataTable;
import de.sub.goobi.helper.Helper;
import de.sub.goobi.statistik.StatistikLaufzeitSchritte;
import de.sub.goobi.statistik.StatistikStatus;

/**
* The Class StatisticsManager organizes all statistical questions by choosing
* the right implementation depening on {@link StatisticsMode}
*
* for old statistical question there will be generated jfreechart-datasets
*
* @author Steffen Hankiewicz
* @version 20.05.2009
****************************************************************************/
public class StatisticsManager implements Serializable {

  private static final long serialVersionUID = -1070332559779545423L;
  private static final Logger logger = Logger.getLogger(StatisticsManager.class);
  /* simple JFreeChart Dataset for the old simple statistics */
  private Dataset jfreeDataset;
  /* internal StatisticsMode */
  private StatisticsMode statisticMode;
  private IDataSource myDataSource;
  private Date sourceDateFrom;
  private Date sourceDateTo = new Date();
  private int sourceNumberOfTimeUnits;
  private TimeUnit sourceTimeUnit;
  private TimeUnit targetTimeUnit;
  private ResultOutput targetResultOutput;
  private CalculationUnit targetCalculationUnit;
  private boolean showAverage;
  private Date calculatedStartDate = new Date();
  private Date calculatedEndDate = new Date();
  private List<StatisticsRenderingElement> renderingElements;
  static private Locale myLocale = null;
  private Boolean includeLoops = null;

  private StatisticsManager() {
    super();
  }

  /**
   * public constructor
   *
   * @param inMode
   *            as {@link StatisticsMode}
   * @param inDataSource
   *            as {@link IDataSource}
   ****************************************************************************/
  public StatisticsManager(StatisticsMode inMode, IDataSource inDataSource, Locale locale) {
    this();
    statisticMode = inMode;
    myDataSource = inDataSource;
    targetResultOutput = ResultOutput.chartAndTable;
    targetTimeUnit = TimeUnit.months;
    sourceTimeUnit = TimeUnit.months;
    myLocale = locale;

    /* for backward compatibility create old jfreechart datasets */
    if (inMode.getIsSimple()) {
      switch (inMode) {

      case SIMPLE_RUNTIME_STEPS:
        jfreeDataset = StatistikLaufzeitSchritte.getDiagramm(inDataSource.getSourceData());
        break;

      default:
        jfreeDataset = StatistikStatus.getDiagramm(inDataSource.getSourceData());
        break;
      }
    }
    if (myLocale == null) {
      myLocale = new Locale("de");
    }
  }

  /**
   * retrieve the jfreechart Dataset for old statistical questions
   *
   * @return {@link Dataset} for charting
   ****************************************************************************/
  public Dataset getJfreeDataset() {
    if (statisticMode.getIsSimple()) {
      return jfreeDataset;
    } else {
      return new DefaultValueDataset();
    }
  }

  /**
   * retrieve current {@link StatisticsMode}
   *
   * @return {@link StatisticsMode} for current statistical question
   ****************************************************************************/
  public StatisticsMode getStatisticMode() {
    return statisticMode;
  }

  /**
   * calculate statistics and retrieve List off {@link DataRow} from
   * {@link StatisticsMode} for presention and rendering
   *
   ****************************************************************************/
  public void calculate() {
    /*
     * -------------------------------- if to-date is before from-date, show
     * error message --------------------------------
     */
    if (sourceDateFrom != null && sourceDateTo != null && sourceDateFrom.after(sourceDateTo)) {
      Helper.setMeldung("myStatisticButton", "selectedDatesNotValide", "selectedDatesNotValide");
      return;
    }

    /*
     * -------------------------------- some debugging here
     * --------------------------------
     */
    logger.debug(sourceDateFrom + " - " + sourceDateTo + " - " + sourceNumberOfTimeUnits + " - " + sourceTimeUnit + "\n" + targetTimeUnit + " - "
        + targetCalculationUnit + " - " + targetResultOutput + " - " + showAverage);

    /*
     * -------------------------------- calculate the statistical results and
     * save it as List of DataTables (because some statistical questions
     * allow multiple tables and charts) --------------------------------
     */
    IStatisticalQuestion question = statisticMode.getStatisticalQuestion();
    try {
      setTimeFrameToStatisticalQuestion(question);

      // picking up users input regarding loop Options
      if (isRenderLoopOption()) {
        try {
          ((StatQuestThroughput) question).setIncludeLoops(includeLoops);
        } catch (Exception e) { // just in case -> shouldn't happen
          logger.debug("unexpected Exception, wrong class loaded", e);
        }
      }
      if (targetTimeUnit != null) {
        question.setTimeUnit(targetTimeUnit);
      }
      if (targetCalculationUnit != null) {
        question.setCalculationUnit(targetCalculationUnit);
      }
      renderingElements = new ArrayList<StatisticsRenderingElement>();
      List<DataTable> myDataTables = question.getDataTables(myDataSource);

      /*
       * -------------------------------- if DataTables exist analyze them
       * --------------------------------
       */
      if (myDataTables != null) {

        /*
         * -------------------------------- localize time frame for gui
         * --------------------------------
         */
        StringBuilder subname = new StringBuilder();
        if (calculatedStartDate != null) {
          subname.append(DateFormat.getDateInstance(DateFormat.SHORT, myLocale).format(calculatedStartDate));
        }
        subname.append(" - ");
        if (calculatedEndDate != null) {
          subname.append(DateFormat.getDateInstance(DateFormat.SHORT, myLocale).format(calculatedEndDate));
        }
        if (calculatedStartDate == null && calculatedEndDate == null) {
          subname = new StringBuilder();
        }

        /*
         * -------------------------------- run through all DataTables
         * --------------------------------
         */
        for (DataTable dt : myDataTables) {
          dt.setSubname(subname.toString());
          StatisticsRenderingElement sre = new StatisticsRenderingElement(dt, question);
          sre.createRenderer(showAverage);
          renderingElements.add(sre);
        }
      }
    } catch (UnsupportedOperationException e) {
      Helper.setFehlerMeldung("StatisticButton", "errorOccuredWhileCalculatingStatistics", e);
    }
  }

  /**
   * Depending on selected Dates oder time range, set the dates for the
   * statistical question here
   *
   * @param question
   *            the {@link IStatisticalQuestion} where the dates should be
   *            set, if it is an implementation of
   *            {@link IStatisticalQuestionLimitedTimeframe}
   *************************************************************************************/
  @SuppressWarnings("incomplete-switch")
  private void setTimeFrameToStatisticalQuestion(IStatisticalQuestion question) {
    /* only add a date, if correct interface is implemented here */
    if (question instanceof IStatisticalQuestionLimitedTimeframe) {
      /* if a timeunit is selected calculate the dates */
      Calendar cl = Calendar.getInstance();

      if (sourceNumberOfTimeUnits > 0) {

        cl.setFirstDayOfWeek(Calendar.MONDAY);
        cl.setTime(new Date());

        switch (sourceTimeUnit) {
        case days:
          calculatedEndDate = calulateStartDateForTimeFrame(cl);
          calculatedStartDate = calculateEndDateForTimeFrame(cl, Calendar.DATE, -1);
          break;

        case weeks:
          cl.set(Calendar.DAY_OF_WEEK, Calendar.MONDAY);
          calculatedEndDate = calulateStartDateForTimeFrame(cl);
          calculatedStartDate = calculateEndDateForTimeFrame(cl, Calendar.DATE, -7);
          break;

        case months:
          cl.set(Calendar.DAY_OF_MONTH, 1);
          calculatedEndDate = calulateStartDateForTimeFrame(cl);
          calculatedStartDate = calculateEndDateForTimeFrame(cl, Calendar.MONTH, -1);
          break;

        case quarters:
          cl.set(Calendar.DAY_OF_MONTH, 1);
          setCalendarToMidnight(cl);
          while ((cl.get(Calendar.MONTH) + 0) % 3 > 0) {
            cl.add(Calendar.MONTH, -1);
          }
          cl.add(Calendar.MILLISECOND, -1);
          calculatedEndDate = cl.getTime();
          calculatedStartDate = calculateEndDateForTimeFrame(cl, Calendar.MONTH, -3);
          break;

        case years:
          cl.set(Calendar.DAY_OF_YEAR, 1);
          calculatedEndDate = calulateStartDateForTimeFrame(cl);
          calculatedStartDate = calculateEndDateForTimeFrame(cl, Calendar.YEAR, -1);
          break;
        }

      } else {
        /* take start and end date */
        cl.setTime(sourceDateTo);
        cl.add(Calendar.DATE, 1);
        setCalendarToMidnight(cl);
        cl.add(Calendar.MILLISECOND, -1);
        calculatedStartDate = sourceDateFrom;
        calculatedEndDate = cl.getTime();
      }
      ((IStatisticalQuestionLimitedTimeframe) question).setTimeFrame(calculatedStartDate, calculatedEndDate);
    } else {
      calculatedStartDate = null;
      calculatedEndDate = null;
    }
  }

  private void setCalendarToMidnight(Calendar cl) {
    cl.set(Calendar.HOUR_OF_DAY, 0);
    cl.set(Calendar.MINUTE, 0);
    cl.set(Calendar.SECOND, 0);
    cl.set(Calendar.MILLISECOND, 0);
  }

  private Date calculateEndDateForTimeFrame(Calendar cl, int calenderUnit, int faktor) {
    cl.add(Calendar.MILLISECOND, 1);
    cl.add(calenderUnit, sourceNumberOfTimeUnits * faktor);
    return cl.getTime();
  }

  private Date calulateStartDateForTimeFrame(Calendar cl) {
    setCalendarToMidnight(cl);
    cl.add(Calendar.MILLISECOND, -1);
    return cl.getTime();
  }

  /**
   * Get all {@link TimeUnit} from enum
   *
   * @return all timeUnits
   *************************************************************************************/
  public List<TimeUnit> getAllTimeUnits() {
    return Arrays.asList(TimeUnit.values());
  }

  /**
   * Get all {@link CalculationUnit} from enum
   *
   * @return all calculationUnit
   *************************************************************************************/
  public List<CalculationUnit> getAllCalculationUnits() {
    return Arrays.asList(CalculationUnit.values());
  }

  /**
   * Get all {@link ResultOutput} from enum
   *
   * @return all resultOutput
   *************************************************************************************/
  public List<ResultOutput> getAllResultOutputs() {
    return Arrays.asList(ResultOutput.values());
  }

  /**
   * @return the sourceDateFrom
   *************************************************************************************/
  public Date getSourceDateFrom() {
    return sourceDateFrom;
  }

  /**
   * @param sourceDateFrom
   *            the sourceDateFrom to set
   *************************************************************************************/
  public void setSourceDateFrom(Date sourceDateFrom) {
    this.sourceDateFrom = sourceDateFrom;
  }

  /**
   * @return the sourceDateTo
   *************************************************************************************/
  public Date getSourceDateTo() {
    return sourceDateTo;
  }

  /**
   * @param sourceDateTo
   *            the sourceDateTo to set
   *************************************************************************************/
  public void setSourceDateTo(Date sourceDateTo) {
    this.sourceDateTo = sourceDateTo;
  }

  /**
   * @return the sourceNumberOfTimeUnitsAsString
   *************************************************************************************/
  public String getSourceNumberOfTimeUnitsAsString() {
    if (sourceNumberOfTimeUnits == 0) {
      return "";
    } else {
      return String.valueOf(sourceNumberOfTimeUnits);
    }
  }

  /**
   * @param inUnits
   *            the sourceNumberOfTimeUnits to set given as String to show an
   *            empty text field in gui
   *************************************************************************************/
  public void setSourceNumberOfTimeUnitsAsString(String inUnits) {
    if (StringUtils.isNotBlank(inUnits) && StringUtils.isNumericSpace(inUnits)) {
      sourceNumberOfTimeUnits = Integer.parseInt(inUnits);
    } else {
      sourceNumberOfTimeUnits = 0;
    }
  }

  /**
   * @return the sourceTimeUnit
   *************************************************************************************/
  public TimeUnit getSourceTimeUnit() {
    return sourceTimeUnit;
  }

  /**
   * @param sourceTimeUnit
   *            the sourceTimeUnit to set
   *************************************************************************************/
  public void setSourceTimeUnit(TimeUnit sourceTimeUnit) {
    this.sourceTimeUnit = sourceTimeUnit;
  }

  /**
   * @return the targetTimeUnit
   *************************************************************************************/
  public TimeUnit getTargetTimeUnit() {
    return targetTimeUnit;
  }

  /**
   * @param targetTimeUnit
   *            the targetTimeUnit to set
   *************************************************************************************/
  public void setTargetTimeUnit(TimeUnit targetTimeUnit) {
    this.targetTimeUnit = targetTimeUnit;
  }

  /**
   * @return the targetResultOutput
   *************************************************************************************/
  public ResultOutput getTargetResultOutput() {
    return targetResultOutput;
  }

  /**
   * @param targetResultOutput
   *            the targetResultOutput to set
   *************************************************************************************/
  public void setTargetResultOutput(ResultOutput targetResultOutput) {
    this.targetResultOutput = targetResultOutput;
  }

  /**
   * @return the targetCalculationUnit
   *************************************************************************************/
  public CalculationUnit getTargetCalculationUnit() {
    return targetCalculationUnit;
  }

  /**
   * @param targetCalculationUnit
   *            the targetCalculationUnit to set
   *************************************************************************************/
  public void setTargetCalculationUnit(CalculationUnit targetCalculationUnit) {
    this.targetCalculationUnit = targetCalculationUnit;
  }

  /**
   * @return the showAverage
   *************************************************************************************/
  public boolean isShowAverage() {
    return showAverage;
  }

  /**
   * @param showAverage
   *            the showAverage to set
   *************************************************************************************/
  public void setShowAverage(boolean showAverage) {
    this.showAverage = showAverage;
  }

  /**
   * @return includeLoops flag
   */
  public boolean isIncludeLoops() {
    if (includeLoops == null) {
      includeLoops = false;
    }
    return includeLoops;
  }

  public boolean isRenderLoopOption() {
    return statisticMode.isRenderIncludeLoops();
  }

  /**
   * @return includeLoops flag
   */
  public void setIncludeLoops(boolean includeLoops) {
    this.includeLoops = includeLoops;
  }

  /**
   * get List of RenderingElements
   *
   * @return List of {@link StatisticsRenderingElement} of calculated results
   *************************************************************************************/
  public List<StatisticsRenderingElement> getRenderingElements() {
    return renderingElements;
  }

  public static Locale getLocale() {
    if (myLocale != null) {
      return myLocale;
    } else {
      return new Locale("de");
    }
  }
}
TOP

Related Classes of org.goobi.production.flow.statistics.StatisticsManager

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.