1/*
2 * Copyright (C) 2014 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 com.android.layoutlib.bridge.intensive.setup;
18
19import com.android.ide.common.rendering.api.ILayoutPullParser;
20
21import org.kxml2.io.KXmlParser;
22import org.xmlpull.v1.XmlPullParserException;
23
24import java.io.File;
25import java.io.FileInputStream;
26import java.io.FileNotFoundException;
27import java.io.IOError;
28import java.io.InputStream;
29import java.util.HashMap;
30import java.util.Map;
31
32import static com.android.SdkConstants.ATTR_IGNORE;
33import static com.android.SdkConstants.EXPANDABLE_LIST_VIEW;
34import static com.android.SdkConstants.GRID_VIEW;
35import static com.android.SdkConstants.LIST_VIEW;
36import static com.android.SdkConstants.SPINNER;
37import static com.android.SdkConstants.TOOLS_URI;
38
39public class LayoutPullParser extends KXmlParser implements ILayoutPullParser{
40
41    /**
42     * @param layoutPath Must start with '/' and be relative to test resources.
43     */
44    public LayoutPullParser(String layoutPath) {
45        assert layoutPath.startsWith("/");
46        try {
47            init(getClass().getResourceAsStream(layoutPath));
48        } catch (XmlPullParserException e) {
49            throw new IOError(e);
50        }
51    }
52
53    /**
54     * @param layoutFile Path of the layout xml file on disk.
55     */
56    public LayoutPullParser(File layoutFile) {
57        try {
58            init(new FileInputStream(layoutFile));
59        } catch (XmlPullParserException | FileNotFoundException e) {
60            throw new IOError(e);
61        }
62    }
63
64    private void init(InputStream stream) throws XmlPullParserException {
65        setFeature(FEATURE_PROCESS_NAMESPACES, true);
66        setInput(stream, null);
67    }
68
69    @Override
70    public Object getViewCookie() {
71        // TODO: Implement this properly.
72        String name = super.getName();
73        if (name == null) {
74            return null;
75        }
76
77        // Store tools attributes if this looks like a layout we'll need adapter view
78        // bindings for in the LayoutlibCallback.
79        if (LIST_VIEW.equals(name) || EXPANDABLE_LIST_VIEW.equals(name) || GRID_VIEW.equals(name) || SPINNER.equals(name)) {
80            Map<String, String> map = null;
81            int count = getAttributeCount();
82            for (int i = 0; i < count; i++) {
83                String namespace = getAttributeNamespace(i);
84                if (namespace != null && namespace.equals(TOOLS_URI)) {
85                    String attribute = getAttributeName(i);
86                    if (attribute.equals(ATTR_IGNORE)) {
87                        continue;
88                    }
89                    if (map == null) {
90                        map = new HashMap<String, String>(4);
91                    }
92                    map.put(attribute, getAttributeValue(i));
93                }
94            }
95
96            return map;
97        }
98
99        return null;
100    }
101
102    @Override
103    @Deprecated
104    public ILayoutPullParser getParser(String layoutName) {
105        // Studio returns null.
106        return null;
107    }
108
109}
110