1/*
2 * Copyright (C) 2008 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package android.util;
18
19import com.android.ide.common.rendering.api.RenderResources;
20import com.android.ide.common.rendering.api.ResourceValue;
21import com.android.layoutlib.bridge.Bridge;
22import com.android.layoutlib.bridge.BridgeConstants;
23import com.android.layoutlib.bridge.android.BridgeContext;
24import com.android.resources.ResourceType;
25
26import org.xmlpull.v1.XmlPullParser;
27
28import android.util.AttributeSet;
29import android.util.XmlPullAttributes;
30
31/**
32 * A correct implementation of the {@link AttributeSet} interface on top of a XmlPullParser
33 */
34public class BridgeXmlPullAttributes extends XmlPullAttributes {
35
36    private final BridgeContext mContext;
37    private final boolean mPlatformFile;
38
39    public BridgeXmlPullAttributes(XmlPullParser parser, BridgeContext context,
40            boolean platformFile) {
41        super(parser);
42        mContext = context;
43        mPlatformFile = platformFile;
44    }
45
46    /*
47     * (non-Javadoc)
48     * @see android.util.XmlPullAttributes#getAttributeNameResource(int)
49     *
50     * This methods must return com.android.internal.R.attr.<name> matching
51     * the name of the attribute.
52     * It returns 0 if it doesn't find anything.
53     */
54    @Override
55    public int getAttributeNameResource(int index) {
56        // get the attribute name.
57        String name = getAttributeName(index);
58
59        // get the attribute namespace
60        String ns = mParser.getAttributeNamespace(index);
61
62        if (BridgeConstants.NS_RESOURCES.equals(ns)) {
63            Integer v = Bridge.getResourceId(ResourceType.ATTR, name);
64            if (v != null) {
65                return v.intValue();
66            }
67
68            return 0;
69        }
70
71        // this is not an attribute in the android namespace, we query the customviewloader, if
72        // the namespaces match.
73        if (mContext.getProjectCallback().getNamespace().equals(ns)) {
74            Integer v = mContext.getProjectCallback().getResourceId(ResourceType.ATTR, name);
75            if (v != null) {
76                return v.intValue();
77            }
78        }
79
80        return 0;
81    }
82
83    /*
84     * (non-Javadoc)
85     * @see android.util.XmlPullAttributes#getAttributeResourceValue(int, int)
86     */
87    @Override
88    public int getAttributeResourceValue(int index, int defaultValue) {
89        String value = getAttributeValue(index);
90
91        return resolveResourceValue(value, defaultValue);
92    }
93
94    /*
95     * (non-Javadoc)
96     * @see android.util.XmlPullAttributes#getAttributeResourceValue(java.lang.String, java.lang.String, int)
97     */
98    @Override
99    public int getAttributeResourceValue(String namespace, String attribute, int defaultValue) {
100        String value = getAttributeValue(namespace, attribute);
101
102        return resolveResourceValue(value, defaultValue);
103    }
104
105    private int resolveResourceValue(String value, int defaultValue) {
106        // now look for this particular value
107        RenderResources resources = mContext.getRenderResources();
108        ResourceValue resource = resources.resolveResValue(
109                resources.findResValue(value, mPlatformFile));
110
111        if (resource != null) {
112            Integer id = null;
113            if (mPlatformFile || resource.isFramework()) {
114                id = Bridge.getResourceId(resource.getResourceType(), resource.getName());
115            } else {
116                id = mContext.getProjectCallback().getResourceId(
117                        resource.getResourceType(), resource.getName());
118            }
119
120            if (id != null) {
121                return id;
122            }
123        }
124
125        return defaultValue;
126    }
127
128}
129