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