All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.apache.velocity.context.EvaluateContext Maven / Gradle / Ivy

package org.apache.velocity.context;

/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.    
 */

import java.util.HashSet;
import java.util.Set;
import java.util.List;

import org.apache.velocity.VelocityContext;
import org.apache.velocity.app.event.EventCartridge;
import org.apache.velocity.runtime.RuntimeConstants;
import org.apache.velocity.runtime.RuntimeServices;
import org.apache.velocity.runtime.resource.Resource;
import org.apache.velocity.util.ClassUtils;
import org.apache.velocity.util.introspection.IntrospectionCacheData;

/**
 *  This is a special, internal-use-only context implementation to be
 *  used for the #evaluate directive.
 *
 *  We use this context to chain the existing context, preventing any changes
 *  from impacting the parent context.  By separating this context into a 
 *  separate class it also allows for the future possibility of changing
 *  the context behavior for the #evaluate directive.
 *  
 *  Note that the context used to store values local to #evaluate()
 *  is user defined but defaults to {@link VelocityContext}.
 *
 *  @author Will Glass-Husain
 *  @version $Id: EvaluateContext.java 691519 2008-09-03 05:36:11Z nbubna $
 *  @since 1.6
 */
public class EvaluateContext extends ChainedInternalContextAdapter
{
    /** container for any local items */
    Context localContext;
    boolean allowRendering = true;
    
     /**
     *  CTOR, wraps an ICA
     * @param inner context for parent template
     * @param rsvc 
     */
    public EvaluateContext( InternalContextAdapter  inner, RuntimeServices rsvc )
    {
        super(inner);
        initContext(rsvc);
    }

    /**
     * Initialize the context based on user-configured class 
     * @param rsvc
     */
    private void initContext( RuntimeServices rsvc )
    {
        String contextClass = rsvc.getString(RuntimeConstants.EVALUATE_CONTEXT_CLASS);

        if (contextClass != null && contextClass.length() > 0)
        {
            Object o = null;

            try
            {
                o = ClassUtils.getNewInstance( contextClass );
            }
            catch (ClassNotFoundException cnfe)
            {
                String err = "The specified class for #evaluate() context (" + contextClass
                + ") does not exist or is not accessible to the current classloader.";
                rsvc.getLog().error(err);
                throw new RuntimeException(err,cnfe);
            }
            catch (Exception e)
            {
                String err = "The specified class for #evaluate() context (" + contextClass
                + ") can not be loaded.";
                rsvc.getLog().error(err,e);
                throw new RuntimeException(err);
            }

            if (!(o instanceof Context))
            {                
                String err = "The specified class for #evaluate() context (" + contextClass
                + ") does not implement " + Context.class.getName() + ".";
                rsvc.getLog().error(err);
                throw new RuntimeException(err);
            }
            
            localContext = (Context) o; 

        }
        else
        {
            String err = "No class specified for #evaluate() context.";
            rsvc.getLog().error(err);
            throw new RuntimeException(err);
        }
        
    }

    /**
     *  Put method also stores values in local scope 
     *
     *  @param key name of item to set
     *  @param value object to set to key
     *  @return old stored object
     */
    public Object put(String key, Object value)
    {
        /*
         *  just put in the local context
         */
        return localContext.put(key, value);

    }

    /**
     *  Retrieves from local or global context.
     *
     *  @param key name of item to get
     *  @return  stored object or null
     */
    public Object get( String key )
    {
        /*
         *  always try the local context then innerContext
         */

        Object o = localContext.get( key );

        if ( o == null)
        {
            o = super.get( key );
        }

        return o;
    }

    /**
     * @see org.apache.velocity.context.Context#containsKey(java.lang.Object)
     */
    public boolean containsKey(Object key)
    {
        return localContext.containsKey(key) || super.containsKey(key);
    }

    /**
     * @see org.apache.velocity.context.Context#getKeys()
     */
    public Object[] getKeys()
    {
        Set keys = new HashSet();
        Object[] localKeys = localContext.getKeys();
        for (int i=0; i < localKeys.length; i++)
        {
            keys.add(localKeys[i]);
        }
        
        Object[] innerKeys = super.getKeys();
        for (int i=0; i < innerKeys.length; i++)
        {
            keys.add(innerKeys[i]);
        }
        return keys.toArray();
    }

    /**
     * @see org.apache.velocity.context.Context#remove(java.lang.Object)
     */
    public Object remove(Object key)
    {
        return localContext.remove( key );
    }

    /**
     * Allows callers to explicitly put objects in the local context.
     * Objects added to the context through this method always end up
     * in the top-level context of possible wrapped contexts.
     *
     *  @param key name of item to set.
     *  @param value object to set to key.
     *  @return old stored object
     */
    public Object localPut(final String key, final Object value)
    {
        return localContext.put(key, value);
    }

    /**
     * @see org.apache.velocity.context.InternalHousekeepingContext#getAllowRendering()
     */
    public boolean getAllowRendering()
    {
       return allowRendering && innerContext.getAllowRendering();
    }

    /**
     * @see org.apache.velocity.context.InternalHousekeepingContext#setAllowRendering(boolean)
     */
    public void setAllowRendering(boolean v)
    {
        allowRendering = false;
    }

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy