Home | History | Annotate | Download | only in res
      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