Package com.opengamma.masterdb.security.hibernate

Source Code of com.opengamma.masterdb.security.hibernate.HibernateSecurityMasterDetailProvider

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

import java.sql.SQLException;
import java.util.Date;
import java.util.Locale;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;

import org.hibernate.HibernateException;
import org.hibernate.Session;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.orm.hibernate3.HibernateCallback;
import org.springframework.orm.hibernate3.HibernateTemplate;

import com.google.common.base.Objects;
import com.opengamma.OpenGammaRuntimeException;
import com.opengamma.core.security.Security;
import com.opengamma.financial.security.bond.BondSecuritySearchRequest;
import com.opengamma.financial.security.swap.SwapSecurity;
import com.opengamma.financial.security.swap.YearOnYearInflationSwapSecurity;
import com.opengamma.financial.security.swap.ZeroCouponInflationSwapSecurity;
import com.opengamma.master.security.ManageableSecurity;
import com.opengamma.master.security.SecuritySearchRequest;
import com.opengamma.masterdb.security.DbSecurityMaster;
import com.opengamma.masterdb.security.SecurityMasterDetailProvider;
import com.opengamma.masterdb.security.hibernate.bond.BondSecurityBeanOperation;
import com.opengamma.masterdb.security.hibernate.capfloor.CapFloorCMSSpreadSecurityBeanOperation;
import com.opengamma.masterdb.security.hibernate.capfloor.CapFloorSecurityBeanOperation;
import com.opengamma.masterdb.security.hibernate.cash.CashSecurityBeanOperation;
import com.opengamma.masterdb.security.hibernate.cashflow.CashFlowSecurityBeanOperation;
import com.opengamma.masterdb.security.hibernate.cds.CDSSecurityBeanOperation;
import com.opengamma.masterdb.security.hibernate.cds.CreditDefaultSwapIndexDefinitionSecurityBeanOperation;
import com.opengamma.masterdb.security.hibernate.cds.CreditDefaultSwapIndexSecurityBeanOperation;
import com.opengamma.masterdb.security.hibernate.cds.LegacyFixedRecoveryCDSSecurityBeanOperation;
import com.opengamma.masterdb.security.hibernate.cds.LegacyRecoveryLockCDSSecurityBeanOperation;
import com.opengamma.masterdb.security.hibernate.cds.LegacyVanillaCDSSecurityBeanOperation;
import com.opengamma.masterdb.security.hibernate.cds.StdFixedRecoveryCDSSecurityBeanOperation;
import com.opengamma.masterdb.security.hibernate.cds.StdRecoveryLockCDSSecurityBeanOperation;
import com.opengamma.masterdb.security.hibernate.cds.StdVanillaCDSSecurityBeanOperation;
import com.opengamma.masterdb.security.hibernate.equity.EquitySecurityBeanOperation;
import com.opengamma.masterdb.security.hibernate.equity.EquityVarianceSwapSecurityBeanOperation;
import com.opengamma.masterdb.security.hibernate.forward.CommodityForwardSecurityBeanOperation;
import com.opengamma.masterdb.security.hibernate.fra.FRASecurityBeanOperation;
import com.opengamma.masterdb.security.hibernate.future.FutureSecurityBeanOperation;
import com.opengamma.masterdb.security.hibernate.fx.FXForwardSecurityBeanOperation;
import com.opengamma.masterdb.security.hibernate.fx.NonDeliverableFXForwardSecurityBeanOperation;
import com.opengamma.masterdb.security.hibernate.option.BondFutureOptionSecurityBeanOperation;
import com.opengamma.masterdb.security.hibernate.option.CDSOptionSecurityBeanOperation;
import com.opengamma.masterdb.security.hibernate.option.CommodityFutureOptionSecurityBeanOperation;
import com.opengamma.masterdb.security.hibernate.option.EquityBarrierOptionSecurityBeanOperation;
import com.opengamma.masterdb.security.hibernate.option.EquityIndexDividendFutureOptionSecurityBeanOperation;
import com.opengamma.masterdb.security.hibernate.option.EquityIndexFutureOptionSecurityBeanOperation;
import com.opengamma.masterdb.security.hibernate.option.EquityIndexOptionSecurityBeanOperation;
import com.opengamma.masterdb.security.hibernate.option.EquityOptionSecurityBeanOperation;
import com.opengamma.masterdb.security.hibernate.option.FxBarrierOptionSecurityBeanOperation;
import com.opengamma.masterdb.security.hibernate.option.FxDigitalOptionSecurityBeanOperation;
import com.opengamma.masterdb.security.hibernate.option.FxFutureOptionSecurityBeanOperation;
import com.opengamma.masterdb.security.hibernate.option.FxOptionSecurityBeanOperation;
import com.opengamma.masterdb.security.hibernate.option.IRFutureOptionSecurityBeanOperation;
import com.opengamma.masterdb.security.hibernate.option.NonDeliverableFxDigitalOptionSecurityBeanOperation;
import com.opengamma.masterdb.security.hibernate.option.NonDeliverableFxOptionSecurityBeanOperation;
import com.opengamma.masterdb.security.hibernate.option.SwaptionSecurityBeanOperation;
import com.opengamma.masterdb.security.hibernate.swap.SwapSecurityBeanOperation;
import com.opengamma.util.db.DbConnector;
import com.opengamma.util.db.DbDialect;
import com.opengamma.util.db.DbMapSqlParameterSource;

/**
* Provides access to persist the full bean structure of the security.
* This supports the default {@link DbSecurityMaster} implementations.
*/
public class HibernateSecurityMasterDetailProvider implements SecurityMasterDetailProvider {

  /** Logger. */
  private static final Logger s_logger = LoggerFactory.getLogger(HibernateSecurityMasterDetailProvider.class);
  private static final ConcurrentMap<Class<?>, SecurityBeanOperation<?, ?>> BEAN_OPERATIONS_BY_SECURITY = new ConcurrentHashMap<Class<?>, SecurityBeanOperation<?, ?>>();
  private static final ConcurrentMap<Class<?>, SecurityBeanOperation<?, ?>> BEAN_OPERATIONS_BY_BEAN = new ConcurrentHashMap<Class<?>, SecurityBeanOperation<?, ?>>();
  private static final ConcurrentMap<String, SecurityBeanOperation<?, ?>> BEAN_OPERATIONS_BY_TYPE = new ConcurrentHashMap<String, SecurityBeanOperation<?, ?>>();

  /**
   * The database connector.
   */
  private DbConnector _dbConnector;
  /**
   * The operation context for management additional resources.
   */
  private final OperationContext _operationContext = new OperationContext();

  //-------------------------------------------------------------------------
  private static void loadBeanOperation(final SecurityBeanOperation<?, ?> beanOperation) {
    if (BEAN_OPERATIONS_BY_SECURITY.containsKey(beanOperation.getSecurityClass())) {
      s_logger.error(beanOperation.getSecurityClass() + " is already registered in BEAN_OPERATIONS_BY_SECURITY");
      throw new OpenGammaRuntimeException(beanOperation.getSecurityClass() + " is already registered in BEAN_OPERATIONS_BY_SECURITY");
    }
    BEAN_OPERATIONS_BY_SECURITY.put(beanOperation.getSecurityClass(), beanOperation);
    if (BEAN_OPERATIONS_BY_BEAN.containsKey(beanOperation.getBeanClass())) {
      s_logger.error(beanOperation.getBeanClass() + " is already registered in BEAN_OPERATIONS_BY_SECURITY");
      throw new OpenGammaRuntimeException(beanOperation.getBeanClass() + " is already registered in BEAN_OPERATIONS_BY_SECURITY");
    }
    BEAN_OPERATIONS_BY_BEAN.put(beanOperation.getBeanClass(), beanOperation);
    if (BEAN_OPERATIONS_BY_TYPE.containsKey(beanOperation.getSecurityType())) {
      s_logger.error(beanOperation.getBeanClass() + " is already registered in BEAN_OPERATIONS_BY_SECURITY");
      throw new OpenGammaRuntimeException(beanOperation.getBeanClass() + " is already registered in BEAN_OPERATIONS_BY_SECURITY");
    }
    BEAN_OPERATIONS_BY_TYPE.put(beanOperation.getSecurityType(), beanOperation)
  }


  /**
   * Provides a way to add a bean operation to the hibernate configuration.
   *
   * Ideally this method should not be public but a way is needed of allowing this class to
   * be extended (or composed with) such that other projecvts can add their own security types.
   * Exposing this method is the simplest way to achieve this at the moment. Longer term we would
   * expect hibernate to be removed in which case it will all become simpler.
   *
   * @param beanOperation the bean operation to be stored
   */
  public void addBeanOperation(final SecurityBeanOperation<?, ?> beanOperation) {
    if (BEAN_OPERATIONS_BY_SECURITY.containsKey(beanOperation.getSecurityClass()) ||
        BEAN_OPERATIONS_BY_BEAN.containsKey(beanOperation.getBeanClass()) ||
        BEAN_OPERATIONS_BY_TYPE.containsKey(beanOperation.getSecurityType())) {

      s_logger.warn(beanOperation.getBeanClass() + " is already registered");

    } else {
      loadBeanOperation(beanOperation);
    }
  }

  private static SecurityBeanOperation<?, ?> getBeanOperation(final ConcurrentMap<Class<?>, SecurityBeanOperation<?, ?>> map, final Class<?> clazz) {
    SecurityBeanOperation<?, ?> beanOperation = map.get(clazz);
    if (beanOperation != null) {
      return beanOperation;
    }
    if (clazz.getSuperclass() == null) {
      return null;
    }
    beanOperation = getBeanOperation(map, clazz.getSuperclass());
    if (beanOperation != null) {
      map.put(clazz, beanOperation);
    }
    return beanOperation;
  }

  @SuppressWarnings("unchecked")
  private static <T extends Security> SecurityBeanOperation<T, SecurityBean> getBeanOperation(final T security) {
    final SecurityBeanOperation<?, ?> beanOperation = getBeanOperation(BEAN_OPERATIONS_BY_SECURITY, security.getClass());
    if (beanOperation == null) {
      throw new OpenGammaRuntimeException("can't find BeanOperation for " + security);
    }
    return (SecurityBeanOperation<T, SecurityBean>) beanOperation;
  }

//  @SuppressWarnings("unchecked")
//  private static <T extends SecurityBean> SecurityBeanOperation<Security, T> getBeanOperation(final T bean) {
//    final SecurityBeanOperation<?, ?> beanOperation = getBeanOperation(BEAN_OPERATIONS_BY_BEAN, bean.getClass());
//    if (beanOperation == null) {
//      throw new OpenGammaRuntimeException("can't find BeanOperation for " + bean);
//    }
//    return (SecurityBeanOperation<Security, T>) beanOperation;
//  }

  @SuppressWarnings("unchecked")
  private static <T extends SecurityBean> SecurityBeanOperation<Security, T> getBeanOperation(final String type) {
    SecurityBeanOperation<?, ?> beanOperation = BEAN_OPERATIONS_BY_TYPE.get(type.toUpperCase(Locale.ENGLISH))// upper case handles "Cash"
    if (beanOperation == null) {
      if (type.contains("_")) {
        beanOperation = BEAN_OPERATIONS_BY_TYPE.get(type.substring(type.indexOf('_') + 1));
      }
      if (type.equals("SWAPTION")) { // SWAPTION used to be SWAP_OPTION, in which case the above code handled it.
        beanOperation = BEAN_OPERATIONS_BY_TYPE.get("OPTION");
      }
      if (ZeroCouponInflationSwapSecurity.SECURITY_TYPE.equals(type) || YearOnYearInflationSwapSecurity.SECURITY_TYPE.equals(type)) {
        beanOperation = BEAN_OPERATIONS_BY_TYPE.get(SwapSecurity.SECURITY_TYPE);
      }
      if (beanOperation == null) {
        throw new OpenGammaRuntimeException("can't find BeanOperation for " + type);
      }
    }
    return (SecurityBeanOperation<Security, T>) beanOperation;
  }

  static {
    // TODO 2010-07-21 Should we load these from a .properties file like the other factories
    loadBeanOperation(BondSecurityBeanOperation.INSTANCE);
    loadBeanOperation(CashSecurityBeanOperation.INSTANCE);
    loadBeanOperation(EquitySecurityBeanOperation.INSTANCE);
    loadBeanOperation(FRASecurityBeanOperation.INSTANCE);
    loadBeanOperation(CommodityForwardSecurityBeanOperation.INSTANCE);
    loadBeanOperation(FutureSecurityBeanOperation.INSTANCE);
    loadBeanOperation(SwapSecurityBeanOperation.INSTANCE);
    loadBeanOperation(EquityIndexOptionSecurityBeanOperation.INSTANCE);
    loadBeanOperation(EquityOptionSecurityBeanOperation.INSTANCE);
    loadBeanOperation(EquityBarrierOptionSecurityBeanOperation.INSTANCE);
    loadBeanOperation(FxOptionSecurityBeanOperation.INSTANCE);
    loadBeanOperation(NonDeliverableFxOptionSecurityBeanOperation.INSTANCE);
    loadBeanOperation(SwaptionSecurityBeanOperation.INSTANCE);
    loadBeanOperation(IRFutureOptionSecurityBeanOperation.INSTANCE);
    loadBeanOperation(EquityIndexFutureOptionSecurityBeanOperation.INSTANCE);
    loadBeanOperation(EquityIndexDividendFutureOptionSecurityBeanOperation.INSTANCE);
    loadBeanOperation(CommodityFutureOptionSecurityBeanOperation.INSTANCE);
    loadBeanOperation(FxFutureOptionSecurityBeanOperation.INSTANCE);
    loadBeanOperation(BondFutureOptionSecurityBeanOperation.INSTANCE);
    loadBeanOperation(FxBarrierOptionSecurityBeanOperation.INSTANCE);
    loadBeanOperation(FxDigitalOptionSecurityBeanOperation.INSTANCE);
    loadBeanOperation(NonDeliverableFxDigitalOptionSecurityBeanOperation.INSTANCE);
    loadBeanOperation(FXForwardSecurityBeanOperation.INSTANCE);
    loadBeanOperation(NonDeliverableFXForwardSecurityBeanOperation.INSTANCE);
    loadBeanOperation(CapFloorSecurityBeanOperation.INSTANCE);
    loadBeanOperation(CapFloorCMSSpreadSecurityBeanOperation.INSTANCE);
    loadBeanOperation(EquityVarianceSwapSecurityBeanOperation.INSTANCE);
    loadBeanOperation(CDSSecurityBeanOperation.INSTANCE);
    loadBeanOperation(LegacyFixedRecoveryCDSSecurityBeanOperation.INSTANCE);
    loadBeanOperation(LegacyRecoveryLockCDSSecurityBeanOperation.INSTANCE);
    loadBeanOperation(LegacyVanillaCDSSecurityBeanOperation.INSTANCE);
    loadBeanOperation(StdFixedRecoveryCDSSecurityBeanOperation.INSTANCE);
    loadBeanOperation(StdRecoveryLockCDSSecurityBeanOperation.INSTANCE);
    loadBeanOperation(StdVanillaCDSSecurityBeanOperation.INSTANCE);
    loadBeanOperation(CashFlowSecurityBeanOperation.INSTANCE);
    loadBeanOperation(CreditDefaultSwapIndexDefinitionSecurityBeanOperation.INSTANCE);
    loadBeanOperation(CreditDefaultSwapIndexSecurityBeanOperation.INSTANCE);
    loadBeanOperation(CDSOptionSecurityBeanOperation.INSTANCE);
  }

  //-------------------------------------------------------------------------
  @Override
  public void init(DbSecurityMaster master) {
    _dbConnector = master.getDbConnector();
  }

  //-------------------------------------------------------------------------
  /**
   * Gets the context for additional resources.
   * @return the context
   */
  protected OperationContext getOperationContext() {
    return _operationContext;
  }

  /**
   * Gets the Hibernate Spring template.
   * @return the template
   */
  protected HibernateTemplate getHibernateTemplate() {
    return _dbConnector.getHibernateTemplate();
  }

  /**
   * Gets the database dialect.
   * @return the dialect
   */
  protected DbDialect getDialect() {
    return _dbConnector.getDialect();
  }

  /**
   * Gets the session DAO.
   * @param session  the session
   * @return the DAO
   */
  protected HibernateSecurityMasterDao getHibernateSecurityMasterSession(final Session session) {
    return new HibernateSecurityMasterSession(session);
  }

  //-------------------------------------------------------------------------
  @Override
  public ManageableSecurity loadSecurityDetail(final ManageableSecurity base) {
    s_logger.debug("loading detail for security {}", base.getUniqueId());
    return getHibernateTemplate().execute(new HibernateCallback<ManageableSecurity>() {
      @SuppressWarnings({"unchecked", "rawtypes" })
      @Override
      public ManageableSecurity doInHibernate(Session session) throws HibernateException, SQLException {
        final SecurityBeanOperation beanOperation = getBeanOperation(base.getSecurityType());
        HibernateSecurityMasterDao secMasterSession = getHibernateSecurityMasterSession(session);
        SecurityBean security = secMasterSession.getSecurityBean(base, beanOperation);
        if (security == null) {
          s_logger.warn("no detail found for security {}", base.getUniqueId());
          return base;
        }
        security = beanOperation.resolve(getOperationContext(), secMasterSession, null, security);
        final ManageableSecurity result = (ManageableSecurity) beanOperation.createSecurity(getOperationContext(), security);
        if (result == null) {
          throw new IllegalStateException("Unable to convert security from database: " + base.getUniqueId() + " " + base.getSecurityType());
        }
        if (Objects.equal(base.getSecurityType(), result.getSecurityType()) == false) {
          throw new IllegalStateException("Security type returned by Hibernate load does not match");
        }
        result.setUniqueId(base.getUniqueId());
        result.setName(base.getName());
        result.setExternalIdBundle(base.getExternalIdBundle());
        result.setAttributes(base.getAttributes());
        return result;
      }
    });
  }

  @Override
  public void storeSecurityDetail(final ManageableSecurity security) {
    s_logger.debug("storing detail for security {}", security.getUniqueId());
    if (security.getClass() == ManageableSecurity.class) {
      return// no detail to store
    }
    getHibernateTemplate().execute(new HibernateCallback<Object>() {
      @SuppressWarnings({"unchecked", "rawtypes" })
      @Override
      public Object doInHibernate(final Session session) throws HibernateException, SQLException {
        final HibernateSecurityMasterDao secMasterSession = getHibernateSecurityMasterSession(session);
        final SecurityBeanOperation beanOperation = getBeanOperation(security);
        final Date now = new Date();
        final OperationContext operationContext = getOperationContext();
        operationContext.setSession(session);
        secMasterSession.createSecurityBean(operationContext, beanOperation, now, security);
        return null;
      }
    });
  }

  @Override
  public void extendSearch(SecuritySearchRequest request, DbMapSqlParameterSource args) {
    if (request instanceof BondSecuritySearchRequest) {
      BondSecuritySearchRequest bondRequest = (BondSecuritySearchRequest) request;
      if (bondRequest.getIssuerName() != null || bondRequest.getIssuerType() != null) {
        args.addValue("sql_search_bond_join", Boolean.TRUE);
      }
      if (bondRequest.getIssuerName() != null) {
        args.addValue("bond_issuer_name", getDialect().sqlWildcardAdjustValue(bondRequest.getIssuerName()));
      }
      if (bondRequest.getIssuerType() != null) {
        args.addValue("bond_issuer_type", getDialect().sqlWildcardAdjustValue(bondRequest.getIssuerName()));
      }
    }
  }

}
TOP

Related Classes of com.opengamma.masterdb.security.hibernate.HibernateSecurityMasterDetailProvider

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.