001/**
002 *
003 * Copyright 2019 Florian Schmaus
004 *
005 * Licensed under the Apache License, Version 2.0 (the "License");
006 * you may not use this file except in compliance with the License.
007 * You may obtain a copy of the License at
008 *
009 *     http://www.apache.org/licenses/LICENSE-2.0
010 *
011 * Unless required by applicable law or agreed to in writing, software
012 * distributed under the License is distributed on an "AS IS" BASIS,
013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014 * See the License for the specific language governing permissions and
015 * limitations under the License.
016 */
017package org.jivesoftware.smack.xml.xpp3;
018
019import java.io.IOException;
020
021import javax.xml.XMLConstants;
022import javax.xml.namespace.QName;
023
024import org.jivesoftware.smack.xml.XmlPullParser;
025import org.jivesoftware.smack.xml.XmlPullParserException;
026
027public final class Xpp3XmlPullParser implements XmlPullParser {
028
029    private final org.xmlpull.v1.XmlPullParser xpp3XmlPullParser;
030
031    public Xpp3XmlPullParser(org.xmlpull.v1.XmlPullParser xpp3XmlPullParser) {
032        this.xpp3XmlPullParser = xpp3XmlPullParser;
033    }
034
035    @Override
036    public Object getProperty(String name) {
037        return xpp3XmlPullParser.getProperty(name);
038    }
039
040    @Override
041    public String getInputEncoding() {
042        return xpp3XmlPullParser.getInputEncoding();
043    }
044
045    @Override
046    public int getNamespaceCount() throws XmlPullParserException {
047        int depth = xpp3XmlPullParser.getDepth();
048        try {
049            return xpp3XmlPullParser.getNamespaceCount(depth);
050        } catch (org.xmlpull.v1.XmlPullParserException e) {
051            throw new XmlPullParserException(e);
052        }
053    }
054
055    @Override
056    public String getNamespacePrefix(int pos) throws XmlPullParserException {
057        try {
058            return xpp3XmlPullParser.getNamespacePrefix(pos);
059        } catch (org.xmlpull.v1.XmlPullParserException e) {
060            throw new XmlPullParserException(e);
061        }
062    }
063
064    @Override
065    public String getNamespaceUri(int pos) throws XmlPullParserException {
066        try {
067            return xpp3XmlPullParser.getNamespaceUri(pos);
068        } catch (org.xmlpull.v1.XmlPullParserException e) {
069            throw new XmlPullParserException(e);
070        }
071    }
072
073    @Override
074    public String getNamespace(String prefix) {
075        return xpp3XmlPullParser.getNamespace(prefix);
076    }
077
078    @Override
079    public int getDepth() {
080        return xpp3XmlPullParser.getDepth();
081    }
082
083    @Override
084    public String getPositionDescription() {
085        return xpp3XmlPullParser.getPositionDescription();
086    }
087
088    @Override
089    public int getLineNumber() {
090        return xpp3XmlPullParser.getLineNumber();
091    }
092
093    @Override
094    public int getColumnNumber() {
095        return xpp3XmlPullParser.getColumnNumber();
096    }
097
098    @Override
099    public boolean isWhiteSpace() throws XmlPullParserException {
100        try {
101            return xpp3XmlPullParser.isWhitespace();
102        } catch (org.xmlpull.v1.XmlPullParserException e) {
103            throw new XmlPullParserException(e);
104        }
105    }
106
107    @Override
108    public String getText() {
109        return xpp3XmlPullParser.getText();
110    }
111
112    @Override
113    public String getNamespace() {
114        return xpp3XmlPullParser.getNamespace();
115    }
116
117    @Override
118    public String getName() {
119        return xpp3XmlPullParser.getName();
120    }
121
122    @Override
123    public QName getQName() {
124        String localpart = xpp3XmlPullParser.getName();
125        String prefix = xpp3XmlPullParser.getPrefix();
126        prefix = nullValueToDefaultPrefix(prefix);
127        String namespace = xpp3XmlPullParser.getNamespace();
128
129        return new QName(namespace, localpart, prefix);
130    }
131
132    @Override
133    public String getPrefix() {
134        return xpp3XmlPullParser.getPrefix();
135    }
136
137    @Override
138    public int getAttributeCount() {
139        return xpp3XmlPullParser.getAttributeCount();
140    }
141
142    @Override
143    public String getAttributeNamespace(int index) {
144        String namespace;
145        try {
146            namespace = xpp3XmlPullParser.getAttributeNamespace(index);
147        }
148        catch (IndexOutOfBoundsException e) {
149            return null;
150        }
151
152        if (XMLConstants.NULL_NS_URI.equals(namespace)) {
153            namespace = null;
154        }
155        return namespace;
156    }
157
158    @Override
159    public String getAttributeName(int index) {
160        try {
161            return xpp3XmlPullParser.getAttributeName(index);
162        }
163        catch (IndexOutOfBoundsException e) {
164            return null;
165        }
166    }
167
168    @Override
169    public QName getAttributeQName(int index) {
170        String localpart = getAttributeName(index);
171        if (localpart == null) {
172            return null;
173        }
174        String prefix = getAttributePrefix(index);
175        prefix = nullValueToDefaultPrefix(prefix);
176        String namespace = getAttributeNamespace(index);
177        return new QName(namespace, localpart, prefix);
178    }
179
180    @Override
181    public String getAttributePrefix(int index) {
182        String prefix;
183        try {
184            prefix = xpp3XmlPullParser.getAttributePrefix(index);
185        }
186        catch (IndexOutOfBoundsException e) {
187            return null;
188        }
189        prefix = nullValueToDefaultPrefix(prefix);
190        return prefix;
191    }
192
193    @Override
194    public String getAttributeType(int index) {
195        try {
196            return xpp3XmlPullParser.getAttributeType(index);
197        }
198        catch (IndexOutOfBoundsException e) {
199            return null;
200        }
201    }
202
203    @Override
204    public String getAttributeValue(int index) {
205        return xpp3XmlPullParser.getAttributeValue(index);
206    }
207
208    @Override
209    public String getAttributeValue(String namespace, String name) {
210        return xpp3XmlPullParser.getAttributeValue(namespace, name);
211    }
212
213    @Override
214    public Event getEventType() throws XmlPullParserException {
215        int xpp3EventInt;
216        try {
217            xpp3EventInt = xpp3XmlPullParser.getEventType();
218        } catch (org.xmlpull.v1.XmlPullParserException e) {
219            throw new XmlPullParserException(e);
220        }
221        return xpp3EventIntegerToEvent(xpp3EventInt);
222    }
223
224    @Override
225    public Event next() throws IOException, XmlPullParserException {
226        int xpp3EventInt;
227        try {
228            xpp3EventInt = xpp3XmlPullParser.next();
229        } catch (org.xmlpull.v1.XmlPullParserException e) {
230            throw new XmlPullParserException(e);
231        }
232        return xpp3EventIntegerToEvent(xpp3EventInt);
233    }
234
235    @Override
236    public String nextText() throws IOException, XmlPullParserException {
237        try {
238            return xpp3XmlPullParser.nextText();
239        } catch (org.xmlpull.v1.XmlPullParserException e) {
240            throw new XmlPullParserException(e);
241        }
242    }
243
244    @Override
245    public TagEvent nextTag() throws IOException, XmlPullParserException {
246        int xpp3EventInt;
247        try {
248            xpp3EventInt = xpp3XmlPullParser.nextTag();
249        } catch (org.xmlpull.v1.XmlPullParserException e) {
250            throw new XmlPullParserException(e);
251        }
252        switch (xpp3EventInt) {
253        case org.xmlpull.v1.XmlPullParser.START_TAG:
254            return TagEvent.START_ELEMENT;
255        case org.xmlpull.v1.XmlPullParser.END_TAG:
256            return TagEvent.END_ELEMENT;
257        default:
258            throw new AssertionError();
259        }
260    }
261
262    @Override
263    public boolean supportsRoundtrip() {
264        return xpp3XmlPullParser.getFeature(Xpp3XmlPullParserFactory.FEATURE_XML_ROUNDTRIP);
265    }
266
267    private static Event xpp3EventIntegerToEvent(int xpp3EventInt) {
268        switch (xpp3EventInt) {
269        case org.xmlpull.v1.XmlPullParser.START_DOCUMENT:
270            return Event.START_DOCUMENT;
271        case org.xmlpull.v1.XmlPullParser.END_DOCUMENT:
272            return Event.END_DOCUMENT;
273        case org.xmlpull.v1.XmlPullParser.START_TAG:
274            return Event.START_ELEMENT;
275        case org.xmlpull.v1.XmlPullParser.END_TAG:
276            return Event.END_ELEMENT;
277        case org.xmlpull.v1.XmlPullParser.TEXT:
278            return Event.TEXT_CHARACTERS;
279        case org.xmlpull.v1.XmlPullParser.CDSECT:
280            return Event.OTHER;
281        case org.xmlpull.v1.XmlPullParser.ENTITY_REF:
282            return Event.ENTITY_REFERENCE;
283        case org.xmlpull.v1.XmlPullParser.IGNORABLE_WHITESPACE:
284            return Event.IGNORABLE_WHITESPACE;
285        case org.xmlpull.v1.XmlPullParser.PROCESSING_INSTRUCTION:
286            return Event.PROCESSING_INSTRUCTION;
287        case org.xmlpull.v1.XmlPullParser.COMMENT:
288            return Event.COMMENT;
289        case org.xmlpull.v1.XmlPullParser.DOCDECL:
290            return Event.OTHER;
291        default:
292            throw new IllegalArgumentException("Unknown XPP3 event integer: " + xpp3EventInt);
293        }
294    }
295
296    private static String nullValueToDefaultPrefix(String prefix) {
297        if (prefix != null) {
298            return prefix;
299        }
300        return XMLConstants.DEFAULT_NS_PREFIX;
301    }
302}