/** * Copyright (C) 2009 - present by OpenGamma Inc. and the OpenGamma group of companies * * Please see distribution for license. */ package com.opengamma.master.security; import java.util.Map; import org.apache.commons.lang.StringUtils; import org.joda.beans.BeanBuilder; import org.joda.beans.BeanDefinition; import org.joda.beans.JodaBeanUtils; import org.joda.beans.MetaProperty; import org.joda.beans.impl.direct.DirectBeanBuilder; import org.joda.beans.impl.direct.DirectMetaPropertyMap; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import com.opengamma.DataNotFoundException; import com.opengamma.core.LinkResolver; import com.opengamma.core.id.ExternalSchemes; import com.opengamma.core.security.Security; import com.opengamma.core.security.SecurityLink; import com.opengamma.core.security.SecuritySource; import com.opengamma.id.ExternalId; import com.opengamma.id.ExternalIdBundle; import com.opengamma.id.ObjectId; import com.opengamma.id.UniqueId; import com.opengamma.id.VersionCorrection; import com.opengamma.master.AbstractLink; import com.opengamma.util.ArgumentChecker; import com.opengamma.util.PublicSPI; /** * A flexible link between an object and a security. * <p> * The security link represents a connection from an entity to a security. * The connection can be held by an {@code ObjectId} or an {@code ExternalIdBundle}. * The link also holds a resolved reference to the security itself. * <p> * This class is mutable and not thread-safe. */ @PublicSPI @BeanDefinition public class ManageableSecurityLink extends AbstractLink<Security> implements SecurityLink { /** Serialization version. */ private static final long serialVersionUID = 1L; /** Logger. */ private static final Logger s_logger = LoggerFactory.getLogger(ManageableSecurityLink.class); /** * Obtains an instance from a security, locking by strong object identifier * if possible and the external identifier bundle if not. * The result will contain the resolved target and one type of reference. * * @param security the security to store, not null * @return the link with target and object identifier set, not null */ public static ManageableSecurityLink of(Security security) { ArgumentChecker.notNull(security, "security"); ManageableSecurityLink link = new ManageableSecurityLink(); link.setAndLockTarget(security); if (link.getObjectId() == null) { link.setExternalId(security.getExternalIdBundle()); } return link; } /** * Obtains an instance from a security, locking by external identifier bundle. * The result will contain the external identifier bundle and the resolved target. * * @param security the security to store, not null * @return the link with target and identifier bundle set, not null */ public static ManageableSecurityLink ofBundleId(Security security) { ArgumentChecker.notNull(security, "security"); ManageableSecurityLink link = new ManageableSecurityLink(security.getExternalIdBundle()); link.setTarget(security); return link; } //------------------------------------------------------------------------- /** * Creates an new instance. */ public ManageableSecurityLink() { super(); } /** * Creates a link from an object identifier. * * @param objectId the object identifier, not null * @deprecated using object ids will limit ability to export links, use ExternalIds or ExternalIdBundles, even if they need to be generated GUIDs */ @Deprecated public ManageableSecurityLink(final ObjectId objectId) { super(objectId); } /** * Creates a link from a unique identifier, only storing the object identifier. * * @param uniqueId the unique identifier, not null * @deprecated using object ids will limit ability to export links, use ExternalIds or ExternalIdBundles, even if they need to be generated GUIDs */ @Deprecated public ManageableSecurityLink(final UniqueId uniqueId) { super(uniqueId); } /** * Creates a link from an external identifier. * * @param identifier the identifier, not null */ public ManageableSecurityLink(final ExternalId identifier) { super(ExternalIdBundle.of(identifier)); } /** * Creates a link from an external identifier bundle. * * @param bundle the identifier bundle, not null */ public ManageableSecurityLink(final ExternalIdBundle bundle) { super(bundle); } /** * Clones the specified link, sharing the target security. * * @param linkToClone the link to clone, not null */ public ManageableSecurityLink(SecurityLink linkToClone) { setObjectId(linkToClone.getObjectId()); setExternalId(linkToClone.getExternalId()); setTarget(linkToClone.getTarget()); } //------------------------------------------------------------------------- /** * Gets the best descriptive name. * * @return the best descriptive name, not null */ public String getBestName() { Security security = getTarget(); ObjectId objectId = getObjectId(); ExternalIdBundle bundle = getExternalId(); if (security != null) { // Try to retrieve the security's assigned name String name = security.getName(); if (StringUtils.isNotBlank(name)) { return name; } bundle = security.getExternalIdBundle(); } if (bundle != null && bundle.size() > 0) { if (bundle.getValue(ExternalSchemes.BLOOMBERG_TICKER) != null) { return bundle.getValue(ExternalSchemes.BLOOMBERG_TICKER); } else if (bundle.getValue(ExternalSchemes.RIC) != null) { return bundle.getValue(ExternalSchemes.RIC); } else if (bundle.getValue(ExternalSchemes.ACTIVFEED_TICKER) != null) { return bundle.getValue(ExternalSchemes.ACTIVFEED_TICKER); } else { return bundle.getExternalIds().iterator().next().getValue(); } } if (objectId != null) { return objectId.toString(); } return ""; } //------------------------------------------------------------------------- /** * Resolves the link to the target security. * * @param resolver the resolver capable of finding the target, not null * @return the resolved target, null if unable to resolve * @throws DataNotFoundException if the target could not be resolved * @throws RuntimeException if an error occurs */ public Security resolve(LinkResolver<Security> resolver) { return resolver.resolve(this); } /** * Resolves the security for the latest version-correction using a security source. * * @param source the source to use to resolve, not null * @return the resolved security, not null * @throws DataNotFoundException if the security could not be resolved * @throws RuntimeException if an error occurs while resolving */ public Security resolve(SecuritySource source) { return resolve(source, VersionCorrection.LATEST); } /** * Resolves the security using a security source. * * @param source the source to use to resolve, not null * @param versionCorrection the version-correction, not null * @return the resolved security, not null * @throws DataNotFoundException if the security could not be resolved * @throws RuntimeException if an error occurs while resolving */ public Security resolve(SecuritySource source, VersionCorrection versionCorrection) { ObjectId objectId = getObjectId(); if (objectId != null) { Security target = source.get(objectId, versionCorrection); setTarget(target); return target; } ExternalIdBundle bundle = getExternalId(); if (bundle.size() > 0) { Security target = source.getSingle(bundle, versionCorrection); if (target != null) { setTarget(target); return target; } } throw new DataNotFoundException("Unable to resolve security: " + getBestName()); } /** * Resolves the security using a security source, * logging any exception and returning null. * * @param source the source to use to resolve, not null * @return the resolved security, null if unable to resolve */ public Security resolveQuiet(SecuritySource source) { try { return resolve(source); } catch (DataNotFoundException ex) { s_logger.warn("Unable to resolve security {}", this); return null; } catch (RuntimeException ex) { s_logger.warn("Unable to resolve security {}: {}", this, ex); return null; } } //------------------------------------------------------------------------- /** * Clones this link, sharing the target security. * * @return the clone, not null */ @Override public ManageableSecurityLink clone() { return (ManageableSecurityLink) super.clone(); } //------------------------- AUTOGENERATED START ------------------------- ///CLOVER:OFF /** * The meta-bean for {@code ManageableSecurityLink}. * @return the meta-bean, not null */ public static ManageableSecurityLink.Meta meta() { return ManageableSecurityLink.Meta.INSTANCE; } static { JodaBeanUtils.registerMetaBean(ManageableSecurityLink.Meta.INSTANCE); } @Override public ManageableSecurityLink.Meta metaBean() { return ManageableSecurityLink.Meta.INSTANCE; } //----------------------------------------------------------------------- @Override public boolean equals(Object obj) { if (obj == this) { return true; } if (obj != null && obj.getClass() == this.getClass()) { return super.equals(obj); } return false; } @Override public int hashCode() { int hash = 7; return hash ^ super.hashCode(); } @Override public String toString() { StringBuilder buf = new StringBuilder(32); buf.append("ManageableSecurityLink{"); int len = buf.length(); toString(buf); if (buf.length() > len) { buf.setLength(buf.length() - 2); } buf.append('}'); return buf.toString(); } @Override protected void toString(StringBuilder buf) { super.toString(buf); } //----------------------------------------------------------------------- /** * The meta-bean for {@code ManageableSecurityLink}. */ public static class Meta extends AbstractLink.Meta<Security> { /** * The singleton instance of the meta-bean. */ static final Meta INSTANCE = new Meta(); /** * The meta-properties. */ private final Map<String, MetaProperty<?>> _metaPropertyMap$ = new DirectMetaPropertyMap( this, (DirectMetaPropertyMap) super.metaPropertyMap()); /** * Restricted constructor. */ protected Meta() { } @Override public BeanBuilder<? extends ManageableSecurityLink> builder() { return new DirectBeanBuilder<ManageableSecurityLink>(new ManageableSecurityLink()); } @Override public Class<? extends ManageableSecurityLink> beanType() { return ManageableSecurityLink.class; } @Override public Map<String, MetaProperty<?>> metaPropertyMap() { return _metaPropertyMap$; } //----------------------------------------------------------------------- } ///CLOVER:ON //-------------------------- AUTOGENERATED END -------------------------- }