001/**
002 *
003 * Copyright © 2014-2018 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.util;
018
019import java.io.IOException;
020import java.net.URI;
021import java.net.URISyntaxException;
022import java.text.ParseException;
023import java.util.Date;
024import java.util.Locale;
025
026import javax.xml.XMLConstants;
027import javax.xml.namespace.QName;
028
029import org.jivesoftware.smack.SmackException;
030
031import org.jxmpp.jid.EntityBareJid;
032import org.jxmpp.jid.EntityFullJid;
033import org.jxmpp.jid.EntityJid;
034import org.jxmpp.jid.Jid;
035import org.jxmpp.jid.impl.JidCreate;
036import org.jxmpp.jid.parts.Resourcepart;
037import org.jxmpp.stringprep.XmppStringprepException;
038import org.jxmpp.util.XmppDateTime;
039import org.xmlpull.v1.XmlPullParser;
040import org.xmlpull.v1.XmlPullParserException;
041
042public class ParserUtils {
043
044    /**
045     * The constant String "jid".
046     */
047    public static final String JID = "jid";
048
049    public static void assertAtStartTag(XmlPullParser parser) throws XmlPullParserException {
050        assert (parser.getEventType() == XmlPullParser.START_TAG);
051    }
052
053    public static void assertAtStartTag(XmlPullParser parser, String name) throws XmlPullParserException {
054        assertAtStartTag(parser);
055        assert name.equals(parser.getName());
056    }
057
058    public static void assertAtEndTag(XmlPullParser parser) throws XmlPullParserException {
059        assert (parser.getEventType() == XmlPullParser.END_TAG);
060    }
061
062    public static void forwardToEndTagOfDepth(XmlPullParser parser, int depth)
063                    throws XmlPullParserException, IOException {
064        int event = parser.getEventType();
065        while (!(event == XmlPullParser.END_TAG && parser.getDepth() == depth)) {
066            event = parser.next();
067        }
068    }
069
070    public static Jid getJidAttribute(XmlPullParser parser) throws XmppStringprepException {
071        return getJidAttribute(parser, JID);
072    }
073
074    public static Jid getJidAttribute(XmlPullParser parser, String name) throws XmppStringprepException {
075        final String jidString = parser.getAttributeValue("", name);
076        if (jidString == null) {
077            return null;
078        }
079        return JidCreate.from(jidString);
080    }
081
082    public static EntityBareJid getBareJidAttribute(XmlPullParser parser) throws XmppStringprepException {
083        return getBareJidAttribute(parser, JID);
084    }
085
086    public static EntityBareJid getBareJidAttribute(XmlPullParser parser, String name) throws XmppStringprepException {
087        final String jidString = parser.getAttributeValue("", name);
088        if (jidString == null) {
089            return null;
090        }
091        return JidCreate.entityBareFrom(jidString);
092    }
093
094    public static EntityFullJid getFullJidAttribute(XmlPullParser parser) throws XmppStringprepException {
095        return getFullJidAttribute(parser, JID);
096    }
097
098    public static EntityFullJid getFullJidAttribute(XmlPullParser parser, String name) throws XmppStringprepException {
099        final String jidString = parser.getAttributeValue("", name);
100        if (jidString == null) {
101            return null;
102        }
103        return JidCreate.entityFullFrom(jidString);
104    }
105
106    public static EntityJid getEntityJidAttribute(XmlPullParser parser, String name) throws XmppStringprepException {
107        final String jidString = parser.getAttributeValue("", name);
108        if (jidString == null) {
109            return null;
110        }
111        Jid jid = JidCreate.from(jidString);
112
113        if (!jid.hasLocalpart()) return null;
114
115        EntityFullJid fullJid = jid.asEntityFullJidIfPossible();
116        if (fullJid != null) {
117            return fullJid;
118        }
119
120        EntityBareJid bareJid = jid.asEntityBareJidIfPossible();
121        return bareJid;
122    }
123
124    public static Resourcepart getResourcepartAttribute(XmlPullParser parser, String name) throws XmppStringprepException {
125        final String resourcepartString = parser.getAttributeValue("", name);
126        if (resourcepartString == null) {
127            return null;
128        }
129        return Resourcepart.from(resourcepartString);
130    }
131
132    /**
133     * Get the boolean value of an argument.
134     *
135     * @param parser
136     * @param name
137     * @return the boolean value or null of no argument of the given name exists
138     */
139    public static Boolean getBooleanAttribute(XmlPullParser parser, String name) {
140        String valueString = parser.getAttributeValue("", name);
141        if (valueString == null)
142            return null;
143        valueString = valueString.toLowerCase(Locale.US);
144        return valueString.equals("true") || valueString.equals("0");
145    }
146
147    public static boolean getBooleanAttribute(XmlPullParser parser, String name,
148                    boolean defaultValue) {
149        Boolean bool = getBooleanAttribute(parser, name);
150        if (bool == null) {
151            return defaultValue;
152        }
153        else {
154            return bool;
155        }
156    }
157
158    public static int getIntegerAttributeOrThrow(XmlPullParser parser, String name, String throwMessage) throws SmackException {
159        Integer res = getIntegerAttribute(parser, name);
160        if (res == null) {
161            throw new SmackException(throwMessage);
162        }
163        return res;
164    }
165
166    public static Integer getIntegerAttribute(XmlPullParser parser, String name) {
167        String valueString = parser.getAttributeValue("", name);
168        if (valueString == null)
169            return null;
170        return Integer.valueOf(valueString);
171    }
172
173    public static int getIntegerAttribute(XmlPullParser parser, String name, int defaultValue) {
174        Integer integer = getIntegerAttribute(parser, name);
175        if (integer == null) {
176            return defaultValue;
177        }
178        else {
179            return integer;
180        }
181    }
182
183    public static int getIntegerFromNextText(XmlPullParser parser) throws XmlPullParserException, IOException {
184        String intString = parser.nextText();
185        return Integer.valueOf(intString);
186    }
187
188    public static Long getLongAttribute(XmlPullParser parser, String name) {
189        String valueString = parser.getAttributeValue("", name);
190        if (valueString == null)
191            return null;
192        return Long.valueOf(valueString);
193    }
194
195    public static long getLongAttribute(XmlPullParser parser, String name, long defaultValue) {
196        Long l = getLongAttribute(parser, name);
197        if (l == null) {
198            return defaultValue;
199        }
200        else {
201            return l;
202        }
203    }
204
205    public static double getDoubleFromNextText(XmlPullParser parser) throws XmlPullParserException, IOException {
206        String doubleString = parser.nextText();
207        return Double.valueOf(doubleString);
208    }
209
210    public static Double getDoubleAttribute(XmlPullParser parser, String name) {
211        String valueString = parser.getAttributeValue("", name);
212        if (valueString == null)
213            return null;
214        return Double.valueOf(valueString);
215    }
216
217    public static double getDoubleAttribute(XmlPullParser parser, String name, long defaultValue) {
218        Double d = getDoubleAttribute(parser, name);
219        if (d == null) {
220            return defaultValue;
221        }
222        else {
223            return d;
224        }
225    }
226
227    public static Date getDateFromNextText(XmlPullParser parser) throws XmlPullParserException, IOException, ParseException {
228        String dateString = parser.nextText();
229        return XmppDateTime.parseDate(dateString);
230    }
231
232    public static URI getUriFromNextText(XmlPullParser parser) throws XmlPullParserException, IOException, URISyntaxException  {
233        String uriString = parser.nextText();
234        return new URI(uriString);
235    }
236
237    public static String getRequiredAttribute(XmlPullParser parser, String name) throws IOException {
238        String value = parser.getAttributeValue("", name);
239        if (StringUtils.isNullOrEmpty(value)) {
240            throw new IOException("Attribute " + name + " is null or empty (" + value + ')');
241        }
242        return value;
243    }
244
245    public static String getRequiredNextText(XmlPullParser parser) throws XmlPullParserException, IOException {
246        String text = parser.nextText();
247        if (StringUtils.isNullOrEmpty(text)) {
248            throw new IOException("Next text is null or empty (" + text + ')');
249        }
250        return text;
251    }
252
253    public static String getXmlLang(XmlPullParser parser) {
254        return parser.getAttributeValue("http://www.w3.org/XML/1998/namespace", "lang");
255    }
256
257    public static QName getQName(XmlPullParser parser) {
258        String elementName = parser.getName();
259        String prefix = parser.getPrefix();
260        if (prefix == null) {
261            prefix = XMLConstants.DEFAULT_NS_PREFIX;
262        }
263        String namespace = parser.getNamespace();
264        return new QName(namespace, elementName, prefix);
265    }
266}