/**
* Copyright (C) 2014 - present by OpenGamma Inc. and the OpenGamma group of companies
*
* Please see distribution for license.
*/
package com.opengamma.web.security;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.SortedSet;
import java.util.TreeMap;
import java.util.TreeSet;
import org.joda.beans.impl.flexi.FlexiBean;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.google.common.base.Joiner;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.Lists;
import com.google.common.collect.Sets;
import com.opengamma.core.id.ExternalSchemes;
import com.opengamma.core.legalentity.LegalEntity;
import com.opengamma.core.security.Security;
import com.opengamma.financial.security.FinancialSecurityVisitorSameValueAdapter;
import com.opengamma.financial.security.capfloor.CapFloorCMSSpreadSecurity;
import com.opengamma.financial.security.capfloor.CapFloorSecurity;
import com.opengamma.financial.security.cds.CreditDefaultSwapIndexComponent;
import com.opengamma.financial.security.cds.CreditDefaultSwapIndexDefinitionSecurity;
import com.opengamma.financial.security.fra.FRASecurity;
import com.opengamma.financial.security.future.AgricultureFutureSecurity;
import com.opengamma.financial.security.future.BondFutureDeliverable;
import com.opengamma.financial.security.future.BondFutureSecurity;
import com.opengamma.financial.security.future.DeliverableSwapFutureSecurity;
import com.opengamma.financial.security.future.EnergyFutureSecurity;
import com.opengamma.financial.security.future.EquityFutureSecurity;
import com.opengamma.financial.security.future.EquityIndexDividendFutureSecurity;
import com.opengamma.financial.security.future.FXFutureSecurity;
import com.opengamma.financial.security.future.FederalFundsFutureSecurity;
import com.opengamma.financial.security.future.IndexFutureSecurity;
import com.opengamma.financial.security.future.InterestRateFutureSecurity;
import com.opengamma.financial.security.future.MetalFutureSecurity;
import com.opengamma.financial.security.future.StockFutureSecurity;
import com.opengamma.financial.security.option.CreditDefaultSwapOptionSecurity;
import com.opengamma.financial.security.option.EquityBarrierOptionSecurity;
import com.opengamma.financial.security.option.EquityIndexOptionSecurity;
import com.opengamma.financial.security.option.EquityOptionSecurity;
import com.opengamma.financial.security.option.IRFutureOptionSecurity;
import com.opengamma.financial.security.option.SwaptionSecurity;
import com.opengamma.financial.security.swap.FixedInflationSwapLeg;
import com.opengamma.financial.security.swap.FixedInterestRateLeg;
import com.opengamma.financial.security.swap.FixedVarianceSwapLeg;
import com.opengamma.financial.security.swap.FloatingGearingIRLeg;
import com.opengamma.financial.security.swap.FloatingInterestRateLeg;
import com.opengamma.financial.security.swap.FloatingSpreadIRLeg;
import com.opengamma.financial.security.swap.FloatingVarianceSwapLeg;
import com.opengamma.financial.security.swap.InflationIndexSwapLeg;
import com.opengamma.financial.security.swap.SwapLegVisitor;
import com.opengamma.financial.security.swap.SwapSecurity;
import com.opengamma.financial.security.swap.YearOnYearInflationSwapSecurity;
import com.opengamma.financial.security.swap.ZeroCouponInflationSwapSecurity;
import com.opengamma.id.ExternalId;
import com.opengamma.master.legalentity.LegalEntityMaster;
import com.opengamma.master.legalentity.LegalEntitySearchRequest;
import com.opengamma.master.legalentity.LegalEntitySearchResult;
import com.opengamma.master.security.ManageableSecurity;
import com.opengamma.master.security.SecurityMaster;
import com.opengamma.util.time.Tenor;
/**
* Builds the model object used in the security freemarker templates
*/
public class SecurityTemplateModelObjectBuilder extends FinancialSecurityVisitorSameValueAdapter<Void> {
private static final Logger s_logger = LoggerFactory.getLogger(SecurityTemplateModelObjectBuilder.class);
private final FlexiBean _out;
private final SecurityMaster _securityMaster;
private final LegalEntityMaster _legalEntityMaster;
SecurityTemplateModelObjectBuilder(final FlexiBean out, final SecurityMaster securityMaster, final LegalEntityMaster legalEntityMaster) {
super(null);
_out = out;
_securityMaster = securityMaster;
_legalEntityMaster = legalEntityMaster;
}
private void addFutureSecurityType(final String futureType) {
_out.put("futureSecurityType", futureType);
}
private void addUnderlyingSecurity(ExternalId underlyingId) {
ManageableSecurity security = getSecurity(underlyingId);
if (security != null) {
_out.put("underlyingSecurity", security);
}
}
private ManageableSecurity getSecurity(ExternalId underlyingIdentifier) {
return AbstractWebSecurityResource.getSecurity(underlyingIdentifier, _securityMaster);
}
@Override
public Void visitSwapSecurity(SwapSecurity security) {
_out.put("payLegType", security.getPayLeg().accept(new SwapLegClassifierVisitor()));
_out.put("receiveLegType", security.getReceiveLeg().accept(new SwapLegClassifierVisitor()));
return null;
}
@Override
public Void visitInterestRateFutureSecurity(InterestRateFutureSecurity security) {
addFutureSecurityType("InterestRate");
addUnderlyingSecurity(security.getUnderlyingId());
return null;
}
@Override
public Void visitBondFutureSecurity(BondFutureSecurity security) {
addFutureSecurityType("BondFuture");
Map<String, String> basket = new TreeMap<String, String>();
for (BondFutureDeliverable bondFutureDeliverable : security.getBasket()) {
SortedSet<String> idSet = Sets.newTreeSet();
for (ExternalId id : bondFutureDeliverable.getIdentifiers()) {
idSet.add(id.getScheme().toString() + "-" + id.getValue());
}
String id = "[" + Joiner.on(",").join(idSet) + "]";
basket.put(id, String.valueOf(bondFutureDeliverable.getConversionFactor()));
}
_out.put("basket", basket);
return null;
}
@Override
public Void visitCapFloorSecurity(CapFloorSecurity security) {
addUnderlyingSecurity(security.getUnderlyingId());
return null;
}
@Override
public Void visitCapFloorCMSSpreadSecurity(CapFloorCMSSpreadSecurity security) {
Security shortUnderlying = getSecurity(security.getShortId());
Security longUnderlying = getSecurity(security.getLongId());
if (shortUnderlying != null) {
_out.put("shortSecurity", shortUnderlying);
}
if (longUnderlying != null) {
_out.put("longSecurity", longUnderlying);
}
return null;
}
@Override
public Void visitEnergyFutureSecurity(EnergyFutureSecurity security) {
addFutureSecurityType("EnergyFuture");
addUnderlyingSecurity(security.getUnderlyingId());
return null;
}
@Override
public Void visitEquityBarrierOptionSecurity(EquityBarrierOptionSecurity security) {
addUnderlyingSecurity(security.getUnderlyingId());
return null;
}
@Override
public Void visitEquityFutureSecurity(EquityFutureSecurity security) {
addFutureSecurityType("EquityFuture");
addUnderlyingSecurity(security.getUnderlyingId());
return null;
}
@Override
public Void visitEquityIndexDividendFutureSecurity(EquityIndexDividendFutureSecurity security) {
addFutureSecurityType("EquityIndexDividendFuture");
addUnderlyingSecurity(security.getUnderlyingId());
return null;
}
@Override
public Void visitEquityIndexOptionSecurity(EquityIndexOptionSecurity security) {
addUnderlyingSecurity(security.getUnderlyingId());
return null;
}
@Override
public Void visitEquityOptionSecurity(EquityOptionSecurity security) {
addUnderlyingSecurity(security.getUnderlyingId());
return null;
}
@Override
public Void visitFRASecurity(FRASecurity security) {
addUnderlyingSecurity(security.getUnderlyingId());
return null;
}
@Override
public Void visitFXFutureSecurity(FXFutureSecurity security) {
addFutureSecurityType("FxFuture");
return null;
}
@Override
public Void visitIndexFutureSecurity(IndexFutureSecurity security) {
addFutureSecurityType("IndexFuture");
addUnderlyingSecurity(security.getUnderlyingId());
return null;
}
@Override
public Void visitIRFutureOptionSecurity(IRFutureOptionSecurity security) {
addUnderlyingSecurity(security.getUnderlyingId());
return null;
}
@Override
public Void visitMetalFutureSecurity(MetalFutureSecurity security) {
addFutureSecurityType("MetalFuture");
addUnderlyingSecurity(security.getUnderlyingId());
return null;
}
@Override
public Void visitStockFutureSecurity(StockFutureSecurity security) {
addFutureSecurityType("StockFuture");
addUnderlyingSecurity(security.getUnderlyingId());
return null;
}
@Override
public Void visitSwaptionSecurity(SwaptionSecurity security) {
addUnderlyingSecurity(security.getUnderlyingId());
return null;
}
@Override
public Void visitAgricultureFutureSecurity(AgricultureFutureSecurity security) {
addFutureSecurityType("AgricultureFuture");
return null;
}
@Override
public Void visitDeliverableSwapFutureSecurity(DeliverableSwapFutureSecurity security) {
addFutureSecurityType("DeliverableSwapFuture");
return null;
}
@Override
public Void visitCreditDefaultSwapIndexDefinitionSecurity(CreditDefaultSwapIndexDefinitionSecurity security) {
List<String> tenors = Lists.newArrayList();
for (Tenor tenor : security.getTerms()) {
tenors.add(tenor.getPeriod().toString());
}
_out.put("terms", ImmutableList.copyOf(tenors));
Set<CreditDefaultSwapIndexComponent> components = new TreeSet<>(Collections.reverseOrder());
for (CreditDefaultSwapIndexComponent component : security.getComponents()) {
components.add(component);
}
_out.put("components", ImmutableList.copyOf(components));
return null;
}
@Override
public Void visitCreditDefaultSwapOptionSecurity(CreditDefaultSwapOptionSecurity security) {
ExternalId underlyingId = security.getUnderlyingId();
if (underlyingId != null) {
LegalEntitySearchRequest request = new LegalEntitySearchRequest();
if (underlyingId.getScheme().equals(ExternalSchemes.MARKIT_RED_CODE)) {
request.addExternalId(underlyingId);
LegalEntitySearchResult searchResult = _legalEntityMaster.search(request);
LegalEntity organization = searchResult.getSingleLegalEntity();
if (organization != null) {
_out.put("underlyingOrganization", organization);
}
} else {
s_logger.warn("{} does not currently support CDSOption underlying lookup based on {}", WebSecuritiesResource.class, underlyingId.getScheme().getName());
}
}
return null;
}
@Override
public Void visitFederalFundsFutureSecurity(FederalFundsFutureSecurity security) {
addFutureSecurityType("FederalFundsFutureSecurity");
addUnderlyingSecurity(security.getUnderlyingId());
return null;
}
@Override
public Void visitZeroCouponInflationSwapSecurity(ZeroCouponInflationSwapSecurity security) {
_out.put("payLegType", security.getPayLeg().accept(new SwapLegClassifierVisitor()));
_out.put("receiveLegType", security.getReceiveLeg().accept(new SwapLegClassifierVisitor()));
return null;
}
@Override
public Void visitYearOnYearInflationSwapSecurity(YearOnYearInflationSwapSecurity security) {
_out.put("payLegType", security.getPayLeg().accept(new SwapLegClassifierVisitor()));
_out.put("receiveLegType", security.getReceiveLeg().accept(new SwapLegClassifierVisitor()));
return null;
}
/**
* SwapLegClassifierVisitor
*/
private static class SwapLegClassifierVisitor implements SwapLegVisitor<String> {
@Override
public String visitFixedInterestRateLeg(FixedInterestRateLeg swapLeg) {
return "FixedInterestRateLeg";
}
@Override
public String visitFloatingInterestRateLeg(FloatingInterestRateLeg swapLeg) {
return "FloatingInterestRateLeg";
}
@Override
public String visitFloatingSpreadIRLeg(FloatingSpreadIRLeg swapLeg) {
return "FloatingSpreadInterestRateLeg";
}
@Override
public String visitFloatingGearingIRLeg(FloatingGearingIRLeg swapLeg) {
return "FloatingGearingInterestRateLeg";
}
@Override
public String visitFixedVarianceSwapLeg(FixedVarianceSwapLeg swapLeg) {
return "FixedVarianceLeg";
}
@Override
public String visitFloatingVarianceSwapLeg(FloatingVarianceSwapLeg swapLeg) {
return "FloatingVarianceLeg";
}
@Override
public String visitFixedInflationSwapLeg(FixedInflationSwapLeg swapLeg) {
return "FixedInflationLeg";
}
@Override
public String visitInflationIndexSwapLeg(InflationIndexSwapLeg swapLeg) {
return "InflationIndexLeg";
}
}
}