/* * Copyright (C) 2008 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.android.layoutlib.bridge; import com.android.layoutlib.api.IXmlPullParser; import org.xmlpull.v1.XmlPullParser; import org.xmlpull.v1.XmlPullParserException; import android.content.res.XmlResourceParser; import android.util.AttributeSet; import android.util.XmlPullAttributes; import java.io.IOException; import java.io.InputStream; import java.io.Reader; /** * {@link BridgeXmlBlockParser} reimplements most of android.xml.XmlBlock.Parser. * It delegates to both an instance of {@link XmlPullParser} and an instance of * {@link XmlPullAttributes} (for the {@link AttributeSet} part). */ public class BridgeXmlBlockParser implements XmlResourceParser { private XmlPullParser mParser; private XmlPullAttributes mAttrib; private boolean mStarted = false; private boolean mDecNextDepth = false; private int mDepth = 0; private int mEventType = START_DOCUMENT; private final boolean mPlatformFile; /** * Builds a {@link BridgeXmlBlockParser}. * @param parser The XmlPullParser to get the content from. * @param context the Context. * @param platformFile Indicates whether the the file is a platform file or not. */ public BridgeXmlBlockParser(XmlPullParser parser, BridgeContext context, boolean platformFile) { mParser = parser; mPlatformFile = platformFile; mAttrib = new BridgeXmlPullAttributes(parser, context, mPlatformFile); } public boolean isPlatformFile() { return mPlatformFile; } public Object getViewKey() { if (mParser instanceof IXmlPullParser) { return ((IXmlPullParser)mParser).getViewKey(); } return null; } // ------- XmlResourceParser implementation public void setFeature(String name, boolean state) throws XmlPullParserException { if (FEATURE_PROCESS_NAMESPACES.equals(name) && state) { return; } if (FEATURE_REPORT_NAMESPACE_ATTRIBUTES.equals(name) && state) { return; } throw new XmlPullParserException("Unsupported feature: " + name); } public boolean getFeature(String name) { if (FEATURE_PROCESS_NAMESPACES.equals(name)) { return true; } if (FEATURE_REPORT_NAMESPACE_ATTRIBUTES.equals(name)) { return true; } return false; } public void setProperty(String name, Object value) throws XmlPullParserException { throw new XmlPullParserException("setProperty() not supported"); } public Object getProperty(String name) { return null; } public void setInput(Reader in) throws XmlPullParserException { mParser.setInput(in); } public void setInput(InputStream inputStream, String inputEncoding) throws XmlPullParserException { mParser.setInput(inputStream, inputEncoding); } public void defineEntityReplacementText(String entityName, String replacementText) throws XmlPullParserException { throw new XmlPullParserException( "defineEntityReplacementText() not supported"); } public String getNamespacePrefix(int pos) throws XmlPullParserException { throw new XmlPullParserException("getNamespacePrefix() not supported"); } public String getInputEncoding() { return null; } public String getNamespace(String prefix) { throw new RuntimeException("getNamespace() not supported"); } public int getNamespaceCount(int depth) throws XmlPullParserException { throw new XmlPullParserException("getNamespaceCount() not supported"); } public String getPositionDescription() { return "Binary XML file line #" + getLineNumber(); } public String getNamespaceUri(int pos) throws XmlPullParserException { throw new XmlPullParserException("getNamespaceUri() not supported"); } public int getColumnNumber() { return -1; } public int getDepth() { return mDepth; } public String getText() { return mParser.getText(); } public int getLineNumber() { return mParser.getLineNumber(); } public int getEventType() { return mEventType; } public boolean isWhitespace() throws XmlPullParserException { // Original comment: whitespace was stripped by aapt. return mParser.isWhitespace(); } public String getPrefix() { throw new RuntimeException("getPrefix not supported"); } public char[] getTextCharacters(int[] holderForStartAndLength) { String txt = getText(); char[] chars = null; if (txt != null) { holderForStartAndLength[0] = 0; holderForStartAndLength[1] = txt.length(); chars = new char[txt.length()]; txt.getChars(0, txt.length(), chars, 0); } return chars; } public String getNamespace() { return mParser.getNamespace(); } public String getName() { return mParser.getName(); } public String getAttributeNamespace(int index) { return mParser.getAttributeNamespace(index); } public String getAttributeName(int index) { return mParser.getAttributeName(index); } public String getAttributePrefix(int index) { throw new RuntimeException("getAttributePrefix not supported"); } public boolean isEmptyElementTag() { // XXX Need to detect this. return false; } public int getAttributeCount() { return mParser.getAttributeCount(); } public String getAttributeValue(int index) { return mParser.getAttributeValue(index); } public String getAttributeType(int index) { return "CDATA"; } public boolean isAttributeDefault(int index) { return false; } public int nextToken() throws XmlPullParserException, IOException { return next(); } public String getAttributeValue(String namespace, String name) { return mParser.getAttributeValue(namespace, name); } public int next() throws XmlPullParserException, IOException { if (!mStarted) { mStarted = true; return START_DOCUMENT; } int ev = mParser.next(); if (mDecNextDepth) { mDepth--; mDecNextDepth = false; } switch (ev) { case START_TAG: mDepth++; break; case END_TAG: mDecNextDepth = true; break; } mEventType = ev; return ev; } public void require(int type, String namespace, String name) throws XmlPullParserException { if (type != getEventType() || (namespace != null && !namespace.equals(getNamespace())) || (name != null && !name.equals(getName()))) throw new XmlPullParserException("expected " + TYPES[type] + getPositionDescription()); } public String nextText() throws XmlPullParserException, IOException { if (getEventType() != START_TAG) { throw new XmlPullParserException(getPositionDescription() + ": parser must be on START_TAG to read next text", this, null); } int eventType = next(); if (eventType == TEXT) { String result = getText(); eventType = next(); if (eventType != END_TAG) { throw new XmlPullParserException( getPositionDescription() + ": event TEXT it must be immediately followed by END_TAG", this, null); } return result; } else if (eventType == END_TAG) { return ""; } else { throw new XmlPullParserException(getPositionDescription() + ": parser must be on START_TAG or TEXT to read text", this, null); } } public int nextTag() throws XmlPullParserException, IOException { int eventType = next(); if (eventType == TEXT && isWhitespace()) { // skip whitespace eventType = next(); } if (eventType != START_TAG && eventType != END_TAG) { throw new XmlPullParserException(getPositionDescription() + ": expected start or end tag", this, null); } return eventType; } // AttributeSet implementation public void close() { // pass } public boolean getAttributeBooleanValue(int index, boolean defaultValue) { return mAttrib.getAttributeBooleanValue(index, defaultValue); } public boolean getAttributeBooleanValue(String namespace, String attribute, boolean defaultValue) { return mAttrib.getAttributeBooleanValue(namespace, attribute, defaultValue); } public float getAttributeFloatValue(int index, float defaultValue) { return mAttrib.getAttributeFloatValue(index, defaultValue); } public float getAttributeFloatValue(String namespace, String attribute, float defaultValue) { return mAttrib.getAttributeFloatValue(namespace, attribute, defaultValue); } public int getAttributeIntValue(int index, int defaultValue) { return mAttrib.getAttributeIntValue(index, defaultValue); } public int getAttributeIntValue(String namespace, String attribute, int defaultValue) { return mAttrib.getAttributeIntValue(namespace, attribute, defaultValue); } public int getAttributeListValue(int index, String[] options, int defaultValue) { return mAttrib.getAttributeListValue(index, options, defaultValue); } public int getAttributeListValue(String namespace, String attribute, String[] options, int defaultValue) { return mAttrib.getAttributeListValue(namespace, attribute, options, defaultValue); } public int getAttributeNameResource(int index) { return mAttrib.getAttributeNameResource(index); } public int getAttributeResourceValue(int index, int defaultValue) { return mAttrib.getAttributeResourceValue(index, defaultValue); } public int getAttributeResourceValue(String namespace, String attribute, int defaultValue) { return mAttrib.getAttributeResourceValue(namespace, attribute, defaultValue); } public int getAttributeUnsignedIntValue(int index, int defaultValue) { return mAttrib.getAttributeUnsignedIntValue(index, defaultValue); } public int getAttributeUnsignedIntValue(String namespace, String attribute, int defaultValue) { return mAttrib.getAttributeUnsignedIntValue(namespace, attribute, defaultValue); } public String getClassAttribute() { return mAttrib.getClassAttribute(); } public String getIdAttribute() { return mAttrib.getIdAttribute(); } public int getIdAttributeResourceValue(int defaultValue) { return mAttrib.getIdAttributeResourceValue(defaultValue); } public int getStyleAttribute() { return mAttrib.getStyleAttribute(); } }