view flys-artifacts/src/main/java/de/intevation/flys/artifacts/datacage/templating/FunctionResolver.java @ 4740:fb135e1dfa35

Added 'type' attribute to <dc:variable/> element. If an optional 'type' attribute is given the result of the XPATH expression is interpreted as this type. Valid values are 'number', 'bool', 'node' and 'nodeset'. All other defaults to 'string' which also is the default if nor type is given.
author Sascha L. Teichmann <teichmann@intevation.de>
date Wed, 02 Jan 2013 15:31:53 +0100
parents 2970046fcdca
children e1566938d04c
line wrap: on
line source
package de.intevation.flys.artifacts.datacage.templating;

import java.util.List;
import java.util.Collection;
import java.util.Map;
import java.util.ArrayList;

import javax.xml.xpath.XPathFunctionResolver;
import javax.xml.xpath.XPathFunction;
import javax.xml.xpath.XPathFunctionException;

import javax.xml.namespace.QName;

import org.apache.log4j.Logger;


/** Resolves functions (e.g. dc:contains) in Datacage/Meta-Data system. */
public class FunctionResolver
implements   XPathFunctionResolver
{
    /** Home logger. */
    private static Logger log = Logger.getLogger(FunctionResolver.class);

    public static final String FUNCTION_NAMESPACE_URI = "dc";

    public static final class Entry {

        String        name;
        XPathFunction function;
        int           arity;

        public Entry() {
        }

        public Entry(String name, XPathFunction function, int arity) {
            this.name     = name;
            this.function = function;
            this.arity    = arity;
        }
    } // class Entry

    public static final FunctionResolver FUNCTIONS = new FunctionResolver();

    static {
        /** Implementation of case-ignoring dc:contains. */
        FUNCTIONS.addFunction("contains", 2, new XPathFunction() {
            @Override
            public Object evaluate(List args) throws XPathFunctionException {
                Object haystack = args.get(0);
                Object needle   = args.get(1);

                if (needle instanceof String) {
                    needle = ((String)needle).toUpperCase();
                }

                try {
                    if (haystack instanceof Collection) {
                        return Boolean.valueOf(
                            ((Collection)haystack).contains(needle));
                    }

                    if (haystack instanceof Map) {
                        return Boolean.valueOf(
                            ((Map)haystack).containsKey(needle));
                    }

                    if (haystack instanceof Object []) {
                        for (Object straw: (Object [])haystack) {
                            if (straw.equals(needle)) {
                                return Boolean.TRUE;
                            }
                        }
                    }

                    return Boolean.FALSE;
                }
                catch (Exception e) {
                    log.error(e);
                    throw new XPathFunctionException(e);
                }
            }
        });
    }

    /** List of functions. */
    protected List<Entry> functions;

    public FunctionResolver() {
        functions = new ArrayList<Entry>();
    }

    /**
     * Create a new function.
     * @param name  Name of the function.
     * @param arity Number of arguments for function.
     * @param function the function itself.
     */
    public void addFunction(String name, int arity, XPathFunction function) {
        functions.add(new Entry(name, function, arity));
    }

    @Override
    public XPathFunction resolveFunction(QName functionName, int arity) {

        if (!functionName.getNamespaceURI().equals(FUNCTION_NAMESPACE_URI)) {
            return null;
        }

        String name = functionName.getLocalPart();
        for (Entry entry: functions) {
            if (entry.arity == arity && entry.name.equals(name)) {
                return entry.function;
            }
        }

        return null;
    }
}
// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :

http://dive4elements.wald.intevation.org