001/** 002 * 003 * Copyright © 2003-2007 Jive Software, 2014-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.roster.provider; 018 019import java.io.IOException; 020 021import org.jivesoftware.smack.packet.IQ; 022import org.jivesoftware.smack.packet.IqData; 023import org.jivesoftware.smack.packet.XmlEnvironment; 024import org.jivesoftware.smack.provider.IqProvider; 025import org.jivesoftware.smack.roster.packet.RosterPacket; 026import org.jivesoftware.smack.util.ParserUtils; 027import org.jivesoftware.smack.xml.XmlPullParser; 028import org.jivesoftware.smack.xml.XmlPullParserException; 029 030import org.jxmpp.jid.BareJid; 031import org.jxmpp.jid.impl.JidCreate; 032 033public class RosterPacketProvider extends IqProvider<RosterPacket> { 034 035 public static final RosterPacketProvider INSTANCE = new RosterPacketProvider(); 036 037 @Override 038 public RosterPacket parse(XmlPullParser parser, int initialDepth, IqData iqData, XmlEnvironment xmlEnvironment) throws XmlPullParserException, IOException { 039 RosterPacket roster = new RosterPacket(); 040 String version = parser.getAttributeValue("", "ver"); 041 roster.setVersion(version); 042 043 outerloop: while (true) { 044 XmlPullParser.Event eventType = parser.next(); 045 switch (eventType) { 046 case START_ELEMENT: 047 String startTag = parser.getName(); 048 switch (startTag) { 049 case "item": 050 RosterPacket.Item item = parseItem(parser); 051 roster.addRosterItem(item); 052 break; 053 } 054 break; 055 case END_ELEMENT: 056 String endTag = parser.getName(); 057 switch (endTag) { 058 case IQ.QUERY_ELEMENT: 059 if (parser.getDepth() == initialDepth) { 060 break outerloop; 061 } 062 } 063 break; 064 default: 065 // Catch all for incomplete switch (MissingCasesInEnumSwitch) statement. 066 break; 067 } 068 } 069 return roster; 070 } 071 072 public static RosterPacket.Item parseItem(XmlPullParser parser) throws XmlPullParserException, IOException { 073 ParserUtils.assertAtStartTag(parser, RosterPacket.Item.ELEMENT); 074 final int initialDepth = parser.getDepth(); 075 String jidString = parser.getAttributeValue("", "jid"); 076 String itemName = parser.getAttributeValue("", "name"); 077 BareJid jid = JidCreate.bareFrom(jidString); 078 079 // Create item. 080 RosterPacket.Item item = new RosterPacket.Item(jid, itemName); 081 // Set status. 082 String ask = parser.getAttributeValue("", "ask"); 083 item.setSubscriptionPending("subscribe".equals(ask)); 084 // Set type. 085 String subscription = parser.getAttributeValue("", "subscription"); 086 RosterPacket.ItemType type = RosterPacket.ItemType.fromString(subscription); 087 item.setItemType(type); 088 // Set approval status. 089 boolean approved = ParserUtils.getBooleanAttribute(parser, "approved", false); 090 item.setApproved(approved); 091 092 outerloop: while (true) { 093 XmlPullParser.Event eventType = parser.next(); 094 switch (eventType) { 095 case START_ELEMENT: 096 String name = parser.getName(); 097 switch (name) { 098 case RosterPacket.Item.GROUP: 099 final String groupName = parser.nextText(); 100 if (groupName != null && groupName.trim().length() > 0) { 101 item.addGroupName(groupName); 102 } 103 break; 104 } 105 break; 106 case END_ELEMENT: 107 if (parser.getDepth() == initialDepth) { 108 break outerloop; 109 } 110 break; 111 default: 112 // Catch all for incomplete switch (MissingCasesInEnumSwitch) statement. 113 break; 114 } 115 } 116 ParserUtils.assertAtEndTag(parser); 117 assert item != null; 118 return item; 119 } 120}