001/** 002 * 003 * Copyright 2003-2005 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.jingle.provider; 019 020import org.jivesoftware.smack.SmackException; 021import org.jivesoftware.smack.packet.IQ; 022import org.jivesoftware.smack.provider.IQProvider; 023import org.jivesoftware.smackx.jingle.JingleActionEnum; 024import org.jivesoftware.smackx.jingle.packet.*; 025import org.xmlpull.v1.XmlPullParser; 026 027/** 028 * The JingleProvider parses Jingle packets. 029 * 030 * @author Alvaro Saurin 031 */ 032public class JingleProvider implements IQProvider { 033 034 /** 035 * Creates a new provider. ProviderManager requires that every 036 * PacketExtensionProvider has a public, no-argument constructor 037 */ 038 public JingleProvider() { 039 super(); 040 } 041 042 /** 043 * Parse a iq/jingle element. 044 */ 045 public IQ parseIQ(final XmlPullParser parser) throws Exception { 046 047 Jingle jingle = new Jingle(); 048 String sid = ""; 049 JingleActionEnum action; 050 String initiator = ""; 051 String responder = ""; 052 boolean done = false; 053 JingleContent currentContent = null; 054 055 // Sub-elements providers 056 JingleContentProvider jcp = new JingleContentProvider(); 057 JingleDescriptionProvider jdpAudio = new JingleDescriptionProvider.Audio(); 058 JingleTransportProvider jtpRawUdp = new JingleTransportProvider.RawUdp(); 059 JingleTransportProvider jtpIce = new JingleTransportProvider.Ice(); 060 JingleContentInfoProvider jmipAudio = new JingleContentInfoProvider.Audio(); 061 062 int eventType; 063 String elementName; 064 String namespace; 065 066 // Get some attributes for the <jingle> element 067 sid = parser.getAttributeValue("", "sid"); 068 action = JingleActionEnum.getAction(parser.getAttributeValue("", "action")); 069 initiator = parser.getAttributeValue("", "initiator"); 070 responder = parser.getAttributeValue("", "responder"); 071 072 jingle.setSid(sid); 073 jingle.setAction(action); 074 jingle.setInitiator(initiator); 075 jingle.setResponder(responder); 076 077 // Start processing sub-elements 078 while (!done) { 079 eventType = parser.next(); 080 elementName = parser.getName(); 081 namespace = parser.getNamespace(); 082 083 if (eventType == XmlPullParser.START_TAG) { 084 085 // Parse some well know subelements, depending on the namespaces 086 // and element names... 087 088 if (elementName.equals(JingleContent.NODENAME)) { 089 // Add a new <content> element to the jingle 090 currentContent = (JingleContent) jcp.parseExtension(parser); 091 jingle.addContent(currentContent); 092 } else if (elementName.equals(JingleDescription.NODENAME) && namespace.equals(JingleDescription.Audio.NAMESPACE)) { 093 // Set the <description> element of the <content> 094 currentContent.setDescription((JingleDescription) jdpAudio.parseExtension(parser)); 095 } else if (elementName.equals(JingleTransport.NODENAME)) { 096 // Add all of the <transport> elements to the <content> of the jingle 097 098 // Parse the possible transport namespaces 099 if (namespace.equals(JingleTransport.RawUdp.NAMESPACE)) { 100 currentContent.addJingleTransport((JingleTransport) jtpRawUdp.parseExtension(parser)); 101 } else if (namespace.equals(JingleTransport.Ice.NAMESPACE)) { 102 currentContent.addJingleTransport((JingleTransport) jtpIce.parseExtension(parser)); 103 } else { 104 throw new SmackException("Unknown transport namespace \"" + namespace + "\" in Jingle packet."); 105 } 106 } else if (namespace.equals(JingleContentInfo.Audio.NAMESPACE)) { 107 jingle.setContentInfo((JingleContentInfo) jmipAudio.parseExtension(parser)); 108 } else { 109 throw new SmackException("Unknown combination of namespace \"" + namespace + "\" and element name \"" 110 + elementName + "\" in Jingle packet."); 111 } 112 113 } else if (eventType == XmlPullParser.END_TAG) { 114 if (parser.getName().equals(Jingle.getElementName())) { 115 done = true; 116 } 117 } 118 } 119 120 return jingle; 121 } 122}