/**
* Copyright (C) 2012 - present by OpenGamma Inc. and the OpenGamma group of companies
*
* Please see distribution for license.
*/
package com.opengamma.web.analytics;
import java.util.List;
import java.util.Map;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import org.threeten.bp.LocalDate;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.Lists;
import com.opengamma.engine.marketdata.spec.FixedHistoricalMarketDataSpecification;
import com.opengamma.engine.marketdata.spec.LatestHistoricalMarketDataSpecification;
import com.opengamma.engine.marketdata.spec.LiveMarketDataSpecification;
import com.opengamma.engine.marketdata.spec.MarketDataSpecification;
import com.opengamma.engine.marketdata.spec.RandomizingMarketDataSpecification;
import com.opengamma.engine.marketdata.spec.UserMarketDataSpecification;
import com.opengamma.id.UniqueId;
/**
* <p>Creates instances of {@link MarketDataSpecification} subclasses from JSON. The JSON format is:</p>
* <h4>Live Data</h4>
* <code>{"marketDataType": "live", "source": "Bloomberg"}</code>
* <h4>Fixed Historical Data</h4>
* <code>{"marketDataType": "fixedHistorical", "resolverKey": "TSS_CONFIG", "date": "2012-08-30"}</code>
* <h4>Latest Historical Data</h4>
* <code>{"marketDataType": "latestHistorical", "resolverKey": "TSS_CONFIG"}</code>
* <h4>Snapshot Data</h4>
* <code>{"marketDataType": "snapshot", "snapshotId": "Snap~1234"}</code>
* <h4>Randomized Snapshot Data</h4>
* <code>{"marketDataType": "snapshot", "snapshotId": "Snap~1234", "updateProbability": "0.2",
* "maxPercentageChange": "5", "averageCycleInterval": "1000"}</code>
* <p>There are REST endpoints for looking up available values for live data source names, resolver keys and
* snapshot IDs. See the package documentation for {@link com.opengamma.web.analytics.rest}.</p>
*/
public class MarketDataSpecificationJsonReader {
private static final String SNAPSHOT_ID = "snapshotId";
private static final String RESOLVER_KEY = "resolverKey";
private static final String SOURCE = "source";
private static final String SNAPSHOT = "snapshot";
private static final String RANDOMIZED_SNAPSHOT = "randomizedsnapshot";
private static final String MARKET_DATA_TYPE = "marketDataType";
private static final String LIVE = "live";
private static final String LATEST_HISTORICAL = "latestHistorical";
private static final String FIXED_HISTORICAL = "fixedHistorical";
private static final String DATE = "date";
private static final String UPDATE_PROBABILITY = "updateProbability";
private static final String MAX_PERCENTAGE_CHANGE = "maxPercentageChange";
private static final String AVERAGE_CYCLE_INTERVAL = "averageCycleInterval";
/** Builders keyed by the name of the market data type. */
private static final Map<String, SpecificationBuilder> s_builders = ImmutableMap.of(
LIVE, new LiveSpecificationBuilder(),
LATEST_HISTORICAL, new LatestHistoricalSpecificationBuilder(),
FIXED_HISTORICAL, new FixedHistoricalSpecificationBuilder(),
SNAPSHOT, new SnapshotSpecificationBuilder(),
RANDOMIZED_SNAPSHOT, new RandomSnapshotSpecificationBuilder()
);
public static MarketDataSpecification buildSpecification(String json) throws JSONException {
return buildSpecification(new JSONObject(json));
}
private static MarketDataSpecification buildSpecification(JSONObject json) throws JSONException {
String marketDataType = json.getString(MARKET_DATA_TYPE);
SpecificationBuilder builder = s_builders.get(marketDataType);
if (builder == null) {
throw new IllegalArgumentException("No builder found for market data type " + marketDataType);
}
return builder.build(json);
}
public static List<MarketDataSpecification> buildSpecifications(String json) {
try {
JSONArray array = new JSONArray(json);
List<MarketDataSpecification> specs = Lists.newArrayListWithCapacity(array.length());
for (int i = 0; i < array.length(); i++) {
specs.add(buildSpecification(array.getJSONObject(i)));
}
return specs;
} catch (JSONException e) {
throw new IllegalArgumentException("Failed to parse MarketDataSpecification JSON", e);
}
}
/** For classes that can build instances of {@link MarketDataSpecification} subclasses. */
private interface SpecificationBuilder {
MarketDataSpecification build(JSONObject json) throws JSONException;
}
/** Builds instances of {@link LiveMarketDataSpecification}. */
private static class LiveSpecificationBuilder implements SpecificationBuilder {
@Override
public MarketDataSpecification build(JSONObject json) throws JSONException {
return LiveMarketDataSpecification.of(json.getString(MarketDataSpecificationJsonReader.SOURCE));
}
}
/** Builds instances of {@link LatestHistoricalMarketDataSpecification}. */
private static class LatestHistoricalSpecificationBuilder implements SpecificationBuilder {
@Override
public MarketDataSpecification build(JSONObject json) throws JSONException {
return new LatestHistoricalMarketDataSpecification(
json.getString(MarketDataSpecificationJsonReader.RESOLVER_KEY));
}
}
/** Builds instances of {@link FixedHistoricalMarketDataSpecification}. */
private static class FixedHistoricalSpecificationBuilder implements SpecificationBuilder {
@Override
public MarketDataSpecification build(JSONObject json) throws JSONException {
return new FixedHistoricalMarketDataSpecification(
json.getString(MarketDataSpecificationJsonReader.RESOLVER_KEY),
LocalDate.parse(json.getString(DATE)));
}
}
/** Builds instances of {@link UserMarketDataSpecification}. */
private static class SnapshotSpecificationBuilder implements SpecificationBuilder {
@Override
public MarketDataSpecification build(JSONObject json) throws JSONException {
return UserMarketDataSpecification.of(UniqueId.parse(json.getString(MarketDataSpecificationJsonReader.SNAPSHOT_ID)));
}
}
/** Builds instances of {@link UserMarketDataSpecification}. */
private static class RandomSnapshotSpecificationBuilder implements SpecificationBuilder {
@Override
public MarketDataSpecification build(JSONObject json) throws JSONException {
return RandomizingMarketDataSpecification.of(
UserMarketDataSpecification.of(UniqueId.parse(json.getString(MarketDataSpecificationJsonReader.SNAPSHOT_ID))),
json.getDouble(MarketDataSpecificationJsonReader.UPDATE_PROBABILITY),
json.getInt(MarketDataSpecificationJsonReader.MAX_PERCENTAGE_CHANGE),
json.getLong(MarketDataSpecificationJsonReader.AVERAGE_CYCLE_INTERVAL)
);
}
}
}