Hi Andrea,

> I imagined it almost the way you proposed it, the only twist would
> be that the map would be stored in thread local to allow multiple
> value and that the function would also allow a default value to
> fall back to if the variable is not defined.

Thread-local values is a brilliant idea !

Would this do the trick ?  (untested)

import java.util.LinkedHashMap;
import java.util.Map;
import org.geotools.filter.FunctionExpressionImpl;
import org.opengis.feature.simple.SimpleFeature;

public class VarLookupFunction extends FunctionExpressionImpl {

    /**
     * Provides a lookup table that is local to each thread.
     */
    private static class Lookup extends ThreadLocal<Map<String, Object>> {

        @Override
        protected Map<String, Object> initialValue() {
            return new LinkedHashMap<String, Object>();
        }

        /**
         * Get a value from the lookup table by name.
         *
         * @param name name of the variable to look up
         *
         * @return value or {...@code null} if the name is not found
         */
        public Object getValue(String name) {
            return super.get().get(name);
        }

        /**
         * Get the table of lookup values.
         * Defined to make code using this class more obvious.
         *
         * @return the table of lookup values
         */
        public Map<String, Object> getTable() {
            return super.get();
        }
    };

    private static final Lookup lookup = new Lookup();

    /**
     * Create a new instance of this function.
     */
    public VarLookupFunction() {
        super("VarLookup");
    }

    /**
     * Set the table of lookup values, deleting any previously set table.
     * The input {...@code Map} is copied.
     *
     * @param values the lookup table; if {...@code null} any existing lookup
     *        table will be cleared.
     */
    public static void setValues(Map<String, Object> values) {
        Map<String, Object> table = lookup.getTable();
        table.clear();

        if (values != null) {
            table.putAll(values);
        }
    }

    /**
     * Add a named value to the lookup table. If the name is already present
     * in the table it will be assigned the new value.
     *
     * @param name the name
     * @param value the value
     */
    public static void setValue(String name, Object value) {
        lookup.getTable().put(name, value);
    }

    /**
     * {...@inheritdoc}
     * @return Always returns 1
     */
    @Override
    public int getArgCount() {
        return 1;
    }

    /**
     * {...@inheritdoc}
     * If the result for this feature is {...@code null} a fallback value will 
be
     * returned if one has been set.
     *
     * @return the result for this feature
     *
     * @see #setFallbackValue
     */
    @Override
    public Object evaluate(SimpleFeature feature) {
        String varName = getExpression(0).evaluate(feature, String.class);
        Object value = lookup.getValue(name);

        if (value != null) {
            return value;
        } else {
            return this.getFallbackValue().getValue();
        }
    }

}

------------------------------------------------------------------------------
Join us December 9, 2009 for the Red Hat Virtual Experience,
a free event focused on virtualization and cloud computing. 
Attend in-depth sessions from your desk. Your couch. Anywhere.
http://p.sf.net/sfu/redhat-sfdev2dev
_______________________________________________
Geotools-gt2-users mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/geotools-gt2-users

Reply via email to