com.opengamma.engine.function.exclusion.AbstractFunctionExclusionGroups.java Source code

Java tutorial

Introduction

Here is the source code for com.opengamma.engine.function.exclusion.AbstractFunctionExclusionGroups.java

Source

/**
 * Copyright (C) 2012 - present by OpenGamma Inc. and the OpenGamma group of companies
 * 
 * Please see distribution for license.
 */
package com.opengamma.engine.function.exclusion;

import java.util.Collection;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;

import com.google.common.collect.MapMaker;
import com.google.common.collect.Sets;
import com.opengamma.engine.function.FunctionDefinition;

/**
 * Partial implementation of {@link FunctionExclusionGroups} that caches the lookups.
 */
public abstract class AbstractFunctionExclusionGroups implements FunctionExclusionGroups {

    /**
     * Placeholder for null as the concurrent map implementation doesn't let us use null keys or values.
     */
    private static final FunctionExclusionGroup NULL = new FunctionExclusionGroup();

    private final ConcurrentMap<Object, FunctionExclusionGroup> _groupsByKey = new ConcurrentHashMap<Object, FunctionExclusionGroup>();
    private final ConcurrentMap<FunctionDefinition, FunctionExclusionGroup> _groupsByFunction = new MapMaker()
            .weakKeys().makeMap();

    /**
     * Returns a key that identifies the exclusion group, if any.
     * 
     * @param function the function to test
     * @return the key or null if the function is not part of a group
     */
    protected abstract Object getKey(FunctionDefinition function);

    protected FunctionExclusionGroup createExclusionGroup(final Object key, final String displayName) {
        return new FunctionExclusionGroup(key, displayName);
    }

    protected String createDisplayName(final Object key) {
        return key.toString();
    }

    protected FunctionExclusionGroup createExclusionGroup(final Object key) {
        return createExclusionGroup(key, createDisplayName(key));
    }

    protected Object getKey(final FunctionExclusionGroup group) {
        return group.getKey();
    }

    protected String getDisplayName(final FunctionExclusionGroup group) {
        return group.getDisplayName();
    }

    @Override
    public FunctionExclusionGroup getExclusionGroup(final FunctionDefinition function) {
        FunctionExclusionGroup group = _groupsByFunction.get(function);
        if (group == null) {
            final Object key = getKey(function);
            if (key == null) {
                _groupsByFunction.putIfAbsent(function, NULL);
                return null;
            } else {
                group = _groupsByKey.get(key);
                if (group == null) {
                    group = createExclusionGroup(key);
                    final FunctionExclusionGroup existing = _groupsByKey.putIfAbsent(key, group);
                    if (existing == null) {
                        _groupsByFunction.putIfAbsent(function, group);
                    } else {
                        group = existing;
                    }
                }
                return group;
            }
        } else {
            if (group != NULL) {
                return group;
            } else {
                return null;
            }
        }
    }

    @Override
    public boolean isExcluded(final FunctionExclusionGroup group,
            final Collection<FunctionExclusionGroup> existing) {
        return existing.contains(group);
    }

    @Override
    public Collection<FunctionExclusionGroup> withExclusion(final Collection<FunctionExclusionGroup> existing,
            final FunctionExclusionGroup newGroup) {
        final Set<FunctionExclusionGroup> result = Sets.newHashSetWithExpectedSize(existing.size() + 1);
        result.addAll(existing);
        result.add(newGroup);
        return result;
    }

}