Home | History | Annotate | Download | only in res
      1 package com.xtremelabs.robolectric.res;
      2 
      3 import java.util.ArrayList;
      4 import java.util.HashMap;
      5 import java.util.List;
      6 import java.util.Map;
      7 
      8 class ResourceReferenceResolver<T> {
      9     private Map<String, T> attributeNamesToValues = new HashMap<String, T>();
     10     private Map<String, List<String>> unresolvedReferences = new HashMap<String, List<String>>();
     11     private String referenceType;
     12     private String[] allowedReferenceTypesForRawValues;
     13 
     14     ResourceReferenceResolver(String referenceType) {
     15         this(referenceType, new String[] { referenceType });
     16     }
     17 
     18     ResourceReferenceResolver(String referenceType, String[] allowedReferenceTypesForRawValues) {
     19         this.referenceType = referenceType;
     20         this.allowedReferenceTypesForRawValues = allowedReferenceTypesForRawValues;
     21     }
     22 
     23     public T getValue(String resourceName) {
     24         return attributeNamesToValues.get(resourceName);
     25     }
     26 
     27     public void processResource(String name, String rawValue, ResourceValueConverter loader, boolean isSystem) {
     28         String valuePointer = referenceType + "/" + name;
     29 
     30         boolean isAllowedReferenceType = false;
     31         for (String allowedReferenceTypesForRawValue : allowedReferenceTypesForRawValues) {
     32             if (rawValue.startsWith("@")
     33                     && rawValue.contains(allowedReferenceTypesForRawValue + "/")) {
     34                 isAllowedReferenceType = true;
     35                 break;
     36             }
     37         }
     38 
     39         if (isAllowedReferenceType) {
     40             addAttributeReference(rawValue, valuePointer);
     41         } else {
     42             if (isSystem) {
     43                 valuePointer = "android:" + valuePointer;
     44             }
     45             addAttribute(valuePointer, (T) loader.convertRawValue(rawValue));
     46         }
     47     }
     48 
     49     public void addAttribute(String valuePointer, T value) {
     50         attributeNamesToValues.put(valuePointer, value);
     51         resolveUnresolvedReferences(valuePointer, value);
     52     }
     53 
     54     private void resolveUnresolvedReferences(String attributeName, T value) {
     55         List<String> references = unresolvedReferences.remove(attributeName);
     56         if (references == null) {
     57             return;
     58         }
     59         for (String reference : references) {
     60             attributeNamesToValues.put(reference, value);
     61         }
     62     }
     63 
     64     private void addUnresolvedReference(String valuePointer, String attributeName) {
     65         List<String> references = unresolvedReferences.get(attributeName);
     66         if (references == null) {
     67             references = new ArrayList<String>();
     68             unresolvedReferences.put(attributeName, references);
     69         }
     70         references.add(valuePointer);
     71     }
     72 
     73     private void addAttributeReference(String rawValue, String valuePointer) {
     74         String attributeName = rawValue.substring(1);
     75         T value = attributeNamesToValues.get(attributeName);
     76         if (value == null) {
     77             addUnresolvedReference(valuePointer, attributeName);
     78         } else {
     79             attributeNamesToValues.put(valuePointer, value);
     80         }
     81     }
     82 }
     83