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 * Prase a string to a boolean value as per "xs:boolean". Valid input strings are "true", "1" for true, and "false", "0" for false. 134 * 135 * @param booleanString the input string. 136 * @return the boolean representation of the input string 137 * @throws IllegalArgumentException if the input string is not valid. 138 * @since 4.3.2 139 */ 140 public static boolean parseXmlBoolean(String booleanString) { 141 switch (booleanString) { 142 case "true": 143 case "1": 144 return true; 145 case "false": 146 case "0": 147 return false; 148 default: 149 throw new IllegalArgumentException(booleanString + " is not a valid boolean string"); 150 } 151 } 152 153 /** 154 * Get the boolean value of an argument. 155 * 156 * @param parser 157 * @param name 158 * @return the boolean value or null of no argument of the given name exists 159 */ 160 public static Boolean getBooleanAttribute(XmlPullParser parser, String name) { 161 String valueString = parser.getAttributeValue("", name); 162 if (valueString == null) 163 return null; 164 valueString = valueString.toLowerCase(Locale.US); 165 return parseXmlBoolean(valueString); 166 } 167 168 public static boolean getBooleanAttribute(XmlPullParser parser, String name, 169 boolean defaultValue) { 170 Boolean bool = getBooleanAttribute(parser, name); 171 if (bool == null) { 172 return defaultValue; 173 } 174 else { 175 return bool; 176 } 177 } 178 179 public static int getIntegerAttributeOrThrow(XmlPullParser parser, String name, String throwMessage) throws SmackException { 180 Integer res = getIntegerAttribute(parser, name); 181 if (res == null) { 182 throw new SmackException(throwMessage); 183 } 184 return res; 185 } 186 187 public static Integer getIntegerAttribute(XmlPullParser parser, String name) { 188 String valueString = parser.getAttributeValue("", name); 189 if (valueString == null) 190 return null; 191 return Integer.valueOf(valueString); 192 } 193 194 public static int getIntegerAttribute(XmlPullParser parser, String name, int defaultValue) { 195 Integer integer = getIntegerAttribute(parser, name); 196 if (integer == null) { 197 return defaultValue; 198 } 199 else { 200 return integer; 201 } 202 } 203 204 public static int getIntegerFromNextText(XmlPullParser parser) throws XmlPullParserException, IOException { 205 String intString = parser.nextText(); 206 return Integer.valueOf(intString); 207 } 208 209 public static Long getLongAttribute(XmlPullParser parser, String name) { 210 String valueString = parser.getAttributeValue("", name); 211 if (valueString == null) 212 return null; 213 return Long.valueOf(valueString); 214 } 215 216 public static long getLongAttribute(XmlPullParser parser, String name, long defaultValue) { 217 Long l = getLongAttribute(parser, name); 218 if (l == null) { 219 return defaultValue; 220 } 221 else { 222 return l; 223 } 224 } 225 226 public static double getDoubleFromNextText(XmlPullParser parser) throws XmlPullParserException, IOException { 227 String doubleString = parser.nextText(); 228 return Double.valueOf(doubleString); 229 } 230 231 public static Double getDoubleAttribute(XmlPullParser parser, String name) { 232 String valueString = parser.getAttributeValue("", name); 233 if (valueString == null) 234 return null; 235 return Double.valueOf(valueString); 236 } 237 238 public static double getDoubleAttribute(XmlPullParser parser, String name, long defaultValue) { 239 Double d = getDoubleAttribute(parser, name); 240 if (d == null) { 241 return defaultValue; 242 } 243 else { 244 return d; 245 } 246 } 247 248 public static Date getDateFromNextText(XmlPullParser parser) throws XmlPullParserException, IOException, ParseException { 249 String dateString = parser.nextText(); 250 return XmppDateTime.parseDate(dateString); 251 } 252 253 public static URI getUriFromNextText(XmlPullParser parser) throws XmlPullParserException, IOException, URISyntaxException { 254 String uriString = parser.nextText(); 255 return new URI(uriString); 256 } 257 258 public static String getRequiredAttribute(XmlPullParser parser, String name) throws IOException { 259 String value = parser.getAttributeValue("", name); 260 if (StringUtils.isNullOrEmpty(value)) { 261 throw new IOException("Attribute " + name + " is null or empty (" + value + ')'); 262 } 263 return value; 264 } 265 266 public static String getRequiredNextText(XmlPullParser parser) throws XmlPullParserException, IOException { 267 String text = parser.nextText(); 268 if (StringUtils.isNullOrEmpty(text)) { 269 throw new IOException("Next text is null or empty (" + text + ')'); 270 } 271 return text; 272 } 273 274 public static String getXmlLang(XmlPullParser parser) { 275 return parser.getAttributeValue("http://www.w3.org/XML/1998/namespace", "lang"); 276 } 277 278 public static QName getQName(XmlPullParser parser) { 279 String elementName = parser.getName(); 280 String prefix = parser.getPrefix(); 281 if (prefix == null) { 282 prefix = XMLConstants.DEFAULT_NS_PREFIX; 283 } 284 String namespace = parser.getNamespace(); 285 return new QName(namespace, elementName, prefix); 286 } 287}