/** * Copyright (C) 2011 - present by OpenGamma Inc. and the OpenGamma group of companies * * Please see distribution for license. */ package com.opengamma.financial.expression; import java.util.HashMap; import java.util.Map; /** * Representation of a user expression. */ public abstract class UserExpression { /** * Special result produced by expressions which fail to evaluate. */ public static final Object NA = new Object() { @Override public String toString() { return "N/A"; } }; /** * Callback interface for registering a source of dynamic variables to an evaluation context. */ public interface DynamicVariables { /** * Returns the value of the variable, or NA if not defined. * * @param name name of the variable * @return the value, or NA if not defined */ Object getValue(String name); } /** * Callback interface for registering a source of dynamic attributes to an evaluation context. */ public interface DynamicAttributes { /** * Returns the value of an attribute, or NA if not defined. * * @param object object the attribute is declared on * @param name name of the attribute * @return the value, or NA if not defined */ Object getValue(Object object, String name); } /** * Evaluation context for an expression. */ public final class Evaluator { private Map<String, Object> _variables; private Map<Class<?>, Object> _contexts; private DynamicVariables _dynamicVariables; private DynamicAttributes _dynamicAttributes; private Evaluator() { } public void setVariable(final String var, final Object value) { assert var != null; assert value != NA; if (_variables == null) { _variables = new HashMap<String, Object>(); } _variables.put(var, value); } public void removeVariable(final String var) { assert var != null; if (_variables != null) { _variables.remove(var); } } public Object getVariable(final String var) { assert var != null; if (_variables == null) { return NA; } final Object result = _variables.get(var); if ((result == null) && !_variables.containsKey(var)) { return NA; } return result; } public void setDynamicVariables(final DynamicVariables dynamicVariables) { _dynamicVariables = dynamicVariables; } public DynamicVariables getDynamicVariables() { return _dynamicVariables; } /** * Evaluates a variable's value. If the variable has been explicitly set, the set value is * used. If it is unset and a dynamic variable provider is registered, that is queried. Otherwise * NA is returned. * * @param var name of the variable * @return the value or NA if undefined */ public Object evaluateVariable(final String var) { assert var != null; final Object value = getVariable(var); if (value != NA) { return value; } if (_dynamicVariables != null) { return _dynamicVariables.getValue(var); } return NA; } public void setDynamicAttributes(final DynamicAttributes dynamicAttributes) { _dynamicAttributes = dynamicAttributes; } public DynamicAttributes getDynamicAttributes() { return _dynamicAttributes; } public Object evaluateAttribute(final Object object, final String attribute) { assert object != null; assert attribute != null; if (_dynamicAttributes != null) { return _dynamicAttributes.getValue(object, attribute); } return NA; } public Object evaluate() { return UserExpression.this.evaluate(this); } private Object getContext(final Class<?> clazz) { assert clazz != null; if (_contexts == null) { return null; } return _contexts.get(clazz); } private void setContext(final Class<?> clazz, final Object context) { assert clazz != null; assert context != null; if (_contexts == null) { _contexts = new HashMap<Class<?>, Object>(); } _contexts.put(clazz, context); } } protected UserExpression() { } public Evaluator evaluator() { return new Evaluator(); } protected Object createContext(final Evaluator evaluator) { return null; } protected Object getContext(final Evaluator evaluator) { Object context = evaluator.getContext(getClass()); if (context == null) { context = createContext(evaluator); evaluator.setContext(getClass(), context); } return context; } protected abstract Object evaluate(Evaluator evaluator); }