BridgeXmlBlockParser.java revision 55acd60be3c027c224a74290df7bedc1a80c669f
1/*
2 * Copyright (C) 2008 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.android;
18
19import com.android.layoutlib.api.IXmlPullParser;
20
21import org.xmlpull.v1.XmlPullParser;
22import org.xmlpull.v1.XmlPullParserException;
23
24import android.content.res.XmlResourceParser;
25import android.util.AttributeSet;
26import android.util.XmlPullAttributes;
27
28import java.io.IOException;
29import java.io.InputStream;
30import java.io.Reader;
31
32/**
33 * {@link BridgeXmlBlockParser} reimplements most of android.xml.XmlBlock.Parser.
34 * It delegates to both an instance of {@link XmlPullParser} and an instance of
35 * {@link XmlPullAttributes} (for the {@link AttributeSet} part).
36 */
37public class BridgeXmlBlockParser implements XmlResourceParser {
38
39    private XmlPullParser mParser;
40    private XmlPullAttributes mAttrib;
41
42    private boolean mStarted = false;
43    private int mEventType = START_DOCUMENT;
44    private final boolean mPlatformFile;
45    private final BridgeContext mContext;
46
47    /**
48     * Builds a {@link BridgeXmlBlockParser}.
49     * @param parser The XmlPullParser to get the content from.
50     * @param context the Context.
51     * @param platformFile Indicates whether the the file is a platform file or not.
52     */
53    public BridgeXmlBlockParser(XmlPullParser parser, BridgeContext context, boolean platformFile) {
54        mParser = parser;
55        mContext = context;
56        mPlatformFile = platformFile;
57        mAttrib = new BridgeXmlPullAttributes(parser, context, mPlatformFile);
58
59        mContext.pushParser(this);
60    }
61
62    public boolean isPlatformFile() {
63        return mPlatformFile;
64    }
65
66    public Object getViewKey() {
67        if (mParser instanceof IXmlPullParser) {
68            return ((IXmlPullParser)mParser).getViewKey();
69        }
70
71        return null;
72    }
73
74    // ------- XmlResourceParser implementation
75
76    public void setFeature(String name, boolean state)
77            throws XmlPullParserException {
78        if (FEATURE_PROCESS_NAMESPACES.equals(name) && state) {
79            return;
80        }
81        if (FEATURE_REPORT_NAMESPACE_ATTRIBUTES.equals(name) && state) {
82            return;
83        }
84        throw new XmlPullParserException("Unsupported feature: " + name);
85    }
86
87    public boolean getFeature(String name) {
88        if (FEATURE_PROCESS_NAMESPACES.equals(name)) {
89            return true;
90        }
91        if (FEATURE_REPORT_NAMESPACE_ATTRIBUTES.equals(name)) {
92            return true;
93        }
94        return false;
95    }
96
97    public void setProperty(String name, Object value) throws XmlPullParserException {
98        throw new XmlPullParserException("setProperty() not supported");
99    }
100
101    public Object getProperty(String name) {
102        return null;
103    }
104
105    public void setInput(Reader in) throws XmlPullParserException {
106        mParser.setInput(in);
107    }
108
109    public void setInput(InputStream inputStream, String inputEncoding)
110            throws XmlPullParserException {
111        mParser.setInput(inputStream, inputEncoding);
112    }
113
114    public void defineEntityReplacementText(String entityName,
115            String replacementText) throws XmlPullParserException {
116        throw new XmlPullParserException(
117                "defineEntityReplacementText() not supported");
118    }
119
120    public String getNamespacePrefix(int pos) throws XmlPullParserException {
121        throw new XmlPullParserException("getNamespacePrefix() not supported");
122    }
123
124    public String getInputEncoding() {
125        return null;
126    }
127
128    public String getNamespace(String prefix) {
129        throw new RuntimeException("getNamespace() not supported");
130    }
131
132    public int getNamespaceCount(int depth) throws XmlPullParserException {
133        throw new XmlPullParserException("getNamespaceCount() not supported");
134    }
135
136    public String getPositionDescription() {
137        return "Binary XML file line #" + getLineNumber();
138    }
139
140    public String getNamespaceUri(int pos) throws XmlPullParserException {
141        throw new XmlPullParserException("getNamespaceUri() not supported");
142    }
143
144    public int getColumnNumber() {
145        return -1;
146    }
147
148    public int getDepth() {
149        return mParser.getDepth();
150    }
151
152    public String getText() {
153        return mParser.getText();
154    }
155
156    public int getLineNumber() {
157        return mParser.getLineNumber();
158    }
159
160    public int getEventType() {
161        return mEventType;
162    }
163
164    public boolean isWhitespace() throws XmlPullParserException {
165        // Original comment: whitespace was stripped by aapt.
166        return mParser.isWhitespace();
167    }
168
169    public String getPrefix() {
170        throw new RuntimeException("getPrefix not supported");
171    }
172
173    public char[] getTextCharacters(int[] holderForStartAndLength) {
174        String txt = getText();
175        char[] chars = null;
176        if (txt != null) {
177            holderForStartAndLength[0] = 0;
178            holderForStartAndLength[1] = txt.length();
179            chars = new char[txt.length()];
180            txt.getChars(0, txt.length(), chars, 0);
181        }
182        return chars;
183    }
184
185    public String getNamespace() {
186        return mParser.getNamespace();
187    }
188
189    public String getName() {
190        return mParser.getName();
191    }
192
193    public String getAttributeNamespace(int index) {
194        return mParser.getAttributeNamespace(index);
195    }
196
197    public String getAttributeName(int index) {
198        return mParser.getAttributeName(index);
199    }
200
201    public String getAttributePrefix(int index) {
202        throw new RuntimeException("getAttributePrefix not supported");
203    }
204
205    public boolean isEmptyElementTag() {
206        // XXX Need to detect this.
207        return false;
208    }
209
210    public int getAttributeCount() {
211        return mParser.getAttributeCount();
212    }
213
214    public String getAttributeValue(int index) {
215        return mParser.getAttributeValue(index);
216    }
217
218    public String getAttributeType(int index) {
219        return "CDATA";
220    }
221
222    public boolean isAttributeDefault(int index) {
223        return false;
224    }
225
226    public int nextToken() throws XmlPullParserException, IOException {
227        return next();
228    }
229
230    public String getAttributeValue(String namespace, String name) {
231        return mParser.getAttributeValue(namespace, name);
232    }
233
234    public int next() throws XmlPullParserException, IOException {
235        if (!mStarted) {
236            mStarted = true;
237            return START_DOCUMENT;
238        }
239        int ev = mParser.next();
240
241        if (ev == END_TAG && mParser.getDepth() == 1) {
242            // done with parser remove it from the context stack.
243            mContext.popParser();
244        }
245        mEventType = ev;
246        return ev;
247    }
248
249    public void require(int type, String namespace, String name)
250            throws XmlPullParserException {
251        if (type != getEventType()
252                || (namespace != null && !namespace.equals(getNamespace()))
253                || (name != null && !name.equals(getName())))
254            throw new XmlPullParserException("expected " + TYPES[type]
255                    + getPositionDescription());
256    }
257
258    public String nextText() throws XmlPullParserException, IOException {
259        if (getEventType() != START_TAG) {
260            throw new XmlPullParserException(getPositionDescription()
261                    + ": parser must be on START_TAG to read next text", this,
262                    null);
263        }
264        int eventType = next();
265        if (eventType == TEXT) {
266            String result = getText();
267            eventType = next();
268            if (eventType != END_TAG) {
269                throw new XmlPullParserException(
270                        getPositionDescription()
271                                + ": event TEXT it must be immediately followed by END_TAG",
272                        this, null);
273            }
274            return result;
275        } else if (eventType == END_TAG) {
276            return "";
277        } else {
278            throw new XmlPullParserException(getPositionDescription()
279                    + ": parser must be on START_TAG or TEXT to read text",
280                    this, null);
281        }
282    }
283
284    public int nextTag() throws XmlPullParserException, IOException {
285        int eventType = next();
286        if (eventType == TEXT && isWhitespace()) { // skip whitespace
287            eventType = next();
288        }
289        if (eventType != START_TAG && eventType != END_TAG) {
290            throw new XmlPullParserException(getPositionDescription()
291                    + ": expected start or end tag", this, null);
292        }
293        return eventType;
294    }
295
296    // AttributeSet implementation
297
298
299    public void close() {
300        // pass
301    }
302
303    public boolean getAttributeBooleanValue(int index, boolean defaultValue) {
304        return mAttrib.getAttributeBooleanValue(index, defaultValue);
305    }
306
307    public boolean getAttributeBooleanValue(String namespace, String attribute,
308            boolean defaultValue) {
309        return mAttrib.getAttributeBooleanValue(namespace, attribute, defaultValue);
310    }
311
312    public float getAttributeFloatValue(int index, float defaultValue) {
313        return mAttrib.getAttributeFloatValue(index, defaultValue);
314    }
315
316    public float getAttributeFloatValue(String namespace, String attribute, float defaultValue) {
317        return mAttrib.getAttributeFloatValue(namespace, attribute, defaultValue);
318    }
319
320    public int getAttributeIntValue(int index, int defaultValue) {
321        return mAttrib.getAttributeIntValue(index, defaultValue);
322    }
323
324    public int getAttributeIntValue(String namespace, String attribute, int defaultValue) {
325        return mAttrib.getAttributeIntValue(namespace, attribute, defaultValue);
326    }
327
328    public int getAttributeListValue(int index, String[] options, int defaultValue) {
329        return mAttrib.getAttributeListValue(index, options, defaultValue);
330    }
331
332    public int getAttributeListValue(String namespace, String attribute,
333            String[] options, int defaultValue) {
334        return mAttrib.getAttributeListValue(namespace, attribute, options, defaultValue);
335    }
336
337    public int getAttributeNameResource(int index) {
338        return mAttrib.getAttributeNameResource(index);
339    }
340
341    public int getAttributeResourceValue(int index, int defaultValue) {
342        return mAttrib.getAttributeResourceValue(index, defaultValue);
343    }
344
345    public int getAttributeResourceValue(String namespace, String attribute, int defaultValue) {
346        return mAttrib.getAttributeResourceValue(namespace, attribute, defaultValue);
347    }
348
349    public int getAttributeUnsignedIntValue(int index, int defaultValue) {
350        return mAttrib.getAttributeUnsignedIntValue(index, defaultValue);
351    }
352
353    public int getAttributeUnsignedIntValue(String namespace, String attribute, int defaultValue) {
354        return mAttrib.getAttributeUnsignedIntValue(namespace, attribute, defaultValue);
355    }
356
357    public String getClassAttribute() {
358        return mAttrib.getClassAttribute();
359    }
360
361    public String getIdAttribute() {
362        return mAttrib.getIdAttribute();
363    }
364
365    public int getIdAttributeResourceValue(int defaultValue) {
366        return mAttrib.getIdAttributeResourceValue(defaultValue);
367    }
368
369    public int getStyleAttribute() {
370        return mAttrib.getStyleAttribute();
371    }
372}
373