1 package org.robolectric.res; 2 3 import java.util.HashMap; 4 import java.util.Map; 5 import java.util.regex.Matcher; 6 import java.util.regex.Pattern; 7 import javax.xml.stream.XMLStreamException; 8 import javax.xml.stream.XMLStreamReader; 9 10 class NodeHandler { 11 private static final Pattern ATTR_RE = Pattern.compile("([^\\[]*)(?:\\[@(.+)='(.+)'])?"); 12 13 private final Map<String, ElementHandler> subElementHandlers = new HashMap<>(); 14 15 private static class ElementHandler extends HashMap<String, AttrHandler> { 16 final NodeHandler nodeHandler; 17 ElementHandler(NodeHandler nodeHandler)18 private ElementHandler(NodeHandler nodeHandler) { 19 this.nodeHandler = nodeHandler; 20 } 21 } 22 23 private static class AttrHandler extends HashMap<String, NodeHandler> { 24 } 25 findMatchFor(XMLStreamReader xml)26 NodeHandler findMatchFor(XMLStreamReader xml) { 27 String tagName = xml.getLocalName(); 28 ElementHandler elementHandler = subElementHandlers.get(tagName); 29 if (elementHandler == null) { 30 elementHandler = subElementHandlers.get("*"); 31 } 32 if (elementHandler != null) { 33 for (Map.Entry<String, AttrHandler> entry : elementHandler.entrySet()) { 34 String attrName = entry.getKey(); 35 String attributeValue = xml.getAttributeValue(null, attrName); 36 if (attributeValue != null) { 37 AttrHandler attrHandler = entry.getValue(); 38 NodeHandler nodeHandler = attrHandler.get(attributeValue); 39 if (nodeHandler != null) { 40 return nodeHandler; 41 } 42 } 43 } 44 45 return elementHandler.nodeHandler; 46 } 47 48 return null; 49 } 50 addHandler(String matchExpr, NodeHandler subHandler)51 public NodeHandler addHandler(String matchExpr, NodeHandler subHandler) { 52 Matcher attrMatcher = ATTR_RE.matcher(matchExpr); 53 if (attrMatcher.find()) { 54 String elementName = attrMatcher.group(1); 55 String attrName = attrMatcher.group(2); 56 String attrValue = attrMatcher.group(3); 57 58 if (elementName == null || elementName.isEmpty()) { 59 elementName = "*"; 60 } 61 62 ElementHandler elementHandler = subElementHandlers.get(elementName); 63 if (elementHandler == null) { 64 elementHandler = new ElementHandler(attrName == null ? subHandler : null); 65 subElementHandlers.put(elementName, elementHandler); 66 } 67 68 if (attrName != null) { 69 AttrHandler attrHandler = elementHandler.get(attrName); 70 if (attrHandler == null) { 71 attrHandler = new AttrHandler(); 72 elementHandler.put(attrName, attrHandler); 73 } 74 attrHandler.put(attrValue, subHandler); 75 } 76 } else { 77 throw new RuntimeException("unknown pattern " + matchExpr); 78 } 79 80 return this; 81 } 82 onStart(XMLStreamReader xml, XmlContext xmlContext)83 public void onStart(XMLStreamReader xml, XmlContext xmlContext) throws XMLStreamException { 84 } 85 onCharacters(XMLStreamReader xml, XmlContext xmlContext)86 public void onCharacters(XMLStreamReader xml, XmlContext xmlContext) throws XMLStreamException { 87 } 88 onEnd(XMLStreamReader xml, XmlContext xmlContext)89 public void onEnd(XMLStreamReader xml, XmlContext xmlContext) throws XMLStreamException { 90 } 91 } 92