package de.neuland.jade4j.model; import java.util.ArrayList; import java.util.Collection; import java.util.Deque; import java.util.HashMap; import java.util.HashSet; import java.util.Iterator; import java.util.LinkedList; import java.util.List; import java.util.Map; import java.util.Set; import de.neuland.jade4j.filter.Filter; import de.neuland.jade4j.parser.node.MixinNode; public class JadeModel implements Map<String, Object> { private static final String LOCALS = "locals"; private Deque<Map<String, Object>> scopes = new LinkedList<Map<String, Object>>(); private Map<String, MixinNode> mixins = new HashMap<String, MixinNode>(); private Map<String, Filter> filter = new HashMap<String, Filter>(); public JadeModel(Map<String, Object> defaults) { Map<String, Object> rootScope = new HashMap<String, Object>(); scopes.add(rootScope); if (defaults != null) { putAll(defaults); } put(LOCALS, this); } public void pushScope() { HashMap<String, Object> scope = new HashMap<String, Object>(); scopes.add(scope); } public void popScope() { scopes.removeLast(); } public void setMixin(String name, MixinNode node) { mixins.put(name, node); } public MixinNode getMixin(String name) { return mixins.get(name); } @Override public void clear() { scopes.clear(); scopes.add(new HashMap<String, Object>()); } @Override public boolean containsKey(Object key) { for (Iterator<Map<String, Object>> i = scopes.descendingIterator(); i.hasNext();) { Map<String, Object> scope = i.next(); if (scope.containsKey(key)) { return true; } } return false; } @Override public boolean containsValue(Object value) { for (Iterator<Map<String, Object>> i = scopes.descendingIterator(); i.hasNext();) { Map<String, Object> scope = i.next(); if (scope.containsValue(value)) { return true; } } return false; } @Override public Set<java.util.Map.Entry<String, Object>> entrySet() { HashMap<String, Object> map = new HashMap<String, Object>(); for (String key : keySet()) { map.put(key, get(key)); } return map.entrySet(); } @Override // adds the object to the highest scope public Object get(Object key) { for (Iterator<Map<String, Object>> i = scopes.descendingIterator(); i.hasNext();) { Map<String, Object> scope = i.next(); if (scope.containsKey(key)) { return scope.get(key); } } return null; } @Override public boolean isEmpty() { return keySet().isEmpty(); } @Override // returns a set of unique keys public Set<String> keySet() { Set<String> keys = new HashSet<String>(); for (Iterator<Map<String, Object>> i = scopes.descendingIterator(); i.hasNext();) { keys.addAll(i.next().keySet()); } return keys; } @Override // adds the object to the current scope public Object put(String key, Object value) { Object currentValue = get(key); scopes.getLast().put(key, value); return currentValue; } @Override // addes all map entries to the current scope map public void putAll(Map<? extends String, ? extends Object> m) { scopes.getLast().putAll(m); } @Override // removes the scopes first object with the given key public Object remove(Object key) { for (Iterator<Map<String, Object>> i = scopes.descendingIterator(); i.hasNext();) { Map<String, Object> scope = i.next(); if (scope.containsKey(key)) { Object object = scope.get(key); scope.remove(key); return object; } } return null; } @Override // returns the size of all unique keys public int size() { return keySet().size(); } @Override // returns the size of all unique keys public Collection<Object> values() { List<Object> values = new ArrayList<Object>(); for (String key : keySet()) { values.add(get(key)); } return values; } public Filter getFilter(String name) { return filter.get(name); } public void addFilter(String name, Filter filter) { this.filter.put(name, filter); } }