Package com.opengamma.masterdb.holiday

Source Code of com.opengamma.masterdb.holiday.DbHolidayMaster

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

import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Timestamp;
import java.sql.Types;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.EnumMap;
import java.util.List;

import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.dao.DataAccessException;
import org.springframework.jdbc.core.ResultSetExtractor;
import org.threeten.bp.LocalDate;

import com.codahale.metrics.MetricRegistry;
import com.codahale.metrics.Timer;
import com.opengamma.core.holiday.HolidayType;
import com.opengamma.elsql.ElSqlBundle;
import com.opengamma.id.ExternalId;
import com.opengamma.id.ExternalIdSearch;
import com.opengamma.id.ExternalIdSearchType;
import com.opengamma.id.ObjectId;
import com.opengamma.id.ObjectIdentifiable;
import com.opengamma.id.UniqueId;
import com.opengamma.id.VersionCorrection;
import com.opengamma.master.AbstractHistoryRequest;
import com.opengamma.master.AbstractHistoryResult;
import com.opengamma.master.holiday.HolidayDocument;
import com.opengamma.master.holiday.HolidayHistoryRequest;
import com.opengamma.master.holiday.HolidayHistoryResult;
import com.opengamma.master.holiday.HolidayMaster;
import com.opengamma.master.holiday.HolidayMetaDataRequest;
import com.opengamma.master.holiday.HolidayMetaDataResult;
import com.opengamma.master.holiday.HolidaySearchRequest;
import com.opengamma.master.holiday.HolidaySearchResult;
import com.opengamma.master.holiday.HolidaySearchSortOrder;
import com.opengamma.master.holiday.ManageableHoliday;
import com.opengamma.masterdb.AbstractDocumentDbMaster;
import com.opengamma.util.ArgumentChecker;
import com.opengamma.util.db.DbConnector;
import com.opengamma.util.db.DbDateUtils;
import com.opengamma.util.db.DbMapSqlParameterSource;
import com.opengamma.util.money.Currency;
import com.opengamma.util.paging.Paging;

/**
* A holiday master implementation using a database for persistence.
* <p>
* This is a full implementation of the holiday master using an SQL database.
* Full details of the API are in {@link HolidayMaster}.
* <p>
* The SQL is stored externally in {@code DbHolidayMaster.elsql}.
* Alternate databases or specific SQL requirements can be handled using database
* specific overrides, such as {@code DbHolidayMaster-MySpecialDB.elsql}.
* <p>
* This class is mutable but must be treated as immutable after configuration.
*/
public class DbHolidayMaster extends AbstractDocumentDbMaster<HolidayDocument> implements HolidayMaster {

  /** Logger. */
  private static final Logger s_logger = LoggerFactory.getLogger(DbHolidayMaster.class);

  /**
   * The default scheme for unique identifiers.
   */
  public static final String IDENTIFIER_SCHEME_DEFAULT = "DbHol";

  /**
   * SQL order by.
   */
  protected static final EnumMap<HolidaySearchSortOrder, String> ORDER_BY_MAP = new EnumMap<HolidaySearchSortOrder, String>(HolidaySearchSortOrder.class);
  static {
    ORDER_BY_MAP.put(HolidaySearchSortOrder.OBJECT_ID_ASC, "oid ASC");
    ORDER_BY_MAP.put(HolidaySearchSortOrder.OBJECT_ID_DESC, "oid DESC");
    ORDER_BY_MAP.put(HolidaySearchSortOrder.VERSION_FROM_INSTANT_ASC, "ver_from_instant ASC");
    ORDER_BY_MAP.put(HolidaySearchSortOrder.VERSION_FROM_INSTANT_DESC, "ver_from_instant DESC");
    ORDER_BY_MAP.put(HolidaySearchSortOrder.NAME_ASC, "name ASC");
    ORDER_BY_MAP.put(HolidaySearchSortOrder.NAME_DESC, "name DESC");
  }

  // -----------------------------------------------------------------
  // TIMERS FOR METRICS GATHERING
  // By default these do nothing. Registration will replace them
  // so that they actually do something.
  // -----------------------------------------------------------------
  private Timer _insertTimer = new Timer();
 
  /**
   * Creates an instance.
   *
   * @param dbConnector  the database connector, not null
   */
  public DbHolidayMaster(final DbConnector dbConnector) {
    super(dbConnector, IDENTIFIER_SCHEME_DEFAULT);
    setElSqlBundle(ElSqlBundle.of(dbConnector.getDialect().getElSqlConfig(), DbHolidayMaster.class));
  }

  @Override
  public void registerMetrics(MetricRegistry summaryRegistry, MetricRegistry detailedRegistry, String namePrefix) {
    super.registerMetrics(summaryRegistry, detailedRegistry, namePrefix);
    _insertTimer = summaryRegistry.timer(namePrefix + ".insert");
  }

  //-------------------------------------------------------------------------
  @Override
  public HolidayMetaDataResult metaData(HolidayMetaDataRequest request) {
    ArgumentChecker.notNull(request, "request");
    HolidayMetaDataResult result = new HolidayMetaDataResult();
    if (request.isHolidayTypes()) {
      result.getHolidayTypes().addAll(Arrays.asList(HolidayType.values()));
    }
    return result;
  }

  //-------------------------------------------------------------------------
  @Override
  public HolidaySearchResult search(final HolidaySearchRequest request) {
    ArgumentChecker.notNull(request, "request");
    ArgumentChecker.notNull(request.getPagingRequest(), "request.pagingRequest");
    ArgumentChecker.notNull(request.getVersionCorrection(), "request.versionCorrection");
    s_logger.debug("search {}", request);
   
    final VersionCorrection vc = request.getVersionCorrection().withLatestFixed(now());
    final HolidaySearchResult result = new HolidaySearchResult(vc);
   
    ExternalIdSearch regionSearch = request.getRegionExternalIdSearch();
    ExternalIdSearch exchangeSearch = request.getExchangeExternalIdSearch();
    String currencyISO = (request.getCurrency() != null ? request.getCurrency().getCode() : null);
    if ((request.getHolidayObjectIds() != null && request.getHolidayObjectIds().size() == 0) ||
        ExternalIdSearch.canMatch(regionSearch) == false ||
        ExternalIdSearch.canMatch(exchangeSearch) == false) {
      result.setPaging(Paging.of(request.getPagingRequest(), 0));
      return result;
    }
   
    final DbMapSqlParameterSource args = new DbMapSqlParameterSource()
      .addTimestamp("version_as_of_instant", vc.getVersionAsOf())
      .addTimestamp("corrected_to_instant", vc.getCorrectedTo())
      .addValueNullIgnored("name", getDialect().sqlWildcardAdjustValue(request.getName()))
      .addValueNullIgnored("hol_type", request.getType() != null ? request.getType().name() : null)
      .addValueNullIgnored("currency_iso", currencyISO);
    if (request.getProviderId() != null) {
      args.addValue("provider_scheme", request.getProviderId().getScheme().getName());
      args.addValue("provider_value", request.getProviderId().getValue());
    }
    if (regionSearch != null) {
      if (regionSearch.getSearchType() != ExternalIdSearchType.ANY) {
        throw new IllegalArgumentException("Unsupported search type: " + regionSearch.getSearchType());
      }
      int i = 0;
      for (ExternalId idKey : regionSearch.getExternalIds()) {
        args.addValue("region_scheme" + i, idKey.getScheme().getName());
        args.addValue("region_value" + i, idKey.getValue());
        i++;
      }
      args.addValue("sql_search_region_ids", sqlSelectIdKeys(request.getRegionExternalIdSearch(), "region"));
    }
    if (exchangeSearch != null) {
      if (exchangeSearch.getSearchType() != ExternalIdSearchType.ANY) {
        throw new IllegalArgumentException("Unsupported search type: " + exchangeSearch.getSearchType());
      }
      int i = 0;
      for (ExternalId idKey : exchangeSearch.getExternalIds()) {
        args.addValue("exchange_scheme" + i, idKey.getScheme().getName());
        args.addValue("exchange_value" + i, idKey.getValue());
        i++;
      }
      args.addValue("sql_search_exchange_ids", sqlSelectIdKeys(request.getExchangeExternalIdSearch(), "exchange"));
    }
    if (request.getHolidayObjectIds() != null) {
      StringBuilder buf = new StringBuilder(request.getHolidayObjectIds().size() * 10);
      for (ObjectId objectId : request.getHolidayObjectIds()) {
        checkScheme(objectId);
        buf.append(extractOid(objectId)).append(", ");
      }
      buf.setLength(buf.length() - 2);
      args.addValue("sql_search_object_ids", buf.toString());
    }
    args.addValue("sort_order", ORDER_BY_MAP.get(request.getSortOrder()));
    args.addValue("paging_offset", request.getPagingRequest().getFirstItem());
    args.addValue("paging_fetch", request.getPagingRequest().getPagingSize());
   
    final String[] sql = {getElSqlBundle().getSql("Search", args), getElSqlBundle().getSql("SearchCount", args)};
    doSearch(request.getPagingRequest(), sql, args, new HolidayDocumentExtractor(), result);
    return result;
  }

  /**
   * Gets the SQL to search for ids.
   * <p>
   * This is too complex for the elsql mechanism.
   *
   * @param bundle  the bundle, not null
   * @param type  the type to search for, not null
   * @return the SQL search and count, not null
   */
  protected String sqlSelectIdKeys(final ExternalIdSearch bundle, final String type) {
    List<String> list = new ArrayList<String>();
    for (int i = 0; i < bundle.size(); i++) {
      list.add("(" + type + "_scheme = :" + type + "_scheme" + i + " AND " + type + "_value = :" + type + "_value" + i + ") ");
    }
    return StringUtils.join(list, "OR ");
  }

  //-------------------------------------------------------------------------
  @Override
  public HolidayDocument get(final UniqueId uniqueId) {
    return doGet(uniqueId, new HolidayDocumentExtractor(), "Holiday");
  }

  //-------------------------------------------------------------------------
  @Override
  public HolidayDocument get(final ObjectIdentifiable objectId, final VersionCorrection versionCorrection) {
    return doGetByOidInstants(objectId, versionCorrection, new HolidayDocumentExtractor(), "Holiday");
  }

  //-------------------------------------------------------------------------
  @Override
  public HolidayHistoryResult history(final HolidayHistoryRequest request) {
    return doHistory(request, new HolidayHistoryResult(), new HolidayDocumentExtractor());
  }

  //-------------------------------------------------------------------------
  /**
   * Inserts a new document.
   *
   * @param document  the document, not null
   * @return the new document, not null
   */
  @Override
  protected HolidayDocument insert(final HolidayDocument document) {
    ArgumentChecker.notNull(document.getHoliday(), "document.holiday");
    ArgumentChecker.notNull(document.getHoliday().getType(), "document.holiday.type");
    ArgumentChecker.notNull(document.getName(), "document.name");
    switch (document.getHoliday().getType()) {
      case BANK:
        ArgumentChecker.notNull(document.getHoliday().getRegionExternalId(), "document.holiday.region");
        break;
      case CURRENCY:
        ArgumentChecker.notNull(document.getHoliday().getCurrency(), "document.holiday.currency");
        break;
      case TRADING:
      case SETTLEMENT:
        ArgumentChecker.notNull(document.getHoliday().getExchangeExternalId(), "document.holiday.exchange");
        break;
      default:
        throw new IllegalArgumentException("Holiday type not set");
    }
   
    try (Timer.Context context = _insertTimer.time()) {
      final long docId = nextId("hol_holiday_seq");
      final long docOid = (document.getUniqueId() != null ? extractOid(document.getUniqueId()) : docId);
      // the arguments for inserting into the holiday table
      final ManageableHoliday holiday = document.getHoliday();
      final DbMapSqlParameterSource docArgs = new DbMapSqlParameterSource()
        .addValue("doc_id", docId)
        .addValue("doc_oid", docOid)
        .addTimestamp("ver_from_instant", document.getVersionFromInstant())
        .addTimestampNullFuture("ver_to_instant", document.getVersionToInstant())
        .addTimestamp("corr_from_instant", document.getCorrectionFromInstant())
        .addTimestampNullFuture("corr_to_instant", document.getCorrectionToInstant())
        .addValue("name", document.getName())
        .addValue("provider_scheme",
            document.getProviderId() != null ? document.getProviderId().getScheme().getName() : null,
            Types.VARCHAR)
        .addValue("provider_value",
            document.getProviderId() != null ? document.getProviderId().getValue() : null,
            Types.VARCHAR)
        .addValue("hol_type", holiday.getType().name())
        .addValue("region_scheme",
            holiday.getRegionExternalId() != null ? holiday.getRegionExternalId().getScheme().getName() : null,
            Types.VARCHAR)
        .addValue("region_value",
            holiday.getRegionExternalId() != null ? holiday.getRegionExternalId().getValue() : null,
            Types.VARCHAR)
        .addValue("exchange_scheme",
            holiday.getExchangeExternalId() != null ? holiday.getExchangeExternalId().getScheme().getName() : null,
            Types.VARCHAR)
        .addValue("exchange_value",
            holiday.getExchangeExternalId() != null ? holiday.getExchangeExternalId().getValue() : null,
            Types.VARCHAR)
        .addValue("currency_iso",
            holiday.getCurrency() != null ? holiday.getCurrency().getCode() : null,
            Types.VARCHAR);
      // the arguments for inserting into the date table
      final List<DbMapSqlParameterSource> dateList = new ArrayList<DbMapSqlParameterSource>();
      for (LocalDate date : holiday.getHolidayDates()) {
        final DbMapSqlParameterSource dateArgs = new DbMapSqlParameterSource()
          .addValue("doc_id", docId)
          .addDate("hol_date", date);
        dateList.add(dateArgs);
      }
      final String sqlDoc = getElSqlBundle().getSql("Insert", docArgs);
      final String sqlDate = getElSqlBundle().getSql("InsertDate");
      getJdbcTemplate().update(sqlDoc, docArgs);
      getJdbcTemplate().batchUpdate(sqlDate, dateList.toArray(new DbMapSqlParameterSource[dateList.size()]));
      // set the uniqueId
      final UniqueId uniqueId = createUniqueId(docOid, docId);
      holiday.setUniqueId(uniqueId);
      document.setUniqueId(uniqueId);
      return document;
    }
   
  }

  //-------------------------------------------------------------------------
  /**
   * Mapper from SQL rows to a HolidayDocument.
   */
  protected final class HolidayDocumentExtractor implements ResultSetExtractor<List<HolidayDocument>> {
    private long _lastDocId = -1;
    private ManageableHoliday _holiday;
    private List<HolidayDocument> _documents = new ArrayList<HolidayDocument>();

    @Override
    public List<HolidayDocument> extractData(final ResultSet rs) throws SQLException, DataAccessException {
      while (rs.next()) {
        final long docId = rs.getLong("DOC_ID");
        if (_lastDocId != docId) {
          _lastDocId = docId;
          buildHoliday(rs, docId);
        }
        final LocalDate holDate = DbDateUtils.fromSqlDate(rs.getDate("HOL_DATE"));
        _holiday.getHolidayDates().add(holDate);
      }
      return _documents;
    }

    private void buildHoliday(final ResultSet rs, final long docId) throws SQLException {
      final long docOid = rs.getLong("DOC_OID");
      final Timestamp versionFrom = rs.getTimestamp("VER_FROM_INSTANT");
      final Timestamp versionTo = rs.getTimestamp("VER_TO_INSTANT");
      final Timestamp correctionFrom = rs.getTimestamp("CORR_FROM_INSTANT");
      final Timestamp correctionTo = rs.getTimestamp("CORR_TO_INSTANT");
      final String name = rs.getString("NAME");
      final String type = rs.getString("HOL_TYPE");
      final String providerScheme = rs.getString("PROVIDER_SCHEME");
      final String providerValue = rs.getString("PROVIDER_VALUE");
      final String regionScheme = rs.getString("REGION_SCHEME");
      final String regionValue = rs.getString("REGION_VALUE");
      final String exchangeScheme = rs.getString("EXCHANGE_SCHEME");
      final String exchangeValue = rs.getString("EXCHANGE_VALUE");
      final String currencyISO = rs.getString("CURRENCY_ISO");
      UniqueId uniqueId = createUniqueId(docOid, docId);
      ManageableHoliday holiday = new ManageableHoliday();
      holiday.setUniqueId(uniqueId);
      holiday.setType(HolidayType.valueOf(type));
      if (regionScheme != null && regionValue != null) {
        holiday.setRegionExternalId(ExternalId.of(regionScheme, regionValue));
      }
      if (exchangeScheme != null && exchangeValue != null) {
        holiday.setExchangeExternalId(ExternalId.of(exchangeScheme, exchangeValue));
      }
      if (currencyISO != null) {
        holiday.setCurrency(Currency.of(currencyISO));
      }
      HolidayDocument doc = new HolidayDocument(holiday);
      doc.setVersionFromInstant(DbDateUtils.fromSqlTimestamp(versionFrom));
      doc.setVersionToInstant(DbDateUtils.fromSqlTimestampNullFarFuture(versionTo));
      doc.setCorrectionFromInstant(DbDateUtils.fromSqlTimestamp(correctionFrom));
      doc.setCorrectionToInstant(DbDateUtils.fromSqlTimestampNullFarFuture(correctionTo));
      doc.setUniqueId(uniqueId);
      doc.setName(name);
      if (providerScheme != null && providerValue != null) {
        doc.setProviderId(ExternalId.of(providerScheme, providerValue));
      }
      _holiday = doc.getHoliday();
      _documents.add(doc);
    }
  }

  @Override
  protected AbstractHistoryResult<HolidayDocument> historyByVersionsCorrections(AbstractHistoryRequest request) {
    HolidayHistoryRequest historyRequest = new HolidayHistoryRequest();
    historyRequest.setCorrectionsFromInstant(request.getCorrectionsFromInstant());
    historyRequest.setCorrectionsToInstant(request.getCorrectionsToInstant());
    historyRequest.setVersionsFromInstant(request.getVersionsFromInstant());
    historyRequest.setVersionsToInstant(request.getVersionsToInstant());
    historyRequest.setObjectId(request.getObjectId());
    return history(historyRequest);
  }

}
TOP

Related Classes of com.opengamma.masterdb.holiday.DbHolidayMaster

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.