/** * Copyright (C) 2012 - present by OpenGamma Inc. and the OpenGamma group of companies * * Please see distribution for license. */ package com.opengamma.web.spring; import java.util.ArrayList; import java.util.Collection; import java.util.List; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentMap; import java.util.concurrent.atomic.AtomicInteger; import com.opengamma.engine.function.FunctionDefinition; import com.opengamma.engine.function.exclusion.AbstractFunctionExclusionGroups; import com.opengamma.engine.function.exclusion.FunctionExclusionGroup; import com.opengamma.engine.function.exclusion.FunctionExclusionGroups; import com.opengamma.financial.analytics.OpenGammaFunctionExclusions; import com.opengamma.util.SingletonFactoryBean; /** * Creates FunctionExclusionGroups appropriate for the {@link DemoStandardFunctionConfiguration} functions. * <p> * The implementation created will look for the {@link OpenGammaFunctionExclusions} marker interface and use the returned string as a key. Keys are ordered with a numbering from large positive * integers downwards. If the key string starts with a number, that number is used, otherwise they are given a unique negative number. */ public class DemoFunctionExclusionGroupsFactoryBean extends SingletonFactoryBean<FunctionExclusionGroups> { @Override protected FunctionExclusionGroups createObject() { return new AbstractFunctionExclusionGroups() { private final AtomicInteger _nextIdentifier = new AtomicInteger(); private final ConcurrentMap<Integer, Object> _used = new ConcurrentHashMap<Integer, Object>(); private boolean notUsed(final Integer intValue, final Object key) { final Object existing = _used.putIfAbsent(intValue, key); if (existing == null) { return true; } return existing.equals(key); } @Override protected String getKey(final FunctionDefinition function) { if (function instanceof OpenGammaFunctionExclusions) { return ((OpenGammaFunctionExclusions) function).getMutualExclusionGroup(); } else { return null; } } @Override protected FunctionExclusionGroup createExclusionGroup(Object key, String displayName) { final String keyString = key.toString(); Integer keyInteger; do { if (keyString.length() > 0) { char c = keyString.charAt(0); if (Character.isDigit(c)) { int i = c - '0'; int j; for (j = 1; j < keyString.length(); j++) { c = keyString.charAt(j); if (!Character.isDigit(c)) { break; } i = (i * 10) + (c - '0'); } keyInteger = i; displayName = displayName.substring(j); assert notUsed(keyInteger, key); break; } } keyInteger = _nextIdentifier.decrementAndGet(); } while (false); return super.createExclusionGroup(keyInteger, displayName); } @Override public boolean isExcluded(final FunctionExclusionGroup group, final Collection<FunctionExclusionGroup> existing) { final int groupKey = (Integer) getKey(group); for (FunctionExclusionGroup toCheck : existing) { final Integer toCheckKey = (Integer) getKey(toCheck); if (groupKey >= toCheckKey.intValue()) { return true; } } return false; } @Override public Collection<FunctionExclusionGroup> withExclusion(final Collection<FunctionExclusionGroup> existing, final FunctionExclusionGroup newGroup) { final List<FunctionExclusionGroup> result = new ArrayList<FunctionExclusionGroup>(existing.size()); result.addAll(existing); result.add(newGroup); return result; } }; } }