1package com.xtremelabs.robolectric.tester.android.util;
2
3import android.util.AttributeSet;
4import android.view.View;
5import com.xtremelabs.robolectric.res.AttrResourceLoader;
6import com.xtremelabs.robolectric.res.ResourceExtractor;
7import com.xtremelabs.robolectric.util.I18nException;
8
9import java.util.*;
10
11public 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