/** * Copyright (C) 2009 - present by OpenGamma Inc. and the OpenGamma group of companies * * Please see distribution for license. */ package com.opengamma.engine.function; import java.util.ArrayList; import java.util.Collection; import java.util.Map; import java.util.Set; import java.util.TreeSet; import java.util.concurrent.ConcurrentSkipListMap; import com.opengamma.util.PublicAPI; /** * The context used while evaluating functions. * <p> * Most functions do not live in isolation, instead they rely on contextual data. * This class and its subclasses provide a multi-valued map-like context for functions. * <p> * This class is abstract and mutable with some degree of thread-safety using a concurrent map. * It is not serializable as it is intended for runtime configuration, holding many non-serializable items. */ @PublicAPI /* package */abstract class AbstractFunctionContext { /** * The concurrent backing map. * This ensures that each get/put is safe, but operations relying on two different gets * could see inconsistent state. */ private final Map<String, Object> _backingMap = new ConcurrentSkipListMap<String, Object>(); /** * Constructor. */ protected AbstractFunctionContext() { } /** * Constructor that assigns all items from the specified context to the new context. * The copy is shallow - elements are not cloned. * * @param copyFrom the object to copy from, not null */ protected AbstractFunctionContext(final AbstractFunctionContext copyFrom) { _backingMap.putAll(copyFrom._backingMap); } /** * Returns a value from the context. * <p> * This is not intended to be called directly from function code - * static context wrappers should provide type safe access to elements. * For example: * <pre> * public class MyFunctionContext { * * private static final String FOO_NAME = "Foo"; * * // ... * * public static Foo getFoo(AbstractFunctionContext context) { * return (Foo) context.get(FOO); * } * * public static void setFoo(AbstractFunctionContext context, Foo foo) { * context.set(FOO, foo); * } * * // ... * * } * </pre> * * @param elementName the name of the element to lookup, not null * @return the value, null if none is defined */ public Object get(final String elementName) { return _backingMap.get(elementName); } /** * Stores a value in the context. * <p> * This is not intended to be called directly from function code - * static context wrappers should provide type safe access to elements. * See the example for {@link #get(String)}. * * @param elementName the name of the element to set, not null * @param value the value to set, not null * @return the previous value for the element, null if none was defined */ public Object put(final String elementName, final Object value) { return _backingMap.put(elementName, value); } /** * Removes a value from the context. * This is not intended to be called directly from function code. * * @param elementName the name of the element to remove, not null * @return the previous value for the element, null if none was defined */ public Object remove(final String elementName) { return _backingMap.remove(elementName); } /** * Returns all element names currently defined in the context. * These can be used with {@link #get(String)} to retrieve the values. * * @return the set of element names, not null */ public Set<String> getAllElementNames() { // See UTL-20. No need to reorder into a TreeSet<>. return new TreeSet<String>(_backingMap.keySet()); } protected Collection<Object> getAllElements() { return new ArrayList<Object>(_backingMap.values()); } /** * Clones this context creating a copy that has an independent backing map. * The clone is shallow - elements are not cloned. * The copy will not be affected by changes to the original instance. * * @return a copy of the context */ @Override public abstract AbstractFunctionContext clone(); }