001/**
002 *
003 * Copyright 2019-2021 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;
018
019import java.io.IOException;
020
021import javax.xml.namespace.QName;
022
023/**
024 * Smack's interface for XML pull parsers. The main XML parser implementations are "Xml Pull Parser 3" (XPP3) on Android and "Streaming API for XML" (StAX, JSR 173) on Java.
025 *
026 * <p>
027 * Differences from StAX's XMLStreamReader are:
028 * </p>
029 * <ul>
030 *  <li>{@link #getName()} and {@link #getAttributeName(int)} return localname, there is {@link #getQName()} and {@link #getAttributeQName(int)} to retrieve the qualified name ({@link javax.xml.namespace.QName QName}).</li>
031 *  <li>{@link #nextText()} instead of {@code XMLStreamReader.getElementText()}.
032 * </ul>
033 * <p>
034 * Differences from XPP3's XmlPullParser are:
035 * </p>
036 * <ul>
037 *  <li>Methods taking an attribute, like {@link #getAttributeName(int)} index return <code>null</code> instead of throwing an exception if no attribute with the given index exists.</li>
038 * </ul>
039 *
040 * <h2>Developer Information</h2>
041 * <p>
042 * The following table shows the mapping of Smack's XmlPullParser events to StAX and XPP3 events:
043 * </p>
044 * <table>
045 * <caption>XmlPullParser event mapping</caption>
046 * <tr><th>Smack's {@link XmlPullParser.Event}</th><th>StAX Event</th><th>XPP3 Event</th></tr>
047 * <tr><td>{@link XmlPullParser.Event#START_DOCUMENT}</td><td>START_DOCUMENT (7)</td><td>START_DOCUMENT (0)</td></tr>
048 * <tr><td>{@link XmlPullParser.Event#END_DOCUMENT}</td><td>END_DOCUMENT (8)</td><td>END_DOCUMENT (1)</td></tr>
049 * <tr><td>{@link XmlPullParser.Event#START_ELEMENT}</td><td>START_ELEMENT (1)</td><td>START_TAG (2)</td></tr>
050 * <tr><td>{@link XmlPullParser.Event#END_ELEMENT}</td><td>END_ELEMENT (2)</td><td>END_TAG (3)</td></tr>
051 * <tr><td>{@link XmlPullParser.Event#TEXT_CHARACTERS}</td><td>CHARACTERS (4)</td><td>TEXT (4)</td></tr>
052 * <tr><td>{@link XmlPullParser.Event#PROCESSING_INSTRUCTION}</td><td>PROCESSING_INSTRUCTION (3)</td><td>PROCESSING_INSTRUCTION (8)</td></tr>
053 * <tr><td>{@link XmlPullParser.Event#COMMENT}</td><td>COMMENT (5)</td><td>COMMENT (9)</td></tr>
054 * <tr><td>{@link XmlPullParser.Event#IGNORABLE_WHITESPACE}</td><td>SPACE (6)</td><td>IGNORABLE_WHITESPACE (7)</td></tr>
055 * <tr><td>{@link XmlPullParser.Event#ENTITY_REFERENCE}</td><td>ENTITY_REFERENCE (9)</td><td>ENTITY_REF (6)</td></tr>
056 * <tr><td>{@link XmlPullParser.Event#OTHER}</td><td>ENTITY_REFERENCE (9)</td><td>ENTITY_REF (6)</td></tr>
057 * </table>
058 * <p>{@link XmlPullParser.Event#OTHER} includes
059 * in case of StAX: ATTRIBUTE (10), DTD (11), CDATA (12), NAMESPACE (13), NOTATION_DECLARATION (14) and ENTITY_DECLRATION (15),
060 * in case of XPP3: CDSECT (5), DOCDECL (10).
061 * </p>
062 *
063 */
064public interface XmlPullParser {
065
066    Object getProperty(String name);
067
068    String getInputEncoding();
069
070    int getNamespaceCount() throws XmlPullParserException;
071
072    String getNamespacePrefix(int pos) throws XmlPullParserException;
073
074    String getNamespaceUri(int pos) throws XmlPullParserException;
075
076    String getNamespace(String prefix);
077
078    default String getDefaultNamespace() {
079        return getNamespace(null);
080    }
081
082    int getDepth();
083
084    String getPositionDescription();
085
086    int getLineNumber();
087
088    int getColumnNumber();
089
090    boolean isWhiteSpace() throws XmlPullParserException;
091
092    String getText();
093
094    String getNamespace();
095
096    /**
097     * Return the name for the current START_ELEMENT or END_ELEMENT event. This method must only be called if the
098     * current event is START_ELEMENT or END_ELEMENT.
099     *
100     * @return the name for the current START_ELEMETN or END_ELEMENT event.
101     */
102    String getName();
103
104    QName getQName();
105
106    String getPrefix();
107
108    int getAttributeCount();
109
110    String getAttributeNamespace(int index);
111
112    /**
113     * Returns the loacalpart of the attribute's name or <code>null</code> in case the index does not refer to an
114     * attribute.
115     *
116     * @param index the attribute index.
117     * @return the localpart of the attribute's name or <code>null</code>.
118     */
119    String getAttributeName(int index);
120
121    QName getAttributeQName(int index);
122
123    String getAttributePrefix(int index);
124
125    String getAttributeType(int index);
126
127    String getAttributeValue(int index);
128
129    String getAttributeValue(String namespace, String name);
130
131    default String getAttributeValue(String name) {
132        return getAttributeValue(null, name);
133    }
134
135    Event getEventType() throws XmlPullParserException;
136
137    Event next() throws IOException, XmlPullParserException;
138
139    /**
140     * Reads the content of a text-only element, an exception is thrown if this is
141     * not a text-only element.
142     * <ul>
143     * <li>Precondition: the current event is START_ELEMENT.</li>
144     * <li>Postcondition: the current event is the corresponding END_ELEMENT.</li>
145     * </ul>
146     *
147     * @return the textual content of the current element.
148     * @throws IOException in case of an IO error.
149     * @throws XmlPullParserException in case of an XML pull parser error.
150     */
151    String nextText() throws IOException, XmlPullParserException;
152
153    TagEvent nextTag() throws IOException, XmlPullParserException;
154
155    enum TagEvent {
156        START_ELEMENT,
157        END_ELEMENT,
158    }
159
160    enum Event {
161        START_DOCUMENT,
162        END_DOCUMENT,
163        START_ELEMENT,
164        END_ELEMENT,
165
166        /**
167         * Replaces TEXT from XPP3.
168         */
169        TEXT_CHARACTERS,
170        PROCESSING_INSTRUCTION,
171        COMMENT,
172        IGNORABLE_WHITESPACE,
173        ENTITY_REFERENCE,
174        OTHER,
175    }
176
177    boolean supportsRoundtrip();
178}