package org.robolectric.res;
import javax.xml.stream.XMLStreamException;
import javax.xml.stream.XMLStreamReader;
import java.util.HashMap;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
class NodeHandler {
private static final Pattern ATTR_RE = Pattern.compile("([^\\[]*)(?:\\[@(.+)='(.+)'])?");
private final Map<String, ElementHandler> subElementHandlers = new HashMap<>();
private static class ElementHandler extends HashMap<String, AttrHandler> {
final NodeHandler nodeHandler;
private ElementHandler(NodeHandler nodeHandler) {
this.nodeHandler = nodeHandler;
}
}
private static class AttrHandler extends HashMap<String, NodeHandler> {
}
NodeHandler findMatchFor(XMLStreamReader xml) {
String tagName = xml.getLocalName();
ElementHandler elementHandler = subElementHandlers.get(tagName);
if (elementHandler == null) {
elementHandler = subElementHandlers.get("*");
}
if (elementHandler != null) {
for (Map.Entry<String, AttrHandler> entry : elementHandler.entrySet()) {
String attrName = entry.getKey();
String attributeValue = xml.getAttributeValue(null, attrName);
if (attributeValue != null) {
AttrHandler attrHandler = entry.getValue();
NodeHandler nodeHandler = attrHandler.get(attributeValue);
if (nodeHandler != null) {
return nodeHandler;
}
}
}
return elementHandler.nodeHandler;
}
return null;
}
public NodeHandler addHandler(String matchExpr, NodeHandler subHandler) {
Matcher attrMatcher = ATTR_RE.matcher(matchExpr);
if (attrMatcher.find()) {
String elementName = attrMatcher.group(1);
String attrName = attrMatcher.group(2);
String attrValue = attrMatcher.group(3);
if (elementName == null || elementName.isEmpty()) {
elementName = "*";
}
ElementHandler elementHandler = subElementHandlers.get(elementName);
if (elementHandler == null) {
elementHandler = new ElementHandler(attrName == null ? subHandler : null);
subElementHandlers.put(elementName, elementHandler);
}
if (attrName != null) {
AttrHandler attrHandler = elementHandler.get(attrName);
if (attrHandler == null) {
attrHandler = new AttrHandler();
elementHandler.put(attrName, attrHandler);
}
attrHandler.put(attrValue, subHandler);
}
} else {
throw new RuntimeException("unknown pattern " + matchExpr);
}
return this;
}
public void onStart(XMLStreamReader xml, XmlContext xmlContext) throws XMLStreamException {
}
public void onCharacters(XMLStreamReader xml, XmlContext xmlContext) throws XMLStreamException {
}
public void onEnd(XMLStreamReader xml, XmlContext xmlContext) throws XMLStreamException {
}
}