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 android.annotation.NonNull; 25 26import java.io.ByteArrayInputStream; 27import java.io.File; 28import java.io.FileInputStream; 29import java.io.FileNotFoundException; 30import java.io.IOError; 31import java.io.InputStream; 32import java.nio.charset.Charset; 33import java.util.HashMap; 34import java.util.Map; 35 36import static com.android.SdkConstants.ATTR_IGNORE; 37import static com.android.SdkConstants.EXPANDABLE_LIST_VIEW; 38import static com.android.SdkConstants.GRID_VIEW; 39import static com.android.SdkConstants.LIST_VIEW; 40import static com.android.SdkConstants.SPINNER; 41import static com.android.SdkConstants.TOOLS_URI; 42 43public class LayoutPullParser extends KXmlParser implements ILayoutPullParser{ 44 @NonNull 45 public static LayoutPullParser createFromFile(@NonNull File layoutFile) 46 throws FileNotFoundException { 47 return new LayoutPullParser(new FileInputStream(layoutFile)); 48 } 49 50 /** 51 * @param layoutPath Must start with '/' and be relative to test resources. 52 */ 53 @NonNull 54 public static LayoutPullParser createFromPath(@NonNull String layoutPath) { 55 if (layoutPath.startsWith("/")) { 56 layoutPath = layoutPath.substring(1); 57 } 58 59 return new LayoutPullParser(LayoutPullParser.class.getClassLoader().getResourceAsStream 60 (layoutPath)); 61 } 62 63 @NonNull 64 public static LayoutPullParser createFromString(@NonNull String contents) { 65 return new LayoutPullParser(new ByteArrayInputStream( 66 contents.getBytes(Charset.forName("UTF-8")))); 67 } 68 69 private LayoutPullParser(@NonNull InputStream inputStream) { 70 try { 71 setFeature(FEATURE_PROCESS_NAMESPACES, true); 72 setInput(inputStream, null); 73 } catch (XmlPullParserException e) { 74 throw new IOError(e); 75 } 76 } 77 78 @Override 79 public Object getViewCookie() { 80 // TODO: Implement this properly. 81 String name = super.getName(); 82 if (name == null) { 83 return null; 84 } 85 86 // Store tools attributes if this looks like a layout we'll need adapter view 87 // bindings for in the LayoutlibCallback. 88 if (LIST_VIEW.equals(name) || EXPANDABLE_LIST_VIEW.equals(name) || GRID_VIEW.equals(name) || SPINNER.equals(name)) { 89 Map<String, String> map = null; 90 int count = getAttributeCount(); 91 for (int i = 0; i < count; i++) { 92 String namespace = getAttributeNamespace(i); 93 if (namespace != null && namespace.equals(TOOLS_URI)) { 94 String attribute = getAttributeName(i); 95 if (attribute.equals(ATTR_IGNORE)) { 96 continue; 97 } 98 if (map == null) { 99 map = new HashMap<String, String>(4); 100 } 101 map.put(attribute, getAttributeValue(i)); 102 } 103 } 104 105 return map; 106 } 107 108 return null; 109 } 110 111 @Override 112 @Deprecated 113 public ILayoutPullParser getParser(String layoutName) { 114 // Studio returns null. 115 return null; 116 } 117 118} 119