186eb8b4e29b1ad889fc814bae723d4d6e491f53fDeepanshu Gupta/*
286eb8b4e29b1ad889fc814bae723d4d6e491f53fDeepanshu Gupta * Copyright (C) 2014 The Android Open Source Project
386eb8b4e29b1ad889fc814bae723d4d6e491f53fDeepanshu Gupta *
486eb8b4e29b1ad889fc814bae723d4d6e491f53fDeepanshu Gupta * Licensed under the Apache License, Version 2.0 (the "License");
586eb8b4e29b1ad889fc814bae723d4d6e491f53fDeepanshu Gupta * you may not use this file except in compliance with the License.
686eb8b4e29b1ad889fc814bae723d4d6e491f53fDeepanshu Gupta * You may obtain a copy of the License at
786eb8b4e29b1ad889fc814bae723d4d6e491f53fDeepanshu Gupta *
886eb8b4e29b1ad889fc814bae723d4d6e491f53fDeepanshu Gupta *      http://www.apache.org/licenses/LICENSE-2.0
986eb8b4e29b1ad889fc814bae723d4d6e491f53fDeepanshu Gupta *
1086eb8b4e29b1ad889fc814bae723d4d6e491f53fDeepanshu Gupta * Unless required by applicable law or agreed to in writing, software
1186eb8b4e29b1ad889fc814bae723d4d6e491f53fDeepanshu Gupta * distributed under the License is distributed on an "AS IS" BASIS,
1286eb8b4e29b1ad889fc814bae723d4d6e491f53fDeepanshu Gupta * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1386eb8b4e29b1ad889fc814bae723d4d6e491f53fDeepanshu Gupta * See the License for the specific language governing permissions and
1486eb8b4e29b1ad889fc814bae723d4d6e491f53fDeepanshu Gupta * limitations under the License.
1586eb8b4e29b1ad889fc814bae723d4d6e491f53fDeepanshu Gupta */
1686eb8b4e29b1ad889fc814bae723d4d6e491f53fDeepanshu Gupta
1786eb8b4e29b1ad889fc814bae723d4d6e491f53fDeepanshu Guptapackage com.android.layoutlib.bridge.intensive.setup;
1886eb8b4e29b1ad889fc814bae723d4d6e491f53fDeepanshu Gupta
1986eb8b4e29b1ad889fc814bae723d4d6e491f53fDeepanshu Guptaimport com.android.ide.common.rendering.api.ILayoutPullParser;
2086eb8b4e29b1ad889fc814bae723d4d6e491f53fDeepanshu Gupta
2186eb8b4e29b1ad889fc814bae723d4d6e491f53fDeepanshu Guptaimport org.kxml2.io.KXmlParser;
2286eb8b4e29b1ad889fc814bae723d4d6e491f53fDeepanshu Guptaimport org.xmlpull.v1.XmlPullParserException;
2386eb8b4e29b1ad889fc814bae723d4d6e491f53fDeepanshu Gupta
2486eb8b4e29b1ad889fc814bae723d4d6e491f53fDeepanshu Guptaimport java.io.File;
2586eb8b4e29b1ad889fc814bae723d4d6e491f53fDeepanshu Guptaimport java.io.FileInputStream;
2686eb8b4e29b1ad889fc814bae723d4d6e491f53fDeepanshu Guptaimport java.io.FileNotFoundException;
2786eb8b4e29b1ad889fc814bae723d4d6e491f53fDeepanshu Guptaimport java.io.IOError;
2886eb8b4e29b1ad889fc814bae723d4d6e491f53fDeepanshu Guptaimport java.io.InputStream;
2986eb8b4e29b1ad889fc814bae723d4d6e491f53fDeepanshu Guptaimport java.util.HashMap;
3086eb8b4e29b1ad889fc814bae723d4d6e491f53fDeepanshu Guptaimport java.util.Map;
3186eb8b4e29b1ad889fc814bae723d4d6e491f53fDeepanshu Gupta
3286eb8b4e29b1ad889fc814bae723d4d6e491f53fDeepanshu Guptaimport static com.android.SdkConstants.ATTR_IGNORE;
3386eb8b4e29b1ad889fc814bae723d4d6e491f53fDeepanshu Guptaimport static com.android.SdkConstants.EXPANDABLE_LIST_VIEW;
3486eb8b4e29b1ad889fc814bae723d4d6e491f53fDeepanshu Guptaimport static com.android.SdkConstants.GRID_VIEW;
3586eb8b4e29b1ad889fc814bae723d4d6e491f53fDeepanshu Guptaimport static com.android.SdkConstants.LIST_VIEW;
3686eb8b4e29b1ad889fc814bae723d4d6e491f53fDeepanshu Guptaimport static com.android.SdkConstants.SPINNER;
3786eb8b4e29b1ad889fc814bae723d4d6e491f53fDeepanshu Guptaimport static com.android.SdkConstants.TOOLS_URI;
3886eb8b4e29b1ad889fc814bae723d4d6e491f53fDeepanshu Gupta
3986eb8b4e29b1ad889fc814bae723d4d6e491f53fDeepanshu Guptapublic class LayoutPullParser extends KXmlParser implements ILayoutPullParser{
4086eb8b4e29b1ad889fc814bae723d4d6e491f53fDeepanshu Gupta
4186eb8b4e29b1ad889fc814bae723d4d6e491f53fDeepanshu Gupta    /**
4286eb8b4e29b1ad889fc814bae723d4d6e491f53fDeepanshu Gupta     * @param layoutPath Must start with '/' and be relative to test resources.
4386eb8b4e29b1ad889fc814bae723d4d6e491f53fDeepanshu Gupta     */
4486eb8b4e29b1ad889fc814bae723d4d6e491f53fDeepanshu Gupta    public LayoutPullParser(String layoutPath) {
45dc3bb324ceeaa5e0b42b977b8f92ac7a04bcd5b1Diego Perez        if (layoutPath.startsWith("/")) {
46dc3bb324ceeaa5e0b42b977b8f92ac7a04bcd5b1Diego Perez            layoutPath = layoutPath.substring(1);
47dc3bb324ceeaa5e0b42b977b8f92ac7a04bcd5b1Diego Perez        }
4886eb8b4e29b1ad889fc814bae723d4d6e491f53fDeepanshu Gupta        try {
49dc3bb324ceeaa5e0b42b977b8f92ac7a04bcd5b1Diego Perez            init(getClass().getClassLoader().getResourceAsStream(layoutPath));
5086eb8b4e29b1ad889fc814bae723d4d6e491f53fDeepanshu Gupta        } catch (XmlPullParserException e) {
5186eb8b4e29b1ad889fc814bae723d4d6e491f53fDeepanshu Gupta            throw new IOError(e);
5286eb8b4e29b1ad889fc814bae723d4d6e491f53fDeepanshu Gupta        }
5386eb8b4e29b1ad889fc814bae723d4d6e491f53fDeepanshu Gupta    }
5486eb8b4e29b1ad889fc814bae723d4d6e491f53fDeepanshu Gupta
5586eb8b4e29b1ad889fc814bae723d4d6e491f53fDeepanshu Gupta    /**
5686eb8b4e29b1ad889fc814bae723d4d6e491f53fDeepanshu Gupta     * @param layoutFile Path of the layout xml file on disk.
5786eb8b4e29b1ad889fc814bae723d4d6e491f53fDeepanshu Gupta     */
5886eb8b4e29b1ad889fc814bae723d4d6e491f53fDeepanshu Gupta    public LayoutPullParser(File layoutFile) {
5986eb8b4e29b1ad889fc814bae723d4d6e491f53fDeepanshu Gupta        try {
6086eb8b4e29b1ad889fc814bae723d4d6e491f53fDeepanshu Gupta            init(new FileInputStream(layoutFile));
61ceb1ab1d2a71c6d4e0cccf110a198ff83cb97e5aDeepanshu Gupta        } catch (XmlPullParserException | FileNotFoundException e) {
6286eb8b4e29b1ad889fc814bae723d4d6e491f53fDeepanshu Gupta            throw new IOError(e);
6386eb8b4e29b1ad889fc814bae723d4d6e491f53fDeepanshu Gupta        }
6486eb8b4e29b1ad889fc814bae723d4d6e491f53fDeepanshu Gupta    }
6586eb8b4e29b1ad889fc814bae723d4d6e491f53fDeepanshu Gupta
6686eb8b4e29b1ad889fc814bae723d4d6e491f53fDeepanshu Gupta    private void init(InputStream stream) throws XmlPullParserException {
6786eb8b4e29b1ad889fc814bae723d4d6e491f53fDeepanshu Gupta        setFeature(FEATURE_PROCESS_NAMESPACES, true);
6886eb8b4e29b1ad889fc814bae723d4d6e491f53fDeepanshu Gupta        setInput(stream, null);
6986eb8b4e29b1ad889fc814bae723d4d6e491f53fDeepanshu Gupta    }
7086eb8b4e29b1ad889fc814bae723d4d6e491f53fDeepanshu Gupta
7186eb8b4e29b1ad889fc814bae723d4d6e491f53fDeepanshu Gupta    @Override
7286eb8b4e29b1ad889fc814bae723d4d6e491f53fDeepanshu Gupta    public Object getViewCookie() {
7386eb8b4e29b1ad889fc814bae723d4d6e491f53fDeepanshu Gupta        // TODO: Implement this properly.
7486eb8b4e29b1ad889fc814bae723d4d6e491f53fDeepanshu Gupta        String name = super.getName();
7586eb8b4e29b1ad889fc814bae723d4d6e491f53fDeepanshu Gupta        if (name == null) {
7686eb8b4e29b1ad889fc814bae723d4d6e491f53fDeepanshu Gupta            return null;
7786eb8b4e29b1ad889fc814bae723d4d6e491f53fDeepanshu Gupta        }
7886eb8b4e29b1ad889fc814bae723d4d6e491f53fDeepanshu Gupta
7986eb8b4e29b1ad889fc814bae723d4d6e491f53fDeepanshu Gupta        // Store tools attributes if this looks like a layout we'll need adapter view
8086eb8b4e29b1ad889fc814bae723d4d6e491f53fDeepanshu Gupta        // bindings for in the LayoutlibCallback.
8186eb8b4e29b1ad889fc814bae723d4d6e491f53fDeepanshu Gupta        if (LIST_VIEW.equals(name) || EXPANDABLE_LIST_VIEW.equals(name) || GRID_VIEW.equals(name) || SPINNER.equals(name)) {
8286eb8b4e29b1ad889fc814bae723d4d6e491f53fDeepanshu Gupta            Map<String, String> map = null;
8386eb8b4e29b1ad889fc814bae723d4d6e491f53fDeepanshu Gupta            int count = getAttributeCount();
8486eb8b4e29b1ad889fc814bae723d4d6e491f53fDeepanshu Gupta            for (int i = 0; i < count; i++) {
8586eb8b4e29b1ad889fc814bae723d4d6e491f53fDeepanshu Gupta                String namespace = getAttributeNamespace(i);
8686eb8b4e29b1ad889fc814bae723d4d6e491f53fDeepanshu Gupta                if (namespace != null && namespace.equals(TOOLS_URI)) {
8786eb8b4e29b1ad889fc814bae723d4d6e491f53fDeepanshu Gupta                    String attribute = getAttributeName(i);
8886eb8b4e29b1ad889fc814bae723d4d6e491f53fDeepanshu Gupta                    if (attribute.equals(ATTR_IGNORE)) {
8986eb8b4e29b1ad889fc814bae723d4d6e491f53fDeepanshu Gupta                        continue;
9086eb8b4e29b1ad889fc814bae723d4d6e491f53fDeepanshu Gupta                    }
9186eb8b4e29b1ad889fc814bae723d4d6e491f53fDeepanshu Gupta                    if (map == null) {
9286eb8b4e29b1ad889fc814bae723d4d6e491f53fDeepanshu Gupta                        map = new HashMap<String, String>(4);
9386eb8b4e29b1ad889fc814bae723d4d6e491f53fDeepanshu Gupta                    }
9486eb8b4e29b1ad889fc814bae723d4d6e491f53fDeepanshu Gupta                    map.put(attribute, getAttributeValue(i));
9586eb8b4e29b1ad889fc814bae723d4d6e491f53fDeepanshu Gupta                }
9686eb8b4e29b1ad889fc814bae723d4d6e491f53fDeepanshu Gupta            }
9786eb8b4e29b1ad889fc814bae723d4d6e491f53fDeepanshu Gupta
9886eb8b4e29b1ad889fc814bae723d4d6e491f53fDeepanshu Gupta            return map;
9986eb8b4e29b1ad889fc814bae723d4d6e491f53fDeepanshu Gupta        }
10086eb8b4e29b1ad889fc814bae723d4d6e491f53fDeepanshu Gupta
10186eb8b4e29b1ad889fc814bae723d4d6e491f53fDeepanshu Gupta        return null;
10286eb8b4e29b1ad889fc814bae723d4d6e491f53fDeepanshu Gupta    }
10386eb8b4e29b1ad889fc814bae723d4d6e491f53fDeepanshu Gupta
10486eb8b4e29b1ad889fc814bae723d4d6e491f53fDeepanshu Gupta    @Override
10586eb8b4e29b1ad889fc814bae723d4d6e491f53fDeepanshu Gupta    @Deprecated
10686eb8b4e29b1ad889fc814bae723d4d6e491f53fDeepanshu Gupta    public ILayoutPullParser getParser(String layoutName) {
10786eb8b4e29b1ad889fc814bae723d4d6e491f53fDeepanshu Gupta        // Studio returns null.
10886eb8b4e29b1ad889fc814bae723d4d6e491f53fDeepanshu Gupta        return null;
10986eb8b4e29b1ad889fc814bae723d4d6e491f53fDeepanshu Gupta    }
11086eb8b4e29b1ad889fc814bae723d4d6e491f53fDeepanshu Gupta
11186eb8b4e29b1ad889fc814bae723d4d6e491f53fDeepanshu Gupta}
112