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 e) { 60 throw new IOError(e); 61 } catch (FileNotFoundException e) { 62 throw new IOError(e); 63 } 64 } 65 66 private void init(InputStream stream) throws XmlPullParserException { 67 setFeature(FEATURE_PROCESS_NAMESPACES, true); 68 setInput(stream, null); 69 } 70 71 @Override 72 public Object getViewCookie() { 73 // TODO: Implement this properly. 74 String name = super.getName(); 75 if (name == null) { 76 return null; 77 } 78 79 // Store tools attributes if this looks like a layout we'll need adapter view 80 // bindings for in the LayoutlibCallback. 81 if (LIST_VIEW.equals(name) || EXPANDABLE_LIST_VIEW.equals(name) || GRID_VIEW.equals(name) || SPINNER.equals(name)) { 82 Map<String, String> map = null; 83 int count = getAttributeCount(); 84 for (int i = 0; i < count; i++) { 85 String namespace = getAttributeNamespace(i); 86 if (namespace != null && namespace.equals(TOOLS_URI)) { 87 String attribute = getAttributeName(i); 88 if (attribute.equals(ATTR_IGNORE)) { 89 continue; 90 } 91 if (map == null) { 92 map = new HashMap<String, String>(4); 93 } 94 map.put(attribute, getAttributeValue(i)); 95 } 96 } 97 98 return map; 99 } 100 101 return null; 102 } 103 104 @Override 105 @Deprecated 106 public ILayoutPullParser getParser(String layoutName) { 107 // Studio returns null. 108 return null; 109 } 110 111} 112