1 package com.xtremelabs.robolectric.tester.android.util; 2 3 import android.util.AttributeSet; 4 import android.view.View; 5 import com.xtremelabs.robolectric.res.AttrResourceLoader; 6 import com.xtremelabs.robolectric.res.ResourceExtractor; 7 import com.xtremelabs.robolectric.util.I18nException; 8 9 import java.util.*; 10 11 public class TestAttributeSet implements AttributeSet { 12 Map<String, String> attributes = new HashMap<String, String>(); 13 private ResourceExtractor resourceExtractor; 14 private AttrResourceLoader attrResourceLoader; 15 private Class<? extends View> viewClass; 16 private boolean isSystem = false; 17 18 /** 19 * Names of attributes to be validated for i18n-safe values. 20 */ 21 private static final String strictI18nAttrs[] = { 22 "android:text", 23 "android:title", 24 "android:titleCondensed", 25 "android:summary" 26 }; 27 28 public TestAttributeSet() { 29 this(new HashMap<String, String>()); 30 } 31 32 public TestAttributeSet(Map<String, String> attributes, ResourceExtractor resourceExtractor, 33 AttrResourceLoader attrResourceLoader, Class<? extends View> viewClass, boolean isSystem) { 34 this.attributes = attributes; 35 this.resourceExtractor = resourceExtractor; 36 this.attrResourceLoader = attrResourceLoader; 37 this.viewClass = viewClass; 38 this.isSystem = isSystem; 39 } 40 41 public TestAttributeSet(Map<String, String> attributes) { 42 this.attributes = attributes; 43 this.resourceExtractor = new ResourceExtractor(); 44 this.attrResourceLoader = new AttrResourceLoader(this.resourceExtractor); 45 this.viewClass = null; 46 } 47 48 public TestAttributeSet put(String name, String value) { 49 attributes.put(name, value); 50 return this; 51 } 52 53 @Override 54 public boolean getAttributeBooleanValue(String namespace, String attribute, boolean defaultValue) { 55 String value = getAttributeValueInMap(namespace, attribute); 56 return (value != null) ? Boolean.valueOf(value) : defaultValue; 57 } 58 59 @Override 60 public String getAttributeValue(String namespace, String attribute) { 61 return getAttributeValueInMap(namespace, attribute); 62 } 63 64 @Override 65 public int getAttributeIntValue(String namespace, String attribute, int defaultValue) { 66 String value = getAttributeValueInMap(namespace, attribute); 67 68 if (attrResourceLoader.hasAttributeFor(viewClass, "xxx", attribute)) { 69 value = attrResourceLoader.convertValueToEnum(viewClass, "xxx", attribute, value); 70 } 71 72 return (value != null) ? Integer.valueOf(value) : defaultValue; 73 } 74 75 @Override 76 public int getAttributeCount() { 77 throw new UnsupportedOperationException(); 78 } 79 80 @Override 81 public String getAttributeName(int index) { 82 throw new UnsupportedOperationException(); 83 } 84 85 @Override 86 public String getAttributeValue(int index) { 87 throw new UnsupportedOperationException(); 88 } 89 90 @Override 91 public String getPositionDescription() { 92 throw new UnsupportedOperationException(); 93 } 94 95 @Override 96 public int getAttributeNameResource(int index) { 97 throw new UnsupportedOperationException(); 98 } 99 100 @Override 101 public int getAttributeListValue(String namespace, String attribute, String[] options, int defaultValue) { 102 throw new UnsupportedOperationException(); 103 } 104 105 @Override 106 public int getAttributeUnsignedIntValue(String namespace, String attribute, int defaultValue) { 107 throw new UnsupportedOperationException(); 108 } 109 110 @Override 111 public float getAttributeFloatValue(String namespace, String attribute, float defaultValue) { 112 String value = getAttributeValueInMap(namespace, attribute); 113 114 if (attrResourceLoader.hasAttributeFor(viewClass, "xxx", attribute)) { 115 value = attrResourceLoader.convertValueToEnum(viewClass, "xxx", attribute, value); 116 } 117 118 return (value != null) ? Float.valueOf(value) : defaultValue; 119 } 120 121 @Override 122 public int getAttributeListValue(int index, String[] options, int defaultValue) { 123 throw new UnsupportedOperationException(); 124 } 125 126 @Override 127 public boolean getAttributeBooleanValue(int resourceId, boolean defaultValue) { 128 throw new UnsupportedOperationException(); 129 } 130 131 @Override 132 public int getAttributeResourceValue(String namespace, String attribute, int defaultValue) { 133 String value = getAttributeValueInMap(namespace, attribute); 134 Integer resourceId = defaultValue; 135 if (value != null) { 136 resourceId = resourceExtractor.getResourceId(value); 137 } 138 return resourceId == null ? defaultValue : resourceId; 139 } 140 141 @Override 142 public int getAttributeResourceValue(int resourceId, int defaultValue) { 143 String attrName = resourceExtractor.getResourceName(resourceId); 144 String value = getAttributeValueInMap(null, attrName); 145 return (value == null) ? defaultValue : resourceExtractor.getResourceId(value); 146 } 147 148 @Override 149 public int getAttributeIntValue(int index, int defaultValue) { 150 throw new UnsupportedOperationException(); 151 } 152 153 @Override 154 public int getAttributeUnsignedIntValue(int index, int defaultValue) { 155 throw new UnsupportedOperationException(); 156 } 157 158 @Override 159 public float getAttributeFloatValue(int index, float defaultValue) { 160 throw new UnsupportedOperationException(); 161 } 162 163 @Override 164 public String getIdAttribute() { 165 throw new UnsupportedOperationException(); 166 } 167 168 @Override 169 public String getClassAttribute() { 170 throw new UnsupportedOperationException(); 171 } 172 173 @Override 174 public int getIdAttributeResourceValue(int defaultValue) { 175 throw new UnsupportedOperationException(); 176 } 177 178 @Override 179 public int getStyleAttribute() { 180 throw new UnsupportedOperationException(); 181 } 182 183 public void validateStrictI18n() { 184 for (int i = 0; i < strictI18nAttrs.length; i++) { 185 String key = strictI18nAttrs[i]; 186 if (attributes.containsKey(key)) { 187 String value = attributes.get(key); 188 if (!value.startsWith("@string/")) { 189 throw new I18nException("View class: " + (viewClass != null ? viewClass.getName() : "") + 190 " has attribute: " + key + " with hardcoded value: \"" + value + "\" and is not i18n-safe."); 191 } 192 } 193 } 194 } 195 196 private String getAttributeValueInMap(String namespace, String attribute) { 197 String value = null; 198 for (String key : attributes.keySet()) { 199 String[] mappedKeys = {null, key}; 200 if (key.contains(":")) { 201 mappedKeys = key.split(":"); 202 } 203 204 if (mappedKeys[1].equals(attribute) && ( 205 namespace == null || namespace != "android" || 206 (namespace.equals("android") && namespace.equals(mappedKeys[0])))) { 207 value = attributes.get(key); 208 break; 209 } 210 } 211 if (value != null && isSystem && value.startsWith("@+id")) { 212 value = value.replace("@+id", "@+android:id"); 213 } 214 return value; 215 } 216 } 217