sascha@998: package de.intevation.flys.artifacts.datacage.templating; sascha@998: sascha@1023: import java.util.ArrayList; sascha@998: import java.util.Map; sascha@998: import java.util.List; sascha@998: import java.util.HashMap; sascha@1023: import java.util.HashSet; sascha@1023: import java.util.Set; sascha@998: sascha@998: import javax.xml.xpath.XPathVariableResolver; sascha@998: sascha@998: import javax.xml.namespace.QName; sascha@998: sascha@998: import org.apache.log4j.Logger; sascha@998: felix@4594: felix@4594: /** felix@4594: * Maintains stack of 'frames' which are maps from string to object. felix@4914: * Used for variables in datacage/meta-data system and acts felix@4914: * as a XPathVariablResolver in xpath evaluation, e.g. by own felix@4914: * dc: - methods. felix@4594: */ sascha@998: public class StackFrames sascha@998: implements XPathVariableResolver sascha@998: { sascha@998: private static Logger log = Logger.getLogger(StackFrames.class); sascha@998: felix@4594: /** The frames (used like a stack). */ sascha@998: protected List> frames; sascha@998: sascha@998: public StackFrames() { sascha@998: frames = new ArrayList>(); sascha@998: } sascha@998: sascha@998: public StackFrames(Map initialFrame) { sascha@998: this(); sascha@998: if (initialFrame != null) { sascha@998: frames.add(new HashMap(initialFrame)); sascha@998: } sascha@998: } sascha@998: felix@4594: /** Push a new String->Object map. */ sascha@998: public void enter() { sascha@998: frames.add(new HashMap()); sascha@998: } sascha@998: felix@4594: /** Pop/Remove last String->Object map. */ sascha@998: public void leave() { sascha@998: frames.remove(frames.size()-1); sascha@998: } sascha@998: felix@4594: /** Put Key/Value in last String->Object map. */ sascha@998: public void put(String key, Object value) { sascha@998: int N = frames.size(); sascha@998: if (N > 0) { sascha@998: frames.get(N-1).put(key, value); sascha@998: } sascha@998: } sascha@998: felix@4594: /** Put multiple Key/Values in last String->Object map. */ sascha@998: public void put(String [] keys, Object [] values) { sascha@998: Map top = frames.get(frames.size()-1); sascha@998: for (int i = 0; i < keys.length; ++i) { sascha@998: top.put(keys[i], values[i]); sascha@998: } sascha@998: } sascha@998: felix@4594: /** Check last frame (string->object map) for key. */ sascha@998: public boolean containsKey(String key) { sascha@1716: key = key.toUpperCase(); sascha@998: for (int i = frames.size()-1; i >= 0; --i) { sascha@998: if (frames.get(i).containsKey(key)) { sascha@998: return true; sascha@998: } sascha@998: } sascha@998: return false; sascha@998: } sascha@998: felix@1930: /** felix@1930: * Get element (variable) key. felix@1930: * Returns null if not found. felix@1930: * @param key name to resolve felix@1930: * @return resolution, null if not found. felix@1930: */ sascha@998: public Object get(String key) { sascha@998: return get(key, null); sascha@998: } sascha@998: felix@4594: /** result[0] is modified with value when true returned. felix@4594: * @return false if key not found in any frame. */ sascha@1716: public boolean getStore(String key, Object [] result) { sascha@1716: sascha@1716: key = key.toUpperCase(); sascha@1716: sascha@1716: for (int i = frames.size()-1; i >= 0; --i) { sascha@1716: Map frame = frames.get(i); sascha@1716: if (frame.containsKey(key)) { sascha@1716: result[0] = frame.get(key); sascha@1716: return true; sascha@1716: } sascha@1716: } sascha@1716: sascha@1716: return false; sascha@1716: } sascha@1716: felix@4914: /** felix@4914: * Returns Object stored for as key, parameter def felix@4914: * if not found. felix@4914: */ felix@4914: private Object get(String key, Object def) { sascha@998: sascha@1716: key = key.toUpperCase(); sascha@1716: sascha@998: for (int i = frames.size()-1; i >= 0; --i) { sascha@998: Map frame = frames.get(i); sascha@998: if (frame.containsKey(key)) { sascha@998: return frame.get(key); sascha@998: } sascha@998: } sascha@998: sascha@998: return def; sascha@998: } sascha@998: sascha@998: @Override sascha@998: public Object resolveVariable(QName variableName) { sascha@998: if (log.isDebugEnabled()) { sascha@998: log.debug("resolve var: " + variableName); sascha@998: } sascha@998: return get(variableName.getLocalPart()); sascha@998: } sascha@1023: sascha@1023: public String dump() { sascha@1023: StringBuilder sb = new StringBuilder("["); sascha@1023: Set already = new HashSet(); sascha@1023: sascha@1023: boolean first = true; sascha@1023: sascha@1023: for (int i = frames.size()-1; i >= 0; --i) { sascha@1023: Map frame = frames.get(i); sascha@1023: for (Map.Entry entry: frame.entrySet()) { sascha@1023: if (already.add(entry.getKey())) { sascha@1023: if (first) { first = false; } sascha@1023: else { sb.append(", "); } sascha@1023: sb.append('\'').append(entry.getKey()) sascha@1023: .append("'='").append(entry.getValue()).append('\''); sascha@1023: } sascha@1023: } sascha@1023: } sascha@1023: return sb.append(']').toString(); sascha@1023: } sascha@998: } sascha@998: // vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :