com.opengamma.financial.security.cds.CDSIndexComponentBundle.java Source code

Java tutorial

Introduction

Here is the source code for com.opengamma.financial.security.cds.CDSIndexComponentBundle.java

Source

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

import java.io.Serializable;
import java.util.Arrays;
import java.util.Comparator;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;

import org.apache.commons.lang.builder.EqualsBuilder;
import org.apache.commons.lang.builder.HashCodeBuilder;
import org.apache.commons.lang.builder.ToStringBuilder;

import com.google.common.base.Function;
import com.google.common.collect.ImmutableSortedSet;
import com.google.common.collect.Maps;
import com.google.common.collect.Sets;
import com.opengamma.id.ExternalId;
import com.opengamma.util.ArgumentChecker;

/**
 * Immutable set of {@link CreditDefaultSwapIndexComponent} that
 * represents the CreditDefaultSwapIndexDefinitionSecurity components
 * <p>
 * It uses a comparator based on the ObligorCode of each components
 * as opposed to natural ordering of weight and name.
 * <p>
 * Note that ideally we would use a Map keyed on RED code with values
 * of the components, sorted by the values. However, standard maps
 * are sorted by kets so would not be usable. Instead this class
 * maintains a Map to ensure each RED code only appears once and
 * a sorted set of the components.
 * </p>
 * 
 */
public final class CDSIndexComponentBundle implements Iterable<CreditDefaultSwapIndexComponent>, Serializable {

    /** Serialization version. */
    private static final long serialVersionUID = 1L;

    /**
     * Comparator to use for sorting if one is not specified by client
     */
    private static final Comparator<CreditDefaultSwapIndexComponent> DEFAULT_COMPARATOR = new CDSIndexComponentObligorComparator();

    /**
     * The set of cdsIndex components.
     */
    private final ImmutableSortedSet<CreditDefaultSwapIndexComponent> _components;

    /**
     * The map of the current red codes.
     */
    private final Map<ExternalId, CreditDefaultSwapIndexComponent> _redCodeMapping;

    /**
     * Creates a cdsIndex components bundle from a set of cdsIndex component.
     * 
     * @param components  the set of components assigned, not null
     */
    private CDSIndexComponentBundle(Iterable<CreditDefaultSwapIndexComponent> components) {
        this(components, DEFAULT_COMPARATOR);
    }

    /**
     * Creates a cdsIndex components bundle from a set of cdsIndex
     * component and a comparator.
     *
     * @param components  the set of components assigned, not null
     */
    private CDSIndexComponentBundle(Iterable<CreditDefaultSwapIndexComponent> components,
            Comparator<? super CreditDefaultSwapIndexComponent> comparator) {
        ArgumentChecker.notEmpty(components, "components");
        ArgumentChecker.noNulls(components, "components");
        ArgumentChecker.notNull(comparator, "comparator");

        _components = ImmutableSortedSet.copyOf(comparator, deduplicate(components));
        _redCodeMapping = Maps.uniqueIndex(_components,
                new Function<CreditDefaultSwapIndexComponent, ExternalId>() {
                    @Override
                    public ExternalId apply(CreditDefaultSwapIndexComponent input) {
                        return input.getObligorRedCode();
                    }
                });
    }

    private static Iterable<CreditDefaultSwapIndexComponent> deduplicate(
            Iterable<CreditDefaultSwapIndexComponent> components) {

        Map<ExternalId, CreditDefaultSwapIndexComponent> redCodeMapping = Maps.newHashMap();

        for (CreditDefaultSwapIndexComponent component : components) {
            redCodeMapping.put(component.getObligorRedCode(), component);
        }

        return redCodeMapping.values();
    }

    /**
     * Obtains a {@link CDSIndexComponentBundle} from an array of
     * CreditDefaultSwapIndexComponents.
     *
     * @param components  an array of components, no nulls, not null
     * @return the cdsIndex components bundle, not null
     */
    public static CDSIndexComponentBundle of(CreditDefaultSwapIndexComponent... components) {
        return create(Arrays.asList(components));
    }

    /**
     * Obtains a {@link CDSIndexComponentBundle} from a collection of
     * CreditDefaultSwapIndexComponents.
     *
     * @param components  the collection of components, no nulls, not null
     * @return the cdsIndex components bundle, not null
     */
    public static CDSIndexComponentBundle of(Iterable<CreditDefaultSwapIndexComponent> components) {
        return create(components);
    }

    /**
     * Obtains an {@link CDSIndexComponentBundle} from a collection of
     * {@link CreditDefaultSwapIndexComponent}.
     * 
     * @param components  the collection of components
     * @return the bundle, not null
     */
    private static CDSIndexComponentBundle create(Iterable<CreditDefaultSwapIndexComponent> components) {
        return new CDSIndexComponentBundle(components);
    }

    //-------------------------------------------------------------------------
    /**
     * Gets the set of {@link CreditDefaultSwapIndexComponent} in the cdsIndex
     * components bundle.
     * 
     * @return the components, unmodifiable, not null
     */
    public Iterable<CreditDefaultSwapIndexComponent> getComponents() {
        return _components;
    }

    /**
     * Returns a new {@link CDSIndexComponentBundle} with the specified
     * {@link CreditDefaultSwapIndexComponent}s added. This instance is immutable
     * and unaffected by this method call.
     *
     * @param components the identifiers to add to the returned bundle, not null
     * @return the new bundle, not null
     */
    public CDSIndexComponentBundle withCDSIndexComponents(final CreditDefaultSwapIndexComponent... components) {
        return withCDSIndexComponents(Arrays.asList(components));
    }

    /**
     * Returns a new {@link CDSIndexComponentBundle} with the specified
     * {@link CreditDefaultSwapIndexComponent}s added. This instance is immutable
     * and unaffected by this method call.
     * 
     * @param components the identifiers to add to the returned bundle, not null
     * @return the new bundle, not null
     */
    public CDSIndexComponentBundle withCDSIndexComponents(
            final Iterable<CreditDefaultSwapIndexComponent> components) {

        final Set<CreditDefaultSwapIndexComponent> updatedComponents = Sets.newLinkedHashSet(_components);

        for (CreditDefaultSwapIndexComponent component : components) {

            if (!component.equals(_redCodeMapping.get(component.getObligorRedCode()))) {
                updatedComponents.add(component);
            }
        }

        return new CDSIndexComponentBundle(updatedComponents, _components.comparator());
    }

    //-------------------------------------------------------------------------
    /**
     * Returns a new bundle using a custom comparator for ordering. Primarily
     * useful for display.
     * 
     * @param comparator comparator specifying how to order the ExternalIds
     * @return the new copy of the bundle, ordered by the comparator
     */
    public CDSIndexComponentBundle withCustomIdOrdering(
            final Comparator<CreditDefaultSwapIndexComponent> comparator) {
        return new CDSIndexComponentBundle(_components, comparator);
    }

    //-------------------------------------------------------------------------
    /**
     * Gets the number of components in the bundle.
     * 
     * @return the bundle size, zero or greater
     */
    public int size() {
        return _components.size();
    }

    /**
     * Returns true if this bundle contains no components.
     * 
     * @return true if this bundle contains no components, false otherwise
     */
    public boolean isEmpty() {
        return _components.isEmpty();
    }

    /**
     * Returns an iterator over the components in the bundle.
     * 
     * @return the components in the bundle, not null
     */
    @Override
    public Iterator<CreditDefaultSwapIndexComponent> iterator() {
        return _components.iterator();
    }

    @Override
    public boolean equals(Object obj) {
        return EqualsBuilder.reflectionEquals(this, obj);
    }

    @Override
    public int hashCode() {
        return HashCodeBuilder.reflectionHashCode(this);
    }

    @Override
    public String toString() {
        return ToStringBuilder.reflectionToString(this);
    }

    private static class CDSIndexComponentObligorComparator
            implements Comparator<CreditDefaultSwapIndexComponent>, Serializable {

        @Override
        public int compare(final CreditDefaultSwapIndexComponent left,
                final CreditDefaultSwapIndexComponent right) {
            return left.getObligorRedCode().compareTo(right.getObligorRedCode());
        }
    }
}