view flys-artifacts/src/main/java/de/intevation/flys/artifacts/datacage/templating/StackFrames.java @ 4594:2970046fcdca

Doc.
author Felix Wolfsteller <felix.wolfsteller@intevation.de>
date Thu, 29 Nov 2012 11:48:20 +0100
parents de0c2bbb27f9
children 4d1e2a0c283a 142ed3c62765
line wrap: on
line source
package de.intevation.flys.artifacts.datacage.templating;

import java.util.ArrayList;
import java.util.Map;
import java.util.List;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Set;

import javax.xml.xpath.XPathVariableResolver;

import javax.xml.namespace.QName;

import org.apache.log4j.Logger;


/**
 * Maintains stack of 'frames' which are maps from string to object.
 * Used for variables in datacage/meta-data system.
 */
public class StackFrames
implements   XPathVariableResolver
{
    private static Logger log = Logger.getLogger(StackFrames.class);

    /** The frames (used like a stack). */
    protected List<Map<String, Object>> frames;

    public StackFrames() {
        frames = new ArrayList<Map<String, Object>>();
    }

    public StackFrames(Map<String, Object> initialFrame) {
        this();
        if (initialFrame != null) {
            frames.add(new HashMap<String, Object>(initialFrame));
        }
    }

    /** Push a new String->Object map. */
    public void enter() {
        frames.add(new HashMap<String, Object>());
    }

    /** Pop/Remove last String->Object map. */
    public void leave() {
        frames.remove(frames.size()-1);
    }

    /** Put Key/Value in last String->Object map. */
    public void put(String key, Object value) {
        int N = frames.size();
        if (N > 0) {
            frames.get(N-1).put(key, value);
        }
    }

    /** Put multiple Key/Values in last String->Object map. */
    public void put(String [] keys, Object [] values) {
        Map<String, Object> top = frames.get(frames.size()-1);
        for (int i = 0; i < keys.length; ++i) {
            top.put(keys[i], values[i]);
        }
    }

    /** Check last frame (string->object map) for key. */
    public boolean containsKey(String key) {
        key = key.toUpperCase();
        for (int i = frames.size()-1; i >= 0; --i) {
            if (frames.get(i).containsKey(key)) {
                return true;
            }
        }
        return false;
    }

    /**
     * Get element (variable) key.
     * Returns null if not found.
     * @param key name to resolve
     * @return resolution, null if not found.
     */
    public Object get(String key) {
        return get(key, null);
    }

    /** result[0] is modified with value when true returned.
     * @return false if key not found in any frame. */
    public boolean getStore(String key, Object [] result) {

        key = key.toUpperCase();

        for (int i = frames.size()-1; i >= 0; --i) {
            Map<String, Object> frame = frames.get(i);
            if (frame.containsKey(key)) {
                result[0] = frame.get(key);
                return true;
            }
        }

        return false;
    }

    public Object get(String key, Object def) {

        key = key.toUpperCase();

        for (int i = frames.size()-1; i >= 0; --i) {
            Map<String, Object> frame = frames.get(i);
            if (frame.containsKey(key)) {
                return frame.get(key);
            }
        }

        return def;
    }

    @Override
    public Object resolveVariable(QName variableName) {
        if (log.isDebugEnabled()) {
            log.debug("resolve var: " + variableName);
        }
        return get(variableName.getLocalPart());
    }

    public String dump() {
        StringBuilder sb = new StringBuilder("[");
        Set<String> already = new HashSet<String>();

        boolean first = true;

        for (int i = frames.size()-1; i >= 0; --i) {
            Map<String, Object> frame = frames.get(i);
            for (Map.Entry<String, Object> entry: frame.entrySet()) {
                if (already.add(entry.getKey())) {
                    if (first) { first = false;   }
                    else       { sb.append(", "); }
                    sb.append('\'').append(entry.getKey())
                      .append("'='").append(entry.getValue()).append('\'');
                }
            }
        }
        return sb.append(']').toString();
    }
}
// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :

http://dive4elements.wald.intevation.org