Package ariba.util.expr

Source Code of ariba.util.expr.ExprContext$ExtensibleContext

//--------------------------------------------------------------------------
//  Copyright (c) 1998-2004, Drew Davidson and Luke Blanshard
//  All rights reserved.
//
//  Redistribution and use in source and binary forms, with or without
//  modification, are permitted provided that the following conditions are
//  met:
//
//  Redistributions of source code must retain the above copyright notice,
//  this list of conditions and the following disclaimer.
//  Redistributions in binary form must reproduce the above copyright
//  notice, this list of conditions and the following disclaimer in the
//  documentation and/or other materials provided with the distribution.
//  Neither the name of the Drew Davidson nor the names of its contributors
//  may be used to endorse or promote products derived from this software
//  without specific prior written permission.
//
//  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
//  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
//  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
//  FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
//  COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
//  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
//  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
//  OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
//  AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
//  OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
//  THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
//  DAMAGE.
//--------------------------------------------------------------------------
package ariba.util.expr;

import java.util.*;
import ariba.util.fieldtype.TypeInfo;

/**
* This class defines the execution context for an AribaExpr expression
* @author Luke Blanshard (blanshlu@netscape.net)
* @author Drew Davidson (drew@ognl.org)
*/
public class ExprContext extends Object implements Map
{
    //--------------------------------------------------------------------------
    // constants

    public static final String          CONTEXT_CONTEXT_KEY = "context";
    public static final String          ROOT_CONTEXT_KEY = "this";
    public static final String          THIS_CONTEXT_KEY = "it";
    public static final String          LOGIN_USER_CONTEXT_KEY = "loginUser";
    public static final String          TRACE_EVALUATIONS_CONTEXT_KEY = "_traceEvaluations";
    public static final String          LAST_EVALUATION_CONTEXT_KEY = "_lastEvaluation";
    public static final String          KEEP_LAST_EVALUATION_CONTEXT_KEY = "_keepLastEvaluation";
    public static final String          CLASS_RESOLVER_CONTEXT_KEY = "_classResolver";
    public static final String          TYPE_CONVERTER_CONTEXT_KEY = "_typeConverter";
    public static final String          MEMBER_ACCESS_CONTEXT_KEY = "_memberAccess";

    private static final String         PROPERTY_KEY_PREFIX = "aribaExpr";
    private static boolean              DEFAULT_TRACE_EVALUATIONS = false;
    private static boolean              DEFAULT_KEEP_LAST_EVALUATION = false;

    public static final ClassResolver   DEFAULT_CLASS_RESOLVER = new DefaultClassResolver();
    public static final TypeConverter   DEFAULT_TYPE_CONVERTER = new DefaultTypeConverter();
    public static final MemberAccess    DEFAULT_MEMBER_ACCESS = new DefaultMemberAccess(false);

    //--------------------------------------------------------------------------
    // nested class

    /**
        @aribaapi ariba
    */
    public static interface ExtensibleContext
    {
        /**
            @aribaapi ariba
        */
        public String getLoginUserTypeName ();

        /**
            @aribaapi ariba
        */
        public Object getLoginUser ();
    }

    //--------------------------------------------------------------------------
    // public static methods

    /**
        @aribaapi ariba
    */
    public static ExtensibleContext getExtensibleContext ()
    {
        return EXTENSIBLE_CONTEXT;
    }

    /**
        @aribaapi ariba
    */
    public static void setExtensibleContext (ExtensibleContext context)
    {
        EXTENSIBLE_CONTEXT = context;
    }

    //--------------------------------------------------------------------------
    // data members

    private static Map                  RESERVED_KEYS = new HashMap(11);
    private static ExtensibleContext    EXTENSIBLE_CONTEXT = null;

    private Object                      root;
    private Object                      currentObject;
    private Node                        currentNode;
    private boolean                     traceEvaluations = DEFAULT_TRACE_EVALUATIONS;
    private Evaluation                  rootEvaluation;
    private Evaluation                  currentEvaluation;
    private Evaluation                  lastEvaluation;
    private boolean                     keepLastEvaluation = DEFAULT_KEEP_LAST_EVALUATION;
    private Map                         values = new HashMap(23);
    private ClassResolver               classResolver = DEFAULT_CLASS_RESOLVER;
    private TypeConverter               typeConverter = DEFAULT_TYPE_CONVERTER;
    private MemberAccess                memberAccess = DEFAULT_MEMBER_ACCESS;

    private SymbolTable                 symbolTable;

    static
    {
        String          s;

        RESERVED_KEYS.put(CONTEXT_CONTEXT_KEY, null);
        RESERVED_KEYS.put(ROOT_CONTEXT_KEY, null);
        RESERVED_KEYS.put(THIS_CONTEXT_KEY, null);
        RESERVED_KEYS.put(TRACE_EVALUATIONS_CONTEXT_KEY, null);
        RESERVED_KEYS.put(LAST_EVALUATION_CONTEXT_KEY, null);
        RESERVED_KEYS.put(KEEP_LAST_EVALUATION_CONTEXT_KEY, null);
        RESERVED_KEYS.put(CLASS_RESOLVER_CONTEXT_KEY, null);
        RESERVED_KEYS.put(TYPE_CONVERTER_CONTEXT_KEY, null);
        RESERVED_KEYS.put(MEMBER_ACCESS_CONTEXT_KEY, null);

        try {
            if ((s = System.getProperty(PROPERTY_KEY_PREFIX + ".traceEvaluations")) != null) {
                DEFAULT_TRACE_EVALUATIONS = Boolean.valueOf(s.trim()).booleanValue();
            }
            if ((s = System.getProperty(PROPERTY_KEY_PREFIX + ".keepLastEvaluation")) != null) {
                DEFAULT_KEEP_LAST_EVALUATION = Boolean.valueOf(s.trim()).booleanValue();
            }
        } catch (SecurityException ex) {
            // restricted access environment, just keep defaults
        }
    }

    /**
        Constructs a new ExprContext with the default class resolver, type converter and
        member access.
     */
    public ExprContext()
    {
        super();
    }

    /**
        Constructs a new ExprContext with the given class resolver, type converter and
        member access.  If any of these parameters is null the default will be used.
     */
    public ExprContext(ClassResolver classResolver, TypeConverter typeConverter, MemberAccess memberAccess)
    {
        this();
        if (classResolver != null) {
            this.classResolver = classResolver;
        }
        if (typeConverter != null) {
            this.typeConverter = typeConverter;
        }
        if (memberAccess != null) {
            this.memberAccess = memberAccess;
        }
    }

    public ExprContext(Map values)
    {
        super();
        this.values = values;
    }

    public ExprContext (
            ClassResolver classResolver,
            TypeConverter typeConverter,
            MemberAccess memberAccess,
            Map values
    )
    {
        this(classResolver, typeConverter, memberAccess);
        this.values = values;
    }

    public ExprContext (SymbolTable symbolTable)
    {
        this();
        this.symbolTable = symbolTable;
    }

    public void setValues (Map value)
    {
        for (Iterator it = value.keySet().iterator(); it.hasNext();) {
            Object      k = it.next();

            values.put(k, value.get(k));
        }
    }

    public Map getValues ()
    {
        return values;
    }

    public void setClassResolver (ClassResolver value)
    {
        if (value == null) {
            throw new IllegalArgumentException("cannot set ClassResolver to null");
        }
        classResolver = value;
    }

    public ClassResolver getClassResolver ()
    {
        return classResolver;
    }

    public void setTypeConverter (TypeConverter value)
    {
        if (value == null) {
            throw new IllegalArgumentException("cannot set TypeConverter to null");
        }
        typeConverter = value;
    }

    public TypeConverter getTypeConverter ()
    {
        return typeConverter;
    }

    public void setMemberAccess (MemberAccess value)
    {
        if (value == null) {
            throw new IllegalArgumentException("cannot set MemberAccess to null");
        }
        memberAccess = value;
    }

    public MemberAccess getMemberAccess ()
    {
        return memberAccess;
    }

    public SymbolTable getSymbolTable ()
    {
        return symbolTable;
    }

    public void setRoot (Object value)
    {
        root = value;
    }

    public Object getRoot ()
    {
        return root;
    }

    public boolean getTraceEvaluations ()
    {
        return traceEvaluations;
    }

    public void setTraceEvaluations (boolean value)
    {
        traceEvaluations = value;
    }

    public Evaluation getLastEvaluation ()
    {
        return lastEvaluation;
    }

    public void setLastEvaluation (Evaluation value)
    {
        lastEvaluation = value;
    }

    /**
        This method can be called when the last evaluation has been used
        and can be returned for reuse in the free pool maintained by the
        runtime.  This is not a necessary step, but is useful for keeping
        memory usage down.  This will recycle the last evaluation and then
        set the last evaluation to null.
     */
    public void recycleLastEvaluation ()
    {
        ExprRuntime.getEvaluationPool().recycleAll(lastEvaluation);
        lastEvaluation = null;
    }

    /**
        Returns true if the last evaluation that was done on this
        context is retained and available through <code>getLastEvaluation()</code>.
        The default is true.
     */
    public boolean getKeepLastEvaluation ()
    {
        return keepLastEvaluation;
    }

    /**
        Sets whether the last evaluation that was done on this
        context is retained and available through <code>getLastEvaluation()</code>.
        The default is true.
     */
    public void setKeepLastEvaluation (boolean value)
    {
        keepLastEvaluation = value;
    }

    public void setCurrentObject (Object value)
    {
        currentObject = value;
    }

    public Object getCurrentObject ()
    {
        return currentObject;
    }

    public void setCurrentNode (Node value)
    {
        currentNode = value;
    }

    public Node getCurrentNode ()
    {
        return currentNode;
    }

    /**
        Gets the current Evaluation from the top of the stack.
        This is the Evaluation that is in process of evaluating.
     */
    public Evaluation getCurrentEvaluation ()
    {
        return currentEvaluation;
    }

    public void setCurrentEvaluation (Evaluation value)
    {
        currentEvaluation = value;
    }

    /**
        Gets the root of the evaluation stack.
        This Evaluation contains the node representing
        the root expression and the source is the root
        source object.
     */
    public Evaluation getRootEvaluation ()
    {
        return rootEvaluation;
    }

    public void setRootEvaluation (Evaluation value)
    {
        rootEvaluation = value;
    }

    /**
        Returns the Evaluation at the relative index given.  This should be
        zero or a negative number as a relative reference back up the evaluation
        stack.  Therefore getEvaluation(0) returns the current Evaluation.
     */
    public Evaluation getEvaluation (int relativeIndex)
    {
        Evaluation      result = null;

        if (relativeIndex <= 0) {
            result = currentEvaluation;
            while ((++relativeIndex < 0) && (result != null)) {
                result = result.getParent();
            }
        }
        return result;
    }

    /**
        Pushes a new Evaluation onto the stack.  This is done
        before a node evaluates.  When evaluation is complete
        it should be popped from the stack via <code>popEvaluation()</code>.
     */
    public void pushEvaluation (Evaluation value)
    {
        if (currentEvaluation != null) {
            currentEvaluation.addChild(value);
        } else {
            setRootEvaluation(value);
        }
        setCurrentEvaluation(value);
    }

    /**
        Pops the current Evaluation off of the top of the stack.
        This is done after a node has completed its evaluation.
     */
    public Evaluation popEvaluation ()
    {
        Evaluation      result;

        result = currentEvaluation;
        setCurrentEvaluation(result.getParent());
        if (currentEvaluation == null) {
            setLastEvaluation(getKeepLastEvaluation() ? result : null);
            setRootEvaluation(null);
            setCurrentNode(null);
        }
        return result;
    }

    /*================= Map interface =================*/
    public int size ()
    {
        return values.size();
    }

    public boolean isEmpty ()
    {
        return values.isEmpty();
    }

    public boolean containsKey (Object key)
    {
        return values.containsKey(key);
    }

    public boolean containsValue (Object value)
    {
        return values.containsValue(value);
    }

    public Object get (Object key)
    {
        if (RESERVED_KEYS.containsKey(key)) {
            if (key.equals(ExprContext.THIS_CONTEXT_KEY)) {
                return getCurrentObject();
            }
            if (key.equals(ExprContext.ROOT_CONTEXT_KEY)) {
                return getRoot();
            }
            if (key.equals(ExprContext.CONTEXT_CONTEXT_KEY)) {
                return this;
            }
            if (key.equals(ExprContext.TRACE_EVALUATIONS_CONTEXT_KEY)) {
                return getTraceEvaluations() ? Boolean.TRUE : Boolean.FALSE;
            }
            if (key.equals(ExprContext.LAST_EVALUATION_CONTEXT_KEY)) {
                return getLastEvaluation();
            }
            if (key.equals(ExprContext.KEEP_LAST_EVALUATION_CONTEXT_KEY)) {
                return getKeepLastEvaluation() ? Boolean.TRUE : Boolean.FALSE;
            }
            if (key.equals(ExprContext.CLASS_RESOLVER_CONTEXT_KEY)) {
                return getClassResolver();
            }
            if (key.equals(ExprContext.TYPE_CONVERTER_CONTEXT_KEY)) {
                return getTypeConverter();
            }
            if (key.equals(ExprContext.MEMBER_ACCESS_CONTEXT_KEY)) {
                return getMemberAccess();
            }
            if (key.equals(ExprContext.LOGIN_USER_CONTEXT_KEY)) {
                return getMemberAccess();
            }
            throw new IllegalArgumentException("unknown reserved key '" + key + "'");
        }
        return values.get(key);
    }

    public Object put (Object key, Object value)
    {
        Object result;

        if (RESERVED_KEYS.containsKey(key)) {
            if (key.equals(ExprContext.THIS_CONTEXT_KEY)) {
                result = getCurrentObject();
                setCurrentObject(value);
            }
            else if (key.equals(ExprContext.ROOT_CONTEXT_KEY)) {
                result = getRoot();
                setRoot(value);
            }
            else if (key.equals(ExprContext.CONTEXT_CONTEXT_KEY)) {
                throw new IllegalArgumentException("can't change " +
                                                   ExprContext.CONTEXT_CONTEXT_KEY +
                                                   " in context");
            }
            else if (key.equals(ExprContext.TRACE_EVALUATIONS_CONTEXT_KEY)) {
                result = getTraceEvaluations() ? Boolean.TRUE : Boolean.FALSE;
                setTraceEvaluations(ExprOps.booleanValue(value));
            }
            else if (key.equals(ExprContext.LAST_EVALUATION_CONTEXT_KEY)) {
                result = getLastEvaluation();
                lastEvaluation = (Evaluation)value;
            }
            else if (key.equals(ExprContext.KEEP_LAST_EVALUATION_CONTEXT_KEY)) {
                result = getKeepLastEvaluation() ? Boolean.TRUE : Boolean.FALSE;
                setKeepLastEvaluation(ExprOps.booleanValue(value));
            }
            else if (key.equals(ExprContext.CLASS_RESOLVER_CONTEXT_KEY)) {
                result = getClassResolver();
                setClassResolver((ClassResolver)value);
            }
            else if (key.equals(ExprContext.TYPE_CONVERTER_CONTEXT_KEY)) {
                result = getTypeConverter();
                setTypeConverter((TypeConverter)value);
            }
            else if (key.equals(ExprContext.MEMBER_ACCESS_CONTEXT_KEY)) {
                result = getMemberAccess();
                setMemberAccess((MemberAccess)value);
            }
            else if (key.equals(ExprContext.LOGIN_USER_CONTEXT_KEY)) {
                throw new IllegalArgumentException("can't change " +
                                                   ExprContext.LOGIN_USER_CONTEXT_KEY +
                                                   " in context");
            }
            else {
                throw new IllegalArgumentException("unknown reserved key '" + key + "'");
            }
        } else {
            result = values.put(key, value);
        }
        return result;
    }

    public Object remove (Object key)
    {
        Object      result;

        if (RESERVED_KEYS.containsKey(key)) {
            if (key.equals(ExprContext.THIS_CONTEXT_KEY)) {
                result = getCurrentObject();
                setCurrentObject(null);
            }
            else if (key.equals(ExprContext.ROOT_CONTEXT_KEY)) {
                result = getRoot();
                setRoot(null);
            }
            else if (key.equals(ExprContext.CONTEXT_CONTEXT_KEY)) {
                throw new IllegalArgumentException("can't remove " +
                                                   ExprContext.CONTEXT_CONTEXT_KEY +
                                                   " from context");
            }
            else if (key.equals(ExprContext.TRACE_EVALUATIONS_CONTEXT_KEY)) {
                throw new IllegalArgumentException("can't remove " +
                                                   ExprContext.TRACE_EVALUATIONS_CONTEXT_KEY +
                                                   " from context");
            }
            else if (key.equals(ExprContext.LAST_EVALUATION_CONTEXT_KEY)) {
                result = lastEvaluation;
                setLastEvaluation(null);
            }
            else if (key.equals(ExprContext.KEEP_LAST_EVALUATION_CONTEXT_KEY)) {
                throw new IllegalArgumentException("can't remove " +
                                                   ExprContext.KEEP_LAST_EVALUATION_CONTEXT_KEY +
                                                   " from context");
            }
            else if (key.equals(ExprContext.CLASS_RESOLVER_CONTEXT_KEY)) {
                result = getClassResolver();
                setClassResolver(null);
            }
            else if (key.equals(ExprContext.TYPE_CONVERTER_CONTEXT_KEY)) {
                result = getTypeConverter();
                setTypeConverter(null);
            }
            else if (key.equals(ExprContext.MEMBER_ACCESS_CONTEXT_KEY)) {
                result = getMemberAccess();
                setMemberAccess(null);
            }
            else if (key.equals(ExprContext.LOGIN_USER_CONTEXT_KEY)) {
                throw new IllegalArgumentException("can't remove " +
                                                   ExprContext.LOGIN_USER_CONTEXT_KEY +
                                                   " from context");
            }
            else {
                throw new IllegalArgumentException("unknown reserved key '" + key + "'");
            }
        } else {
            result = values.remove(key);
        }
        return result;
    }

    public void putAll (Map t)
    {
        for (Iterator it = t.keySet().iterator(); it.hasNext();) {
            Object      k = it.next();

            put(k, t.get(k));
        }
    }

    public void clear ()
    {
        values.clear();
        setRoot(null);
        setCurrentObject(null);
        setRootEvaluation(null);
        setCurrentEvaluation(null);
        setLastEvaluation(null);
        setCurrentNode(null);
        setClassResolver(DEFAULT_CLASS_RESOLVER);
        setTypeConverter(DEFAULT_TYPE_CONVERTER);
        setMemberAccess(DEFAULT_MEMBER_ACCESS);
    }

    public Set keySet ()
    {
        /* Should root, currentObject, classResolver, typeConverter & memberAccess be included here? */
        return values.keySet();
    }

    public Collection values ()
    {
        /* Should root, currentObject, classResolver, typeConverter & memberAccess be included here? */
        return values.values();
    }

    public Set entrySet ()
    {
        /* Should root, currentObject, classResolver, typeConverter & memberAccess be included here? */
        return values.entrySet();
    }

    public boolean equals (Object o)
    {
        return values.equals(o);
    }

    public int hashCode ()
    {
        return values.hashCode();
    }

    public Integer getSymbolKind (Symbol symbol)
    {
        Integer symbolKind = null;
        SymbolTable symbolTable = getSymbolTable();
        if (symbolTable != null) {
            SemanticRecord record = symbolTable.getSymbolRecord(symbol);
            if (record != null) {
                symbolKind = record.getSymbolKind();
            }
        }
        return symbolKind;
    }

    public TypeInfo getSymbolType (Symbol symbol)
    {
        TypeInfo type = null;
        SymbolTable symbolTable = getSymbolTable();
        if (symbolTable != null) {
            SemanticRecord record = symbolTable.getSymbolRecord(symbol);
            if (record != null) {
                type = record.getTypeInfo();
            }
        }
        return type;
    }

    /**
        @aribaapi ariba
    */
    public static String getLoginUserTypeName ()
    {
        return EXTENSIBLE_CONTEXT != null
                ? EXTENSIBLE_CONTEXT.getLoginUserTypeName() : null;
    }

    /**
        @aribaapi ariba
    */
    public static Object getLoginUser ()
    {
        return EXTENSIBLE_CONTEXT != null ? EXTENSIBLE_CONTEXT.getLoginUser() : null;
    }
}
TOP

Related Classes of ariba.util.expr.ExprContext$ExtensibleContext

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.