001/** 002 * 003 * Copyright 2003-2007 Jive Software. 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.smackx.vcardtemp.provider; 018 019import org.jivesoftware.smack.SmackException; 020import org.jivesoftware.smack.provider.IQProvider; 021import org.jivesoftware.smackx.vcardtemp.packet.VCard; 022import org.xmlpull.v1.XmlPullParser; 023import org.xmlpull.v1.XmlPullParserException; 024 025import java.io.IOException; 026 027/** 028 * vCard provider. 029 * 030 * @author Gaston Dombiak 031 * @author Derek DeMoro 032 * @author Chris Deering 033 */ 034public class VCardProvider extends IQProvider<VCard> { 035 036 // @formatter:off 037 private static final String[] ADR = new String[] { 038 "POSTAL", 039 "PARCEL", 040 "DOM", 041 "INTL", 042 "PREF", 043 "POBOX", 044 "EXTADR", 045 "STREET", 046 "LOCALITY", 047 "REGION", 048 "PCODE", 049 "CTRY", 050 "FF", 051 }; 052 053 private static final String[] TEL = new String[] { 054 "VOICE", 055 "FAX", 056 "PAGER", 057 "MSG", 058 "CELL", 059 "VIDEO", 060 "BBS", 061 "MODEM", 062 "ISDN", 063 "PCS", 064 "PREF", 065 }; 066 // @formatter:on 067 068 @Override 069 public VCard parse(XmlPullParser parser, int initialDepth) throws XmlPullParserException, IOException, 070 SmackException { 071 VCard vCard = new VCard(); 072 String name = null; 073 074 outerloop: while (true) { 075 int eventType = parser.next(); 076 switch (eventType) { 077 case XmlPullParser.START_TAG: 078 name = parser.getName(); 079 switch (name) { 080 case "N": 081 parseName(parser, vCard); 082 break; 083 case "ORG": 084 parseOrg(parser, vCard); 085 break; 086 case "TEL": 087 parseTel(parser, vCard); 088 break; 089 case "ADR": 090 parseAddress(parser, vCard); 091 break; 092 case "EMAIL": 093 parseEmail(parser, vCard); 094 break; 095 case "NICKNAME": 096 vCard.setNickName(parser.nextText()); 097 break; 098 case "JABBERID": 099 vCard.setJabberId(parser.nextText()); 100 break; 101 case "PHOTO": 102 parsePhoto(parser, vCard); 103 break; 104 default: 105 break; 106 } 107 break; 108 case XmlPullParser.TEXT: 109 if (initialDepth + 1 == parser.getDepth()) { 110 vCard.setField(name, parser.getText()); 111 } 112 break; 113 case XmlPullParser.END_TAG: 114 if (parser.getDepth() == initialDepth) { 115 break outerloop; 116 } 117 break; 118 default: 119 break; 120 } 121 } 122 123 return vCard; 124 } 125 126 private static void parseAddress(XmlPullParser parser, VCard vCard) throws XmlPullParserException, IOException { 127 final int initialDepth = parser.getDepth(); 128 boolean isWork = true; 129 outerloop: while (true) { 130 int eventType = parser.next(); 131 switch (eventType) { 132 case XmlPullParser.START_TAG: 133 String name = parser.getName(); 134 if ("HOME".equals(name)) { 135 isWork = false; 136 } 137 else { 138 for (String adr : ADR) { 139 if (adr.equals(name)) { 140 if (isWork) { 141 vCard.setAddressFieldWork(name, parser.nextText()); 142 } 143 else { 144 vCard.setAddressFieldHome(name, parser.nextText()); 145 } 146 } 147 } 148 } 149 break; 150 case XmlPullParser.END_TAG: 151 if (parser.getDepth() == initialDepth) { 152 break outerloop; 153 } 154 break; 155 default: 156 break; 157 } 158 } 159 } 160 161 private static void parseTel(XmlPullParser parser, VCard vCard) throws XmlPullParserException, IOException { 162 final int initialDepth = parser.getDepth(); 163 boolean isWork = true; 164 String telLabel = null; 165 166 outerloop: while (true) { 167 int eventType = parser.next(); 168 switch (eventType) { 169 case XmlPullParser.START_TAG: 170 String name = parser.getName(); 171 if ("HOME".equals(name)) { 172 isWork = false; 173 } 174 else { 175 if (telLabel != null && "NUMBER".equals(name)) { 176 if (isWork) { 177 vCard.setPhoneWork(telLabel, parser.nextText()); 178 } 179 else { 180 vCard.setPhoneHome(telLabel, parser.nextText()); 181 } 182 } 183 else { 184 for (String tel : TEL) { 185 if (tel.equals(name)) { 186 telLabel = name; 187 } 188 } 189 } 190 } 191 break; 192 case XmlPullParser.END_TAG: 193 if (parser.getDepth() == initialDepth) { 194 break outerloop; 195 } 196 break; 197 default: 198 break; 199 } 200 } 201 } 202 203 private static void parseOrg(XmlPullParser parser, VCard vCard) throws XmlPullParserException, IOException { 204 final int initialDepth = parser.getDepth(); 205 206 outerloop: while (true) { 207 int eventType = parser.next(); 208 switch (eventType) { 209 case XmlPullParser.START_TAG: 210 String name = parser.getName(); 211 switch (name) { 212 case "ORGNAME": 213 vCard.setOrganization(parser.nextText()); 214 break; 215 case "ORGUNIT": 216 vCard.setOrganizationUnit(parser.nextText()); 217 break; 218 default: 219 break; 220 } 221 break; 222 case XmlPullParser.END_TAG: 223 if (parser.getDepth() == initialDepth) { 224 break outerloop; 225 } 226 break; 227 default: 228 break; 229 } 230 } 231 } 232 233 private static void parseEmail(XmlPullParser parser, VCard vCard) throws XmlPullParserException, IOException { 234 final int initialDepth = parser.getDepth(); 235 boolean isWork = false; 236 237 outerloop: while (true) { 238 int eventType = parser.next(); 239 switch (eventType) { 240 case XmlPullParser.START_TAG: 241 String name = parser.getName(); 242 switch (name) { 243 case "WORK": 244 isWork = true; 245 break; 246 case "USERID": 247 if (isWork) { 248 vCard.setEmailWork(parser.nextText()); 249 } 250 else { 251 vCard.setEmailHome(parser.nextText()); 252 } 253 break; 254 default: 255 break; 256 } 257 break; 258 case XmlPullParser.END_TAG: 259 if (parser.getDepth() == initialDepth) { 260 break outerloop; 261 } 262 break; 263 default: 264 break; 265 } 266 } 267 } 268 269 private static void parseName(XmlPullParser parser, VCard vCard) throws XmlPullParserException, IOException { 270 final int initialDepth = parser.getDepth(); 271 272 outerloop: while (true) { 273 int eventType = parser.next(); 274 switch (eventType) { 275 case XmlPullParser.START_TAG: 276 String name = parser.getName(); 277 switch (name) { 278 case "FAMILY": 279 vCard.setLastName(parser.nextText()); 280 break; 281 case "GIVEN": 282 vCard.setFirstName(parser.nextText()); 283 break; 284 case "MIDDLE": 285 vCard.setMiddleName(parser.nextText()); 286 break; 287 case "PREFIX": 288 vCard.setPrefix(parser.nextText()); 289 break; 290 case "SUFFIX": 291 vCard.setSuffix(parser.nextText()); 292 break; 293 default: 294 break; 295 } 296 break; 297 case XmlPullParser.END_TAG: 298 if (parser.getDepth() == initialDepth) { 299 break outerloop; 300 } 301 break; 302 default: 303 break; 304 305 } 306 } 307 } 308 309 private static void parsePhoto(XmlPullParser parser, VCard vCard) throws XmlPullParserException, IOException { 310 final int initialDepth = parser.getDepth(); 311 String binval = null; 312 String mimetype = null; 313 314 outerloop: while (true) { 315 int eventType = parser.next(); 316 switch (eventType) { 317 case XmlPullParser.START_TAG: 318 String name = parser.getName(); 319 switch (name) { 320 case "BINVAL": 321 binval = parser.nextText(); 322 break; 323 case "TYPE": 324 mimetype = parser.nextText(); 325 break; 326 default: 327 break; 328 } 329 break; 330 case XmlPullParser.END_TAG: 331 if (parser.getDepth() == initialDepth) { 332 break outerloop; 333 } 334 break; 335 default: 336 break; 337 } 338 } 339 340 if (binval == null || mimetype == null) { 341 return; 342 } 343 344 vCard.setAvatar(binval, mimetype); 345 } 346}