1 package com.xtremelabs.robolectric.res; 2 3 import android.view.View; 4 import org.w3c.dom.Document; 5 import org.w3c.dom.Node; 6 import org.w3c.dom.NodeList; 7 8 import javax.xml.xpath.XPathConstants; 9 import javax.xml.xpath.XPathExpression; 10 import javax.xml.xpath.XPathFactory; 11 import java.io.File; 12 import java.util.HashMap; 13 import java.util.HashSet; 14 import java.util.Map; 15 import java.util.Set; 16 17 public class AttrResourceLoader extends XmlLoader { 18 Map<String, String> classAttrEnumToValue = new HashMap<String, String>(); 19 Set<String> knownClassAttrs = new HashSet<String>(); 20 21 public AttrResourceLoader(ResourceExtractor resourceExtractor) { 22 super(resourceExtractor); 23 } 24 25 @Override 26 protected void processResourceXml(File xmlFile, Document document, boolean isSystem) throws Exception { 27 XPathExpression stringsXPath = XPathFactory.newInstance().newXPath().compile("/resources/declare-styleable/attr/enum"); 28 NodeList stringNodes = (NodeList) stringsXPath.evaluate(document, XPathConstants.NODESET); 29 for (int i = 0; i < stringNodes.getLength(); i++) { 30 Node node = stringNodes.item(i); 31 String viewName = node.getParentNode().getParentNode().getAttributes().getNamedItem("name").getNodeValue(); 32 String enumName = node.getParentNode().getAttributes().getNamedItem("name").getNodeValue(); 33 String name = node.getAttributes().getNamedItem("name").getNodeValue(); 34 String value = node.getAttributes().getNamedItem("value").getNodeValue(); 35 36 classAttrEnumToValue.put(key(viewName, enumName, name, isSystem), value); 37 knownClassAttrs.add(key(viewName, enumName, isSystem)); 38 } 39 } 40 41 public String convertValueToEnum(Class<? extends View> viewClass, String namespace, String attrName, String attrValue) { 42 boolean isSystem = "android".equals(namespace); 43 String className = findKnownAttrClass(attrName, viewClass, isSystem); 44 return classAttrEnumToValue.get(key(className, attrName, attrValue, isSystem)); 45 } 46 47 public boolean hasAttributeFor(Class<? extends View> viewClass, String namespace, String attrName) { 48 boolean isSystem = "android".equals(namespace); 49 return findKnownAttrClass(attrName, viewClass, isSystem) != null; 50 } 51 52 private String findKnownAttrClass(String attrName, Class<?> clazz, boolean isSystem) { 53 while (clazz != null) { 54 String className = clazz.getName(); 55 if (isSystem) { 56 className = clazz.getSimpleName(); 57 } 58 if (knownClassAttrs.contains(key(className, attrName, isSystem))) { 59 return className; 60 } 61 clazz = clazz.getSuperclass(); 62 } 63 return null; 64 } 65 66 private String key(String viewName, String attrName, String name, boolean isSystem) { 67 return key(viewName, attrName, isSystem) + "#" + name; 68 } 69 70 private String key(String viewName, String attrName, boolean isSystem) { 71 return (isSystem ? "android:" : "") + viewName + "#" + attrName; 72 } 73 } 74