1 /*
2  * Copyright (C) 2008 The Android Open Source Project
3  *
4  * Licensed under the Eclipse Public License, Version 1.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.eclipse.org/org/documents/epl-v10.php
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 
17 package com.android.ide.eclipse.adt.internal.editors.layout;
18 
19 import com.android.ide.common.rendering.legacy.ILegacyPullParser;
20 
21 import org.xmlpull.v1.XmlPullParserException;
22 
23 import java.io.InputStream;
24 import java.io.Reader;
25 
26 /**
27  * Base implementation of an {@link ILegacyPullParser} for cases where the parser is not sitting
28  * on top of an actual XML file.
29  * <p/>It's designed to work on layout files, and will most likely not work on other resource
30  * files.
31  */
32 public abstract class BasePullParser implements ILegacyPullParser {
33 
34     protected int mParsingState = START_DOCUMENT;
35 
BasePullParser()36     public BasePullParser() {
37     }
38 
39     // --- new methods to override ---
40 
onNextFromStartDocument()41     public abstract void onNextFromStartDocument();
onNextFromStartTag()42     public abstract void onNextFromStartTag();
onNextFromEndTag()43     public abstract void onNextFromEndTag();
44 
45     // --- basic implementation of IXmlPullParser ---
46 
47     @Override
setFeature(String name, boolean state)48     public void setFeature(String name, boolean state) throws XmlPullParserException {
49         if (FEATURE_PROCESS_NAMESPACES.equals(name) && state) {
50             return;
51         }
52         if (FEATURE_REPORT_NAMESPACE_ATTRIBUTES.equals(name) && state) {
53             return;
54         }
55         throw new XmlPullParserException("Unsupported feature: " + name);
56     }
57 
58     @Override
getFeature(String name)59     public boolean getFeature(String name) {
60         if (FEATURE_PROCESS_NAMESPACES.equals(name)) {
61             return true;
62         }
63         if (FEATURE_REPORT_NAMESPACE_ATTRIBUTES.equals(name)) {
64             return true;
65         }
66         return false;
67     }
68 
69     @Override
setProperty(String name, Object value)70     public void setProperty(String name, Object value) throws XmlPullParserException {
71         throw new XmlPullParserException("setProperty() not supported");
72     }
73 
74     @Override
getProperty(String name)75     public Object getProperty(String name) {
76         return null;
77     }
78 
79     @Override
setInput(Reader in)80     public void setInput(Reader in) throws XmlPullParserException {
81         throw new XmlPullParserException("setInput() not supported");
82     }
83 
84     @Override
setInput(InputStream inputStream, String inputEncoding)85     public void setInput(InputStream inputStream, String inputEncoding)
86             throws XmlPullParserException {
87         throw new XmlPullParserException("setInput() not supported");
88     }
89 
90     @Override
defineEntityReplacementText(String entityName, String replacementText)91     public void defineEntityReplacementText(String entityName, String replacementText)
92             throws XmlPullParserException {
93         throw new XmlPullParserException("defineEntityReplacementText() not supported");
94     }
95 
96     @Override
getNamespacePrefix(int pos)97     public String getNamespacePrefix(int pos) throws XmlPullParserException {
98         throw new XmlPullParserException("getNamespacePrefix() not supported");
99     }
100 
101     @Override
getInputEncoding()102     public String getInputEncoding() {
103         return null;
104     }
105 
106     @Override
getNamespace(String prefix)107     public String getNamespace(String prefix) {
108         throw new RuntimeException("getNamespace() not supported");
109     }
110 
111     @Override
getNamespaceCount(int depth)112     public int getNamespaceCount(int depth) throws XmlPullParserException {
113         throw new XmlPullParserException("getNamespaceCount() not supported");
114     }
115 
116     @Override
getNamespaceUri(int pos)117     public String getNamespaceUri(int pos) throws XmlPullParserException {
118         throw new XmlPullParserException("getNamespaceUri() not supported");
119     }
120 
121     @Override
getColumnNumber()122     public int getColumnNumber() {
123         return -1;
124     }
125 
126     @Override
getLineNumber()127     public int getLineNumber() {
128         return -1;
129     }
130 
131     @Override
getAttributeType(int arg0)132     public String getAttributeType(int arg0) {
133         return "CDATA";
134     }
135 
136     @Override
getEventType()137     public int getEventType() {
138         return mParsingState;
139     }
140 
141     @Override
getText()142     public String getText() {
143         return null;
144     }
145 
146     @Override
getTextCharacters(int[] arg0)147     public char[] getTextCharacters(int[] arg0) {
148         return null;
149     }
150 
151     @Override
isAttributeDefault(int arg0)152     public boolean isAttributeDefault(int arg0) {
153         return false;
154     }
155 
156     @Override
isWhitespace()157     public boolean isWhitespace() {
158         return false;
159     }
160 
161     @Override
next()162     public int next() throws XmlPullParserException {
163         switch (mParsingState) {
164             case END_DOCUMENT:
165                 throw new XmlPullParserException("Nothing after the end");
166             case START_DOCUMENT:
167                 onNextFromStartDocument();
168                 break;
169             case START_TAG:
170                 onNextFromStartTag();
171                 break;
172             case END_TAG:
173                 onNextFromEndTag();
174                 break;
175             case TEXT:
176                 // not used
177                 break;
178             case CDSECT:
179                 // not used
180                 break;
181             case ENTITY_REF:
182                 // not used
183                 break;
184             case IGNORABLE_WHITESPACE:
185                 // not used
186                 break;
187             case PROCESSING_INSTRUCTION:
188                 // not used
189                 break;
190             case COMMENT:
191                 // not used
192                 break;
193             case DOCDECL:
194                 // not used
195                 break;
196         }
197 
198         return mParsingState;
199     }
200 
201     @Override
nextTag()202     public int nextTag() throws XmlPullParserException {
203         int eventType = next();
204         if (eventType != START_TAG && eventType != END_TAG) {
205             throw new XmlPullParserException("expected start or end tag", this, null);
206         }
207         return eventType;
208     }
209 
210     @Override
nextText()211     public String nextText() throws XmlPullParserException {
212         if (getEventType() != START_TAG) {
213             throw new XmlPullParserException("parser must be on START_TAG to read next text", this,
214                     null);
215         }
216         int eventType = next();
217         if (eventType == TEXT) {
218             String result = getText();
219             eventType = next();
220             if (eventType != END_TAG) {
221                 throw new XmlPullParserException(
222                         "event TEXT it must be immediately followed by END_TAG", this, null);
223             }
224             return result;
225         } else if (eventType == END_TAG) {
226             return "";
227         } else {
228             throw new XmlPullParserException("parser must be on START_TAG or TEXT to read text",
229                     this, null);
230         }
231     }
232 
233     @Override
nextToken()234     public int nextToken() throws XmlPullParserException {
235         return next();
236     }
237 
238     @Override
require(int type, String namespace, String name)239     public void require(int type, String namespace, String name) throws XmlPullParserException {
240         if (type != getEventType() || (namespace != null && !namespace.equals(getNamespace()))
241                 || (name != null && !name.equals(getName())))
242             throw new XmlPullParserException("expected " + TYPES[type] + getPositionDescription());
243     }
244 }
245