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