Package gov.nasa.arc.mct.fastplot.view

Source Code of gov.nasa.arc.mct.fastplot.view.PlotDataFeedUpdateHandler

/*******************************************************************************
* Mission Control Technologies, Copyright (c) 2009-2012, United States Government
* as represented by the Administrator of the National Aeronautics and Space
* Administration. All rights reserved.
*
* The MCT platform is licensed under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* http://www.apache.org/licenses/LICENSE-2.0.
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
*
* MCT includes source code licensed under additional open source licenses. See
* the MCT Open Source Licenses file included with this distribution or the About
* MCT Licenses dialog available at runtime from the MCT Help menu for additional
* information.
*******************************************************************************/
package gov.nasa.arc.mct.fastplot.view;

import gov.nasa.arc.mct.components.FeedProvider;
import gov.nasa.arc.mct.components.FeedProvider.FeedType;
import gov.nasa.arc.mct.components.FeedProvider.RenderingInfo;

import java.awt.Color;
import java.util.Collection;
import java.util.GregorianCalendar;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.SortedMap;
import java.util.TreeMap;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class PlotDataFeedUpdateHandler {
  private final static Logger logger = LoggerFactory
      .getLogger(PlotDataFeedUpdateHandler.class);

  private PlotViewManifestation plotViewManifestation;

  private static final RenderingInfo DEFAULT_RI = new RenderingInfo(null, Color.WHITE, "0", Color.WHITE, false);

  PlotDataFeedUpdateHandler(
      PlotViewManifestation supportedPlotViewManifestation) {
    plotViewManifestation = supportedPlotViewManifestation;
  }

  void synchronizeTime(Map<String, List<Map<String, String>>> data,
      long syncTime) {
    GregorianCalendar calendar = new GregorianCalendar();
    calendar.setTimeInMillis(syncTime);
    plotViewManifestation.getPlot().showTimeSyncLine(calendar);
    updateFromFeeds(data, true, true, false);
  }
 
  void updateFromFeed(Map<String, List<Map<String, String>>> data, boolean predictionOnly) {
    plotViewManifestation.getPlot().informUpdateFromFeedEventStarted();
    // Receiving any data from the feed informs us that any sync lines
    // should be
    // removed.
    // Check if we cached updates while the updateFromFeed was previously
    // locked.
    updateFromFeeds(data, false, true, predictionOnly);
    plotViewManifestation.getPlot().refreshDisplay();
    // Request that the plot updates its display with the new feed data.
    if (plotViewManifestation.controlPanel != null
        && plotViewManifestation.controlPanel.isShowing()) {
      //plotViewManifestation.controlPanel.refreshDisplay();
      //TODO: Reconnect so that time marches on
    }
    plotViewManifestation.getPlot().informUpdateFromFeedEventCompleted();
  }

  public void processData(Map<String, List<Map<String, String>>> data) {
    if (logger.isDebugEnabled()) {
      logger.debug("\n Recived new slice {}", printDataOnSlice(data));
    }
    boolean currentCompressionState = plotViewManifestation.getPlot().isCompressionEnabled();
    try {
      plotViewManifestation.getPlot().setCompressionEnabled(false);
      updateFromFeeds(data, false, false, false);
    } finally {
      plotViewManifestation.getPlot().setCompressionEnabled(currentCompressionState);
    }
   
  }

  public void startDataRequest() {
    plotViewManifestation.getPlot().informUpdateDataEventStarted();
    plotViewManifestation.getPlot().refreshDisplay();
  }
 
  public void endDataRequest() {
    closeOutProcessData();
  }
 
  private void closeOutProcessData() {
    if (plotViewManifestation.controlPanel != null
        && plotViewManifestation.controlPanel.isShowing()) {
      //plotViewManifestation.controlPanel.refreshDisplay();
      //TODO: Time must march on
    }
    // unlock the plot's update events.
    plotViewManifestation.getPlot().informUpdateDataEventCompleted();
    plotViewManifestation.getPlot().refreshDisplay();
  }

  /**
   * Unwrap the data from the feed service.
   *
   * @param feedIds
   *            the set of feed IDs
   * @param data
   *            the data
   */
  void updateFromFeeds(Map<String, List<Map<String, String>>> data,
      boolean legendOnly, boolean updateLegend, boolean predictionOnly) {
    if (data != null) {
      Map<String, SortedMap<Long, Double>> dataForPlot = new HashMap<String, SortedMap<Long,Double>>();

      // Iterate over the feeds (each is a plot line on the chart)
      Collection<FeedProvider> feeds = plotViewManifestation
          .getVisibleFeedProviders();

      for (FeedProvider provider : feeds) {
        if (provider.getFeedType() != FeedType.STRING) {
          String feedId = provider.getSubscriptionId();
          List<Map<String, String>> dataForThisFeed = data.get(feedId);
 
          // This prevents "live" data (from the current time, not the maximum valid time) from predictive feeds from
          // showing up in the plot.  This prevents a bug where live data arrives in the middle of a historical data request, and
          // the plot thinks the next historical slice is redundant and ignores it (since it overlaps with the live data).
          boolean allowPlotting = predictionOnly == provider.isPrediction() || !updateLegend;
         
          if (dataForThisFeed != null && plotViewManifestation.getPlot().isKnownDataSet(feedId) && allowPlotting) {
            SortedMap<Long, Double> dataForPlotThisFeed = dataForPlot.get(feedId);
            if(dataForPlotThisFeed == null) {
              dataForPlotThisFeed = new TreeMap<Long, Double>();
              dataForPlot.put(feedId, dataForPlotThisFeed);
            }
 
            RenderingInfo lastRI = DEFAULT_RI;
            boolean haveLegendInfo = false;
 
            // Loop over each point that needs to be plotted for this
            // feed.
            for (Map<String, String> pointsData : dataForThisFeed) {
              RenderingInfo ri = provider
                  .getRenderingInfo(pointsData);
              assert pointsData != null : "PointsData is Null";
              String timeAsString = pointsData
                  .get(FeedProvider.NORMALIZED_TIME_KEY);
              String valueAsString = ri.getValueText();
                boolean isPlottable = ri.isPlottable();
 
              // Robust to time or value keys not being present.
              if (timeAsString != null && valueAsString != null) {
                try {
                  long milliSecondsEpoch = Long
                      .parseLong(timeAsString);
                  if (!isPlottable) {
                    valueAsString = "";
                  }
                  lastRI = ri;
                  haveLegendInfo = true;
 
                  if (!plotViewManifestation.getPlot()
                      .isKnownDataSet(feedId)) {
                    plotViewManifestation.getPlot().addDataSet(
                        feedId, provider.getLegendText());
                  }
 
                  if (!legendOnly) {
                    double value;
                    if(isPlottable) {
                      value = Double.parseDouble(valueAsString);
                    } else {
                      value = Double.NaN;
                    }
                    dataForPlotThisFeed.put(milliSecondsEpoch, value);
                  }
 
                } catch (NumberFormatException e) {
                  logger
                      .error(
                          "Number format exception converting string to double while processing the data feed entry {}, {}",
                          timeAsString, valueAsString);
                }
              } else {
                logger
                    .error(
                        "Either time, value, or isValid entry was not defined. {}, {}",
                        timeAsString, valueAsString);
              }
            }
            if (haveLegendInfo && updateLegend) {
              plotViewManifestation.getPlot().updateLegend(feedId, lastRI);
            }
          }
        }
      }

      plotViewManifestation.getPlot().addData(dataForPlot);
    } else {
      logger.debug("Data was null");
    }
  }

  private String printDataOnSlice(Map<String, List<Map<String, String>>> data) {
    long earliestTime = Long.MAX_VALUE;
    long latestTime = -Long.MAX_VALUE;
    int numberDataPoints = 0;

    for (String feedId : data.keySet()) {
      List<Map<String, String>> dataForThisFeed = data.get(feedId);
      if (dataForThisFeed != null) {
        for (Map<String, String> pointsData : dataForThisFeed) {
          assert pointsData != null : "PointsData is Null";
          String timeAsString = pointsData
              .get(FeedProvider.NORMALIZED_TIME_KEY);
          if (timeAsString != null) {
            try {
              numberDataPoints++;
              long milliSecondsEpoch = Long
                  .parseLong(timeAsString);
              if (milliSecondsEpoch > latestTime) {
                latestTime = milliSecondsEpoch;
              }

              if (milliSecondsEpoch < earliestTime) {
                earliestTime = milliSecondsEpoch;
              }

              assert latestTime >= earliestTime : "latest < earliest!";

            } catch (NumberFormatException e) {
              logger
                  .error(
                      "Number format exception converting string to double while processing the data feed entry {}",
                      timeAsString);
            }
          } else {
            logger
                .error(
                    "Either time, value, or isValid entry was not defined. {}",
                    timeAsString);
          }
        }
      }
    }
    if (numberDataPoints > 0) {
      return "Slice: "
          + numberDataPoints;
    } else {
      return "Slice: " + numberDataPoints + " [ .. ]";
    }
  }

}
TOP

Related Classes of gov.nasa.arc.mct.fastplot.view.PlotDataFeedUpdateHandler

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.