Mercurial > dive4elements > river
diff flys-artifacts/src/main/java/org/dive4elements/river/artifacts/datacage/templating/StackFrames.java @ 5831:bd047b71ab37
Repaired internal references
author | Sascha L. Teichmann <teichmann@intevation.de> |
---|---|
date | Thu, 25 Apr 2013 12:06:39 +0200 |
parents | flys-artifacts/src/main/java/de/intevation/flys/artifacts/datacage/templating/StackFrames.java@142ed3c62765 |
children |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/flys-artifacts/src/main/java/org/dive4elements/river/artifacts/datacage/templating/StackFrames.java Thu Apr 25 12:06:39 2013 +0200 @@ -0,0 +1,168 @@ +package org.dive4elements.river.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); + + public static final Object NULL = new Object(); + + /** 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; + } + + public Object getNull(String key) { + return getNull(key, null); + } + + public Object getNull(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)) { + Object value = frame.get(key); + return value != null ? value : NULL; + } + } + + return def; + } + + @Override + public Object resolveVariable(QName variableName) { + if (log.isDebugEnabled()) { + log.debug("resolve var: " + variableName); + } + + return getNull(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 :