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 
TestAttributeSet()28     public TestAttributeSet() {
29         this(new HashMap<String, String>());
30     }
31 
TestAttributeSet(Map<String, String> attributes, ResourceExtractor resourceExtractor, AttrResourceLoader attrResourceLoader, Class<? extends View> viewClass, boolean isSystem)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 
TestAttributeSet(Map<String, String> attributes)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 
put(String name, String value)48     public TestAttributeSet put(String name, String value) {
49         attributes.put(name, value);
50         return this;
51     }
52 
53     @Override
getAttributeBooleanValue(String namespace, String attribute, boolean defaultValue)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
getAttributeValue(String namespace, String attribute)60     public String getAttributeValue(String namespace, String attribute) {
61         return getAttributeValueInMap(namespace, attribute);
62     }
63 
64     @Override
getAttributeIntValue(String namespace, String attribute, int defaultValue)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
getAttributeCount()76     public int getAttributeCount() {
77         throw new UnsupportedOperationException();
78     }
79 
80     @Override
getAttributeName(int index)81     public String getAttributeName(int index) {
82         throw new UnsupportedOperationException();
83     }
84 
85     @Override
getAttributeValue(int index)86     public String getAttributeValue(int index) {
87         throw new UnsupportedOperationException();
88     }
89 
90     @Override
getPositionDescription()91     public String getPositionDescription() {
92         throw new UnsupportedOperationException();
93     }
94 
95     @Override
getAttributeNameResource(int index)96     public int getAttributeNameResource(int index) {
97         throw new UnsupportedOperationException();
98     }
99 
100     @Override
getAttributeListValue(String namespace, String attribute, String[] options, int defaultValue)101     public int getAttributeListValue(String namespace, String attribute, String[] options, int defaultValue) {
102         throw new UnsupportedOperationException();
103     }
104 
105     @Override
getAttributeUnsignedIntValue(String namespace, String attribute, int defaultValue)106     public int getAttributeUnsignedIntValue(String namespace, String attribute, int defaultValue) {
107         throw new UnsupportedOperationException();
108     }
109 
110     @Override
getAttributeFloatValue(String namespace, String attribute, float defaultValue)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
getAttributeListValue(int index, String[] options, int defaultValue)122     public int getAttributeListValue(int index, String[] options, int defaultValue) {
123         throw new UnsupportedOperationException();
124     }
125 
126     @Override
getAttributeBooleanValue(int resourceId, boolean defaultValue)127     public boolean getAttributeBooleanValue(int resourceId, boolean defaultValue) {
128         throw new UnsupportedOperationException();
129     }
130 
131     @Override
getAttributeResourceValue(String namespace, String attribute, int defaultValue)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
getAttributeResourceValue(int resourceId, int defaultValue)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
getAttributeIntValue(int index, int defaultValue)149     public int getAttributeIntValue(int index, int defaultValue) {
150         throw new UnsupportedOperationException();
151     }
152 
153     @Override
getAttributeUnsignedIntValue(int index, int defaultValue)154     public int getAttributeUnsignedIntValue(int index, int defaultValue) {
155         throw new UnsupportedOperationException();
156     }
157 
158     @Override
getAttributeFloatValue(int index, float defaultValue)159     public float getAttributeFloatValue(int index, float defaultValue) {
160         throw new UnsupportedOperationException();
161     }
162 
163     @Override
getIdAttribute()164     public String getIdAttribute() {
165         throw new UnsupportedOperationException();
166     }
167 
168     @Override
getClassAttribute()169     public String getClassAttribute() {
170         throw new UnsupportedOperationException();
171     }
172 
173     @Override
getIdAttributeResourceValue(int defaultValue)174     public int getIdAttributeResourceValue(int defaultValue) {
175         throw new UnsupportedOperationException();
176     }
177 
178     @Override
getStyleAttribute()179     public int getStyleAttribute() {
180         throw new UnsupportedOperationException();
181     }
182 
validateStrictI18n()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 
getAttributeValueInMap(String namespace, String attribute)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