Package nl.topicus.onderwijs.dashboard.modules.plots

Source Code of nl.topicus.onderwijs.dashboard.modules.plots.PlotService

package nl.topicus.onderwijs.dashboard.modules.plots;

import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;

import nl.topicus.onderwijs.dashboard.config.ISettings;
import nl.topicus.onderwijs.dashboard.datasources.AverageRequestTime;
import nl.topicus.onderwijs.dashboard.datasources.NumberOfUsers;
import nl.topicus.onderwijs.dashboard.datasources.RequestsPerMinute;
import nl.topicus.onderwijs.dashboard.keys.Key;
import nl.topicus.onderwijs.dashboard.keys.Project;
import nl.topicus.onderwijs.dashboard.modules.AbstractService;
import nl.topicus.onderwijs.dashboard.modules.DashboardRepository;
import nl.topicus.onderwijs.dashboard.modules.DataSource;
import nl.topicus.onderwijs.dashboard.modules.ServiceConfiguration;
import nl.topicus.onderwijs.dashboard.web.WicketApplication;

import org.apache.commons.math.ArgumentOutsideDomainException;
import org.apache.commons.math.MathException;
import org.apache.commons.math.analysis.interpolation.LoessInterpolator;
import org.apache.commons.math.analysis.polynomials.PolynomialSplineFunction;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

@Service
@ServiceConfiguration(interval = 1, unit = TimeUnit.MINUTES, runInRandomMode = true)
public class PlotService extends AbstractService {
  private Map<PlotKey, DataSourceSeries<?, ?>> data = new HashMap<PlotKey, DataSourceSeries<?, ?>>();
  private Map<PlotKey, DataSourcePlotSeries<?, ?>> series = new HashMap<PlotKey, DataSourcePlotSeries<?, ?>>();

  private WicketApplication application;

  private LoessInterpolator loessInterpolator;

  @Autowired
  public PlotService(ISettings settings) {
    super(settings);
  }

  @Autowired
  public void setApplication(WicketApplication application) {
    this.application = application;
  }

  @Override
  public void onConfigure(DashboardRepository repository) {
    loessInterpolator = new LoessInterpolator();
    for (Project curProject : repository.getKeys(Project.class)) {
      if (repository.getData(AverageRequestTime.class).containsKey(
          curProject))
        addSeries(curProject, AverageRequestTime.class);
      if (repository.getData(NumberOfUsers.class).containsKey(curProject))
        addSeries(curProject, NumberOfUsers.class);
      if (repository.getData(RequestsPerMinute.class).containsKey(
          curProject))
        addSeries(curProject, RequestsPerMinute.class);
    }
  }

  private <T extends Number, D extends DataSource<T>> void addSeries(
      Project project, Class<D> dataSource) {
    PlotKey key = new PlotKey(project, dataSource);
    data.put(key, new DataSourceSeries<T, D>(project, dataSource));
    series.put(key, new DataSourcePlotSeries<T, D>(project));
  }

  @SuppressWarnings("unchecked")
  public <T extends Number, D extends DataSource<T>> List<DataSourcePlotSeries<T, D>> getSeries(
      Class<D> dataSource) {
    List<DataSourcePlotSeries<T, D>> ret = new ArrayList<DataSourcePlotSeries<T, D>>();
    for (Project curProject : application.getRepository().getKeys(
        Project.class)) {
      ret.add((DataSourcePlotSeries<T, D>) series.get(new PlotKey(
          curProject, dataSource)));
    }
    return ret;
  }

  @Override
  public void refreshData() {
    cleanupDataEntries();

    updateDataEntries();

    updateAllPlotSeries();
  }

  private void cleanupDataEntries() {
    Map<Key, Map<String, ?>> serviceSettings = getSettings()
        .getServiceSettings(PlotService.class);
    for (DataSourceSeries<?, ?> curData : data.values()) {
      if (serviceSettings.containsKey(curData.getKey())
          && serviceSettings.get(curData.getKey()).containsKey(
              "timeToLive")) {
        int dataTTL = Integer.parseInt(serviceSettings
            .get(curData.getKey()).get("timeToLive").toString());
        Calendar ttlDate = Calendar.getInstance();
        ttlDate.add(Calendar.SECOND, 0 - dataTTL);
        curData.cleanupEntries(ttlDate.getTime());
      }
    }
  }

  private void updateDataEntries() {
    for (DataSourceSeries<?, ?> curData : data.values()) {
      curData.addEntry(application.getRepository());
    }
  }

  private void updateAllPlotSeries() {
    for (DataSourceSeries<?, ?> curData : data.values()) {
      DataSourcePlotSeries<Integer, ?> curSeries = (DataSourcePlotSeries<Integer, ?>) series
          .get(new PlotKey(curData.getKey(), curData.getDataSource()));
      updatePlotSeries(curSeries, curData);
    }
  }

  private void updatePlotSeries(DataSourcePlotSeries<Integer, ?> curSeries,
      DataSourceSeries<?, ?> curData) {
    if (!updatePlotSeriesWithLoessInterpolatorData(curSeries, curData)) {
      updatePlotSeriesWithOriginalData(curSeries, curData);
    }
  }

  private void updatePlotSeriesWithOriginalData(
      DataSourcePlotSeries<Integer, ?> curSeries,
      DataSourceSeries<?, ?> curData) {
    curSeries.clear();
    for (DataSourceSeriesEntry<?> entry : curData.getData()) {
      curSeries.addEntry(entry.getKey(), (Integer) entry.getValue());
    }
  }

  private boolean updatePlotSeriesWithLoessInterpolatorData(
      DataSourcePlotSeries<Integer, ?> curSeries,
      DataSourceSeries<?, ?> curData) {
    if (curData.getData().size() < 10) {
      return false;
    }

    Date last = curData.getLastEntry().getKey();
    double[] xvals = new double[curData.getData().size()];
    double[] yvals = new double[curData.getData().size()];
    for (int i = 0; i < curData.getData().size(); i++) {
      xvals[i] = new Long(curData.getData().get(i).getKey().getTime());
      if (curData.getData().get(i).getValue() != null) {
        yvals[i] = curData.getData().get(i).getValue().doubleValue();
      }
    }

    PolynomialSplineFunction psf = null;
    try {
      psf = loessInterpolator.interpolate(xvals, yvals);
    } catch (MathException e) {
      e.printStackTrace();
      return false;
    }
    if (psf != null) {
      curSeries.clear();
      Date time = curData.getFirstEntry().getKey();
      do {
        try {
          double v = psf.value(time.getTime());
          curSeries.addEntry(time, Double.valueOf(v).intValue());

        } catch (ArgumentOutsideDomainException e) {
          e.printStackTrace();
          return false;
        }
        Calendar c = Calendar.getInstance();
        c.setTime(time);
        c.add(Calendar.SECOND, 10);
        time = c.getTime();
      } while (time.before(last));
      return true;
    }
    return false;
  }
}
TOP

Related Classes of nl.topicus.onderwijs.dashboard.modules.plots.PlotService

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.