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 */
017
018package org.jivesoftware.smackx.muc.provider;
019
020import java.io.IOException;
021
022import org.jivesoftware.smack.packet.XmlEnvironment;
023import org.jivesoftware.smack.provider.ExtensionElementProvider;
024import org.jivesoftware.smack.util.ParserUtils;
025import org.jivesoftware.smack.xml.XmlPullParser;
026import org.jivesoftware.smack.xml.XmlPullParserException;
027
028import org.jivesoftware.smackx.muc.packet.MUCUser;
029
030import org.jxmpp.JxmppContext;
031import org.jxmpp.jid.EntityBareJid;
032import org.jxmpp.jid.EntityJid;
033
034/**
035 * The MUCUserProvider parses packets with extended presence information about
036 * roles and affiliations.
037 *
038 * @author Gaston Dombiak
039 */
040public class MUCUserProvider extends ExtensionElementProvider<MUCUser> {
041
042    /**
043     * Parses a MUCUser stanza (extension sub-packet).
044     *
045     * @param parser the XML parser, positioned at the starting element of the extension.
046     * @return a PacketExtension.
047     * @throws IOException if an I/O error occurred.
048     * @throws XmlPullParserException if an error in the XML parser occurred.
049     */
050    @Override
051    public MUCUser parse(XmlPullParser parser, int initialDepth, XmlEnvironment xmlEnvironment, JxmppContext jxmppContext) throws XmlPullParserException, IOException {
052        MUCUser mucUser = new MUCUser();
053        outerloop: while (true) {
054            switch (parser.next()) {
055            case START_ELEMENT:
056                switch (parser.getName()) {
057                case "invite":
058                    var invite = parseInvite(parser, jxmppContext);
059                    mucUser.setInvite(invite);
060                    break;
061                case "item":
062                    var item = MUCParserUtils.parseItem(parser, jxmppContext);
063                    mucUser.setItem(item);
064                    break;
065                case "password":
066                    mucUser.setPassword(parser.nextText());
067                    break;
068                case "status":
069                    String statusString = parser.getAttributeValue("", "code");
070                    mucUser.addStatusCode(MUCUser.Status.create(statusString));
071                    break;
072                case "decline":
073                    var decline = parseDecline(parser, jxmppContext);
074                    mucUser.setDecline(decline);
075                    break;
076                case "destroy":
077                    var destroy = MUCParserUtils.parseDestroy(parser, jxmppContext);
078                    mucUser.setDestroy(destroy);
079                    break;
080                }
081                break;
082            case END_ELEMENT:
083                if (parser.getDepth() == initialDepth) {
084                    break outerloop;
085                }
086                break;
087            default:
088                // Catch all for incomplete switch (MissingCasesInEnumSwitch) statement.
089                break;
090            }
091        }
092
093        return mucUser;
094    }
095
096    private static MUCUser.Invite parseInvite(XmlPullParser parser, JxmppContext jxmppContext) throws XmlPullParserException, IOException {
097        String reason = null;
098        EntityBareJid to = ParserUtils.getBareJidAttribute(parser, "to", jxmppContext);
099        EntityJid from = ParserUtils.getEntityJidAttribute(parser, "from", jxmppContext);
100
101        outerloop: while (true) {
102            XmlPullParser.Event eventType = parser.next();
103            if (eventType == XmlPullParser.Event.START_ELEMENT) {
104                if (parser.getName().equals("reason")) {
105                    reason = parser.nextText();
106                }
107            }
108            else if (eventType == XmlPullParser.Event.END_ELEMENT) {
109                if (parser.getName().equals("invite")) {
110                    break outerloop;
111                }
112            }
113        }
114        return new MUCUser.Invite(reason, from, to);
115    }
116
117    private static MUCUser.Decline parseDecline(XmlPullParser parser, JxmppContext jxmppContext) throws XmlPullParserException, IOException {
118        String reason = null;
119        EntityBareJid to = ParserUtils.getBareJidAttribute(parser, "to", jxmppContext);
120        EntityBareJid from = ParserUtils.getBareJidAttribute(parser, "from", jxmppContext);
121
122        outerloop: while (true) {
123            XmlPullParser.Event eventType = parser.next();
124            if (eventType == XmlPullParser.Event.START_ELEMENT) {
125                if (parser.getName().equals("reason")) {
126                    reason = parser.nextText();
127                }
128            }
129            else if (eventType == XmlPullParser.Event.END_ELEMENT) {
130                if (parser.getName().equals("decline")) {
131                    break outerloop;
132                }
133            }
134        }
135        return new MUCUser.Decline(reason, from, to);
136    }
137}