package com.intrbiz.bergamot.compat.macro; import java.util.Collections; import java.util.HashSet; import java.util.LinkedList; import java.util.List; import java.util.Map; import java.util.Map.Entry; import java.util.Set; import java.util.TreeMap; import java.util.function.Function; public final class MacroFrame { public static final MacroFrame GLOBAL_MACROS = new MacroFrame(new MacroFrame[0]); private List<MacroFrame> prototypes = new LinkedList<MacroFrame>(); private Map<String, String> macros = new TreeMap<String, String>(); public MacroFrame() { this(GLOBAL_MACROS); } public MacroFrame(MacroFrame... prototypes) { super(); this.setPrototypes(prototypes); } public List<MacroFrame> getPrototypes() { return Collections.unmodifiableList(this.prototypes); } public void addPrototype(MacroFrame prototype) { this.prototypes.add(prototype); } public void setPrototypes(MacroFrame... prototypes) { for (MacroFrame prototype : prototypes) { this.addPrototype(prototype); } } public void removePrototype(MacroFrame prototype) { this.prototypes.remove(prototype); } public void clearPrototypes() { this.prototypes.clear(); } public void put(String macroName, String value) { this.macros.put(macroName, value); } public Set<String> getMacros() { Set<String> keys = new HashSet<String>(); keys.addAll(macros.keySet()); for (MacroFrame prototype : this.prototypes) { keys.addAll(prototype.getMacros()); } return keys; } public Set<String> getLocalMacros() { Set<String> keys = new HashSet<String>(); keys.addAll(macros.keySet()); return keys; } public String get(String macroName) { String value = this.macros.get(macroName); if (value == null) { for (MacroFrame prototype : this.prototypes) { value = prototype.get(macroName); if (value != null) break; } } return value; } public String getLocal(String macroName) { return this.macros.get(macroName); } public boolean contains(String macroName) { if (this.macros.containsKey(macroName)) return true; for (MacroFrame prototype : this.prototypes) { if (prototype.contains(macroName)) return true; } return false; } public boolean containsLocal(String macroName) { return this.macros.containsKey(macroName); } public MacroFrame find(String macroName) { if (this.macros.containsKey(macroName)) return this; for (MacroFrame prototype : this.prototypes) { MacroFrame frame = prototype.find(macroName); if (frame != null) return frame; } return null; } public void remove(String macroName) { this.macros.remove(macroName); } public void removeAll(String macroName) { this.macros.remove(macroName); for (MacroFrame prototype : this.prototypes) { prototype.removeAll(macroName); } } public String toString() { return this.toString(""); } private String toString(String padding) { StringBuilder sb = new StringBuilder(); sb.append("{\r\n"); for (Entry<String, String> macro : this.macros.entrySet()) { sb.append(padding).append(" ").append(macro.getKey()).append(" => ").append(macro.getValue()).append(",\r\n"); } sb.append(padding).append(" prototypes => [\r\n"); for (MacroFrame prototype : this.prototypes) { sb.append(padding).append(" ").append(prototype == null ? "null" : prototype.toString(padding + " ")).append(",\r\n"); } sb.append(padding).append("]}"); return sb.toString(); } public static <E> MacroFrame fromParameters(List<E> parameters, Function<E,String> key, Function<E,String> value) { MacroFrame checkFrame = new MacroFrame(); for (E parameter : parameters) { checkFrame.put(key.apply(parameter), value.apply(parameter)); } return checkFrame; } }