package fitnesse.wikitext.parser; import util.Maybe; import java.util.ArrayList; import java.util.HashMap; import java.util.List; public class Symbol { public static final Maybe<Symbol> nothing = new Maybe<Symbol>(); public static final Symbol emptySymbol = new Symbol(SymbolType.Empty); private SymbolType type; private String content = ""; private List<Symbol> children = new ArrayList<Symbol>(); private HashMap<String, String> variables; private HashMap<String, String> properties; public Symbol(SymbolType type) { this.type = type; } public Symbol(SymbolType type, String content) { this.content = content; this.type = type; } public SymbolType getType() { return type; } public boolean isType(SymbolType type) { return this.type.matchesFor(type); } public boolean isStartCell() { return isType(Table.symbolType) || isType(SymbolType.EndCell); } public boolean isStartLine() { return isType(HorizontalRule.symbolType) || isType(Nesting.symbolType); } public boolean isLineType() { return isType(HeaderLine.symbolType) || isType(SymbolType.CenterLine) || isType(SymbolType.Meta) || isType(SymbolType.NoteLine); } public String getContent() { return content; } public void setContent(String content) { this.content = content; } public Symbol childAt(int index) { return getChildren().get(index); } public Symbol lastChild() { return childAt(getChildren().size() - 1); } public List<Symbol> getChildren() { return children; } public Symbol addToFront(Symbol child) { ArrayList<Symbol> newChildren = new ArrayList<Symbol>(); newChildren.add(child); newChildren.addAll(children); children = newChildren; return this; } public Symbol add(Symbol child) { children.add(child); return this; } public Symbol add(String text) { children.add(new Symbol(SymbolType.Text, text)); return this; } public Symbol childrenAfter(int after) { Symbol result = new Symbol(SymbolType.SymbolList); for (int i = after + 1; i < children.size(); i++) result.add(children.get(i)); return result; } public boolean walkPostOrder(SymbolTreeWalker walker) { if (walker.visitChildren(this)) { for (Symbol child: children) { if (!child.walkPostOrder(walker)) return false; } } return walker.visit(this); } public boolean walkPreOrder(SymbolTreeWalker walker) { if (!walker.visit(this)) return false; if (walker.visitChildren(this)) { for (Symbol child: children) { if (!child.walkPreOrder(walker)) return false; } } return true; } public void evaluateVariables(String[] names, VariableSource source) { if (variables == null) variables = new HashMap<String, String>(); for (String name: names) { Maybe<String> value = source.findVariable(name); if (!value.isNothing()) variables.put(name, value.getValue()); } } public String getVariable(String name, String defaultValue) { return variables != null && variables.containsKey(name) ? variables.get(name) : defaultValue; } public Symbol putProperty(String key, String value) { if (properties == null) properties = new HashMap<String, String> (); properties.put(key, value); return this; } public boolean hasProperty(String key) { return properties != null && properties.containsKey(key); } public String getProperty(String key, String defaultValue) { return properties != null && properties.containsKey(key) ? properties.get(key) : defaultValue; } public String getProperty(String key) { return getProperty(key, ""); } public SymbolType closeType() { return type == SymbolType.OpenBrace ? SymbolType.CloseBrace : type == SymbolType.OpenBracket ? SymbolType.CloseBracket : type == SymbolType.OpenParenthesis ? SymbolType.CloseParenthesis : type == Literal.symbolType ? SymbolType.CloseLiteral : type == Comment.symbolType ? SymbolType.Newline : SymbolType.Empty; } }