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