Package com.opengamma.web.analytics

Source Code of com.opengamma.web.analytics.ViewportResultsJsonCsvWriter

/**
* Copyright (C) 2012 - present by OpenGamma Inc. and the OpenGamma group of companies
*
* Please see distribution for license.
*/
package com.opengamma.web.analytics;

import static com.opengamma.web.analytics.formatting.DataType.UNKNOWN;

import java.io.StringWriter;
import java.math.BigDecimal;
import java.util.Collection;
import java.util.Collections;
import java.util.EnumSet;
import java.util.List;
import java.util.Map;

import org.json.JSONObject;

import au.com.bytecode.opencsv.CSVWriter;

import com.google.common.collect.ImmutableMap;
import com.google.common.collect.Iterables;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.opengamma.engine.ComputationTargetSpecification;
import com.opengamma.engine.calcnode.MissingValue;
import com.opengamma.engine.value.ValueSpecification;
import com.opengamma.engine.view.AggregatedExecutionLog;
import com.opengamma.engine.view.ExecutionLog;
import com.opengamma.engine.view.ExecutionLogWithContext;
import com.opengamma.util.log.LogEvent;
import com.opengamma.util.log.LogLevel;
import com.opengamma.web.analytics.formatting.DataType;
import com.opengamma.web.analytics.formatting.ResultsFormatter;
import com.opengamma.web.analytics.formatting.TypeFormatter;
import com.opengamma.web.server.conversion.DoubleValueOptionalDecimalPlaceFormatter;

/**
* Creates a JSON/CSV object from an instance of {@link ViewportResults}.
*/
public class ViewportResultsJsonCsvWriter {

  private static final String VERSION = "version";
  private static final String VALUE = "v";
  private static final String HISTORY = "h";
  private static final String TYPE = "t";
  private static final String DATA = "data";
  private static final String ERROR = "error";
  private static final String CALCULATION_DURATION = "calculationDuration";
  private static final String LOG_LEVEL = "logLevel";
  private static final String LOG_OUTPUT = "logOutput";
  private static final String EXCEPTION_CLASS = "exceptionClass";
  private static final String EXCEPTION_MESSAGE = "exceptionMessage";
  private static final String EXCEPTION_STACK_TRACE = "exceptionStackTrace";
  private static final String EVENTS = "events";
  private static final String LEVEL = "level";
  private static final String MESSAGE = "message";
  private static final String FUNCTION_NAME = "functionName";
  private static final String TARGET = "target";

  private final ResultsFormatter _formatter;
  private final DoubleValueOptionalDecimalPlaceFormatter _durationFormatter = new DoubleValueOptionalDecimalPlaceFormatter();

  public ViewportResultsJsonCsvWriter(ResultsFormatter formatter) {
    _formatter = formatter;
  }
 
  public String getCsv(ViewportResults viewportResults) {
    GridColumnGroups columnGroups = viewportResults.getColumns();
    String[] header1 = new String[columnGroups.getGroups().size()];
    String[] header2 = new String[columnGroups.getColumnCount()];
   
    int index = 0;
    for (GridColumnGroup gridColumnGroup : columnGroups.getGroups()) {
      header1[index++] = gridColumnGroup.getName();
    }
   
    List<GridColumn> columns = columnGroups.getColumns();
    index = 0;
    for (GridColumn gridColumn : columns) {
      header2[index++] = gridColumn.getHeader();
    }
   
    StringWriter stringWriter = new StringWriter();
    @SuppressWarnings("resource")
    CSVWriter csvWriter = new CSVWriter(stringWriter);
   
    csvWriter.writeNext(header1);
    csvWriter.writeNext(header2);
   
    List<ResultsCell> viewportCells = viewportResults.getResults();
    Iterable<List<ResultsCell>> results = Iterables.partition(viewportCells, columnGroups.getColumnCount());
    for (List<ResultsCell> row : results) {
      String[] rowArray = new String[row.size()];
      int col = 0;
      for (ResultsCell cell : row) {
        Object cellValue = cell.getValue();
        if (cellValue instanceof RowTarget) {
          rowArray[col++] = ((RowTarget) cellValue).getName();
          continue;
        }
       
        ValueSpecification cellValueSpec = cell.getValueSpecification();
        Object formattedValue = _formatter.format(cellValue, cellValueSpec, cell.getFormat(), cell.getInlineKey());
        if (formattedValue instanceof String) {
          rowArray[col++] = (String) formattedValue;
        } else {
          rowArray[col++] = formattedValue.toString();
        }
      }
      csvWriter.writeNext(rowArray);
    }
    return stringWriter.toString();
  }

  // TODO use a Freemarker template - will that perform well enough?
  public String getJson(ViewportResults viewportResults) {
    List<ResultsCell> viewportCells = viewportResults.getResults();
    List<Object> results = Lists.newArrayListWithCapacity(viewportCells.size());
    for (ResultsCell cell : viewportCells) {
      Object cellValue = cell.getValue();
      ValueSpecification cellValueSpec = cell.getValueSpecification();
      Object formattedValue = _formatter.format(cellValue, cellValueSpec, cell.getFormat(), cell.getInlineKey());
      Collection<Object> history = cell.getHistory();
      Class<?> columnType = cell.getType();
      DataType columnFormat = _formatter.getDataType(columnType);
      Map<String, Object> valueMap = Maps.newHashMap();
      AggregatedExecutionLog executionLog = cell.getExecutionLog();
      LogLevel logLevel = maxLogLevel(executionLog);

      valueMap.put(VALUE, formattedValue);
      if (columnFormat == UNKNOWN) {
        // if the the column type isn't known then send the type with the value
        valueMap.put(TYPE, _formatter.getDataTypeForValue(cellValue, cellValueSpec).name());
      }
      if (history != null) {
        List<Object> formattedHistoy = formatHistory(cellValueSpec, cell.getInlineKey(), history);
        if (formattedHistoy != null) {
          valueMap.put(HISTORY, formattedHistoy);
        }
      }
      if (cell.isError() || isError(formattedValue)) {
        valueMap.put(ERROR, true);
      }
      if (logLevel != null) {
        valueMap.put(LOG_LEVEL, logLevel);
      }
      if (hasLogOutput(executionLog)) {
        valueMap.put(LOG_OUTPUT, formatLogOutput(executionLog));
      }
      results.add(valueMap);
    }
    String duration = _durationFormatter.format(new BigDecimal(viewportResults.getCalculationDuration().toMillis()));
    ImmutableMap<String, Object> resultsMap = ImmutableMap.of(VERSION, viewportResults.getVersion(),
                                                              CALCULATION_DURATION, duration,
                                                              DATA, results);
    return new JSONObject(resultsMap).toString();
  }

  private static boolean isError(Object value) {
    return value instanceof MissingValue;
  }

  private static LogLevel maxLogLevel(AggregatedExecutionLog log) {
    if (log == null) {
      return null;
    }
    EnumSet<LogLevel> logLevels = log.getLogLevels();
    if (logLevels.isEmpty()) {
      return null;
    }
    List<LogLevel> logLevelList = Lists.newArrayList(logLevels);
    Collections.sort(logLevelList);
    return logLevelList.get(logLevelList.size() - 1);
  }

  private static boolean hasLogOutput(AggregatedExecutionLog aggregatedLog) {
    return aggregatedLog != null && aggregatedLog.getLogs() != null && !aggregatedLog.getLogs().isEmpty();
  }

  private static List<Map<String, Object>> formatLogOutput(AggregatedExecutionLog aggregatedLog) {
    List<Map<String, Object>> output = Lists.newArrayList();
    for (ExecutionLogWithContext logWithContext : aggregatedLog.getLogs()) {
      Map<String, Object> logMap = Maps.newHashMap();
      ComputationTargetSpecification target = logWithContext.getTargetSpecification();
      logMap.put(FUNCTION_NAME, logWithContext.getFunctionName());
      logMap.put(TARGET, target.getType() + " " + target.getUniqueId());
      ExecutionLog log = logWithContext.getExecutionLog();
      if (log.hasException()) {
        logMap.put(EXCEPTION_CLASS, log.getExceptionClass());
        logMap.put(EXCEPTION_MESSAGE, log.getExceptionMessage());
        logMap.put(EXCEPTION_STACK_TRACE, log.getExceptionStackTrace());
      }
      List<Map<String, Object>> events = Lists.newArrayList();
      logMap.put(EVENTS, events);
      if (log.getEvents() != null) {
        for (LogEvent logEvent : log.getEvents()) {
          events.add(ImmutableMap.<String, Object>of(LEVEL, logEvent.getLevel(), MESSAGE, logEvent.getMessage()));
        }
      }
      output.add(logMap);
    }
    return output;
  }

  /**
   * Formats history data as a JSON list.
   *
   * @param cellValueSpec The cell's value specification, can be null
   * @param inlineKey If the cell contains a single value derived from an inlined value, this object is the key
   * to obtain the cell's value from the underlying value.
   *@param history The history values, not null  @return The formatted history
   */
  private List<Object> formatHistory(ValueSpecification cellValueSpec, Object inlineKey, Collection<Object> history) {
    List<Object> formattedHistory = Lists.newArrayListWithCapacity(history.size());
    for (Object historyValue : history) {
      Object formattedValue = _formatter.format(historyValue, cellValueSpec, TypeFormatter.Format.HISTORY, inlineKey);
      if (formattedValue != ResultsFormatter.VALUE_UNAVAILABLE) {
        formattedHistory.add(formattedValue);
      }
    }
    // it's possible for an object to have history but not to have any formatted history if it's inlined. some inline
    // keys won't have a value for some inlined results. in that case the cell will have empty history although
    // there is history for the underlying value
    if (formattedHistory.isEmpty()) {
      return null;
    } else {
      return formattedHistory;
    }
  }
}
TOP

Related Classes of com.opengamma.web.analytics.ViewportResultsJsonCsvWriter

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.