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.workgroup.packet; 019 020import java.io.IOException; 021import java.util.HashMap; 022import java.util.List; 023import java.util.Map; 024 025import org.jivesoftware.smack.packet.IQ; 026import org.jivesoftware.smack.packet.XmlEnvironment; 027import org.jivesoftware.smack.parsing.SmackParsingException; 028import org.jivesoftware.smack.provider.IQProvider; 029import org.jivesoftware.smack.util.PacketParserUtils; 030import org.jivesoftware.smack.util.ParserUtils; 031import org.jivesoftware.smack.xml.XmlPullParser; 032import org.jivesoftware.smack.xml.XmlPullParserException; 033 034import org.jivesoftware.smackx.workgroup.MetaData; 035import org.jivesoftware.smackx.workgroup.agent.InvitationRequest; 036import org.jivesoftware.smackx.workgroup.agent.OfferContent; 037import org.jivesoftware.smackx.workgroup.agent.TransferRequest; 038import org.jivesoftware.smackx.workgroup.agent.UserRequest; 039import org.jivesoftware.smackx.workgroup.util.MetaDataUtils; 040 041import org.jxmpp.jid.Jid; 042 043/** 044 * An IQProvider for agent offer requests. 045 * 046 * @author loki der quaeler 047 */ 048public class OfferRequestProvider extends IQProvider<IQ> { 049 // FIXME It seems because OfferRequestPacket is also defined here, we can 050 // not add it as generic to the provider, the provider and the packet should 051 // be split, but since this is legacy code, I don't think that this will 052 // happen anytime soon. 053 054 @Override 055 public OfferRequestPacket parse(XmlPullParser parser, int initialDepth, XmlEnvironment xmlEnvironment) throws XmlPullParserException, IOException, SmackParsingException { 056 XmlPullParser.Event eventType = parser.getEventType(); 057 String sessionID = null; 058 int timeout = -1; 059 OfferContent content = null; 060 boolean done = false; 061 Map<String, List<String>> metaData = new HashMap<>(); 062 063 if (eventType != XmlPullParser.Event.START_ELEMENT) { 064 // throw exception 065 } 066 067 Jid userJID = ParserUtils.getJidAttribute(parser); 068 // Default userID to the JID. 069 Jid userID = userJID; 070 071 while (!done) { 072 eventType = parser.next(); 073 074 if (eventType == XmlPullParser.Event.START_ELEMENT) { 075 String elemName = parser.getName(); 076 077 if ("timeout".equals(elemName)) { 078 timeout = Integer.parseInt(parser.nextText()); 079 } 080 else if (MetaData.ELEMENT_NAME.equals(elemName)) { 081 metaData = MetaDataUtils.parseMetaData(parser); 082 } 083 else if (SessionID.ELEMENT_NAME.equals(elemName)) { 084 sessionID = parser.getAttributeValue("", "id"); 085 } 086 else if (UserID.ELEMENT_NAME.equals(elemName)) { 087 userID = ParserUtils.getJidAttribute(parser, "id"); 088 } 089 else if ("user-request".equals(elemName)) { 090 content = UserRequest.getInstance(); 091 } 092 else if (RoomInvitation.ELEMENT_NAME.equals(elemName)) { 093 RoomInvitation invitation = (RoomInvitation) PacketParserUtils 094 .parseExtensionElement(RoomInvitation.ELEMENT_NAME, RoomInvitation.NAMESPACE, parser, xmlEnvironment); 095 content = new InvitationRequest(invitation.getInviter(), invitation.getRoom(), 096 invitation.getReason()); 097 } 098 else if (RoomTransfer.ELEMENT_NAME.equals(elemName)) { 099 RoomTransfer transfer = (RoomTransfer) PacketParserUtils 100 .parseExtensionElement(RoomTransfer.ELEMENT_NAME, RoomTransfer.NAMESPACE, parser, xmlEnvironment); 101 content = new TransferRequest(transfer.getInviter(), transfer.getRoom(), transfer.getReason()); 102 } 103 } 104 else if (eventType == XmlPullParser.Event.END_ELEMENT) { 105 if ("offer".equals(parser.getName())) { 106 done = true; 107 } 108 } 109 } 110 111 OfferRequestPacket offerRequest = 112 new OfferRequestPacket(userJID, userID, timeout, metaData, sessionID, content); 113 offerRequest.setType(IQ.Type.set); 114 115 return offerRequest; 116 } 117 118 public static class OfferRequestPacket extends IQ { 119 120 public static final String ELEMENT = "offer"; 121 public static final String NAMESPACE = "http://jabber.org/protocol/workgroup"; 122 123 private final int timeout; 124 private final Jid userID; 125 private final Jid userJID; 126 private final Map<String, List<String>> metaData; 127 private final String sessionID; 128 private final OfferContent content; 129 130 public OfferRequestPacket(Jid userJID, Jid userID, int timeout, Map<String, List<String>> metaData, 131 String sessionID, OfferContent content) { 132 super(ELEMENT, NAMESPACE); 133 this.userJID = userJID; 134 this.userID = userID; 135 this.timeout = timeout; 136 this.metaData = metaData; 137 this.sessionID = sessionID; 138 this.content = content; 139 } 140 141 /** 142 * Returns the userID, which is either the same as the userJID or a special 143 * value that the user provided as part of their "join queue" request. 144 * 145 * @return the user ID. 146 */ 147 public Jid getUserID() { 148 return userID; 149 } 150 151 /** 152 * The JID of the user that made the "join queue" request. 153 * 154 * @return the user JID. 155 */ 156 public Jid getUserJID() { 157 return userJID; 158 } 159 160 /** 161 * Returns the session ID associated with the request and ensuing chat. If the offer 162 * does not contain a session ID, <code>null</code> will be returned. 163 * 164 * @return the session id associated with the request. 165 */ 166 public String getSessionID() { 167 return sessionID; 168 } 169 170 /** 171 * Returns the number of seconds the agent has to accept the offer before 172 * it times out. 173 * 174 * @return the offer timeout (in seconds). 175 */ 176 public int getTimeout() { 177 return this.timeout; 178 } 179 180 public OfferContent getContent() { 181 return content; 182 } 183 184 /** 185 * Returns any meta-data associated with the offer. 186 * 187 * @return meta-data associated with the offer. 188 */ 189 public Map<String, List<String>> getMetaData() { 190 return this.metaData; 191 } 192 193 @Override 194 protected IQChildElementXmlStringBuilder getIQChildElementBuilder(IQChildElementXmlStringBuilder buf) { 195 buf.append(" jid=\"").append(userJID).append("\">"); 196 buf.append("<timeout>").append(Integer.toString(timeout)).append("</timeout>"); 197 198 if (sessionID != null) { 199 buf.append('<').append(SessionID.ELEMENT_NAME); 200 buf.append(" session=\""); 201 buf.append(getSessionID()).append("\" xmlns=\""); 202 buf.append(SessionID.NAMESPACE).append("\"/>"); 203 } 204 205 if (metaData != null) { 206 buf.append(MetaDataUtils.serializeMetaData(metaData)); 207 } 208 209 if (userID != null) { 210 buf.append('<').append(UserID.ELEMENT_NAME); 211 buf.append(" id=\""); 212 buf.append(userID).append("\" xmlns=\""); 213 buf.append(UserID.NAMESPACE).append("\"/>"); 214 } 215 216 return buf; 217 } 218 } 219}