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 */ 017package org.jivesoftware.smackx.jingleold.provider; 018 019import java.io.IOException; 020 021import org.jivesoftware.smack.packet.XmlEnvironment; 022import org.jivesoftware.smack.provider.ExtensionElementProvider; 023import org.jivesoftware.smack.xml.XmlPullParser; 024import org.jivesoftware.smack.xml.XmlPullParserException; 025 026import org.jivesoftware.smackx.jingleold.nat.ICECandidate; 027import org.jivesoftware.smackx.jingleold.nat.TransportCandidate; 028import org.jivesoftware.smackx.jingleold.packet.JingleTransport; 029import org.jivesoftware.smackx.jingleold.packet.JingleTransport.JingleTransportCandidate; 030 031/** 032 * Provider for a Jingle transport element. 033 * 034 * @author Alvaro Saurin 035 */ 036public abstract class JingleTransportProvider extends ExtensionElementProvider<JingleTransport> { 037 038 /** 039 * Obtain the corresponding TransportNegotiator instance. 040 * 041 * @return a new TransportNegotiator instance 042 */ 043 protected JingleTransport getInstance() { 044 return new JingleTransport(); 045 } 046 047 /** 048 * Parse a iq/jingle/transport element. 049 * 050 * @param parser the structure to parse 051 * @return a transport element. 052 * @throws IOException if an I/O error occurred. 053 * @throws XmlPullParserException if an error in the XML parser occurred. 054 */ 055 @Override 056 public JingleTransport parse(XmlPullParser parser, int initialDepth, XmlEnvironment xmlEnvironment) throws XmlPullParserException, IOException { 057 JingleTransport trans = getInstance(); 058 059 outerloop: while (true) { 060 XmlPullParser.Event eventType = parser.next(); 061 062 if (eventType == XmlPullParser.Event.START_ELEMENT) { 063 String name = parser.getName(); 064 if (name.equals(JingleTransportCandidate.NODENAME)) { 065 JingleTransportCandidate jtc = parseCandidate(parser); 066 if (jtc != null) trans.addCandidate(jtc); 067 } 068 else { 069 // TODO: Should be SmackParseException. 070 throw new IOException("Unknown tag \"" + name + "\" in transport element."); 071 } 072 } 073 else if (eventType == XmlPullParser.Event.END_ELEMENT) { 074 if (parser.getDepth() == initialDepth) { 075 break outerloop; 076 } 077 } 078 } 079 080 return trans; 081 } 082 083 protected abstract JingleTransportCandidate parseCandidate(XmlPullParser parser); 084 085 /** 086 * RTP-ICE profile. 087 */ 088 public static class Ice extends JingleTransportProvider { 089 090 /** 091 * Default constructor. 092 */ 093 public Ice() { 094 super(); 095 } 096 097 /** 098 * Obtain the corresponding TransportNegotiator.Ice instance. 099 * 100 * @return a new TransportNegotiator.Ice instance 101 */ 102 @Override 103 protected JingleTransport getInstance() { 104 return new JingleTransport.Ice(); 105 } 106 107 /** 108 * Parse a iq/jingle/transport/candidate element. 109 * 110 * @param parser the structure to parse 111 * @return a candidate element 112 */ 113 @Override 114 protected JingleTransportCandidate parseCandidate(XmlPullParser parser) { 115 ICECandidate mt = new ICECandidate(); 116 117 String channel = parser.getAttributeValue("", "channel"); 118 String generation = parser.getAttributeValue("", "generation"); 119 String ip = parser.getAttributeValue("", "ip"); 120 String name = parser.getAttributeValue("", "name"); 121 String network = parser.getAttributeValue("", "network"); 122 String username = parser.getAttributeValue("", "username"); 123 String password = parser.getAttributeValue("", "password"); 124 String port = parser.getAttributeValue("", "port"); 125 String preference = parser.getAttributeValue("", "preference"); 126 String proto = parser.getAttributeValue("", "proto"); 127 String type = parser.getAttributeValue("", "type"); 128 129 if (channel != null) { 130 mt.setChannel(new TransportCandidate.Channel(channel)); 131 } 132 133 if (generation != null) { 134 mt.setGeneration(Integer.parseInt(generation)); 135 } 136 137 if (ip != null) { 138 mt.setIp(ip); 139 } 140 else { 141 return null; 142 } 143 144 if (name != null) { 145 mt.setName(name); 146 } 147 148 if (network != null) { 149 mt.setNetwork(Integer.parseInt(network)); 150 } 151 152 if (username != null) { 153 mt.setUsername(username); 154 } 155 156 if (password != null) { 157 mt.setPassword(password); 158 } 159 160 if (port != null) { 161 mt.setPort(Integer.parseInt(port)); 162 } 163 164 if (preference != null) { 165 mt.setPreference(Integer.parseInt(preference)); 166 } 167 168 if (proto != null) { 169 mt.setProto(new TransportCandidate.Protocol(proto)); 170 } 171 172 if (type != null) { 173 mt.setType(ICECandidate.Type.valueOf(type)); 174 } 175 176 return new JingleTransport.Ice.Candidate(mt); 177 } 178 } 179 180 /** 181 * Raw UDP profile. 182 */ 183 public static class RawUdp extends JingleTransportProvider { 184 185 /** 186 * Default constructor. 187 */ 188 public RawUdp() { 189 super(); 190 } 191 192 /** 193 * Obtain the corresponding TransportNegotiator.RawUdp instance. 194 * 195 * @return a new TransportNegotiator.RawUdp instance 196 */ 197 @Override 198 protected JingleTransport getInstance() { 199 return new JingleTransport.RawUdp(); 200 } 201 202 /** 203 * Parse a iq/jingle/transport/candidate element. 204 * 205 * @param parser the structure to parse 206 * @return a candidate element 207 */ 208 @Override 209 protected JingleTransportCandidate parseCandidate(XmlPullParser parser) { 210 TransportCandidate.Fixed mt = new TransportCandidate.Fixed(); 211 212 String generation = parser.getAttributeValue("", "generation"); 213 String ip = parser.getAttributeValue("", "ip"); 214 String name = parser.getAttributeValue("", "name"); 215 String port = parser.getAttributeValue("", "port"); 216 217 // LOGGER.debug(); 218 219 if (generation != null) { 220 mt.setGeneration(Integer.parseInt(generation)); 221 } 222 223 if (ip != null) { 224 mt.setIp(ip); 225 } 226 227 if (name != null) { 228 mt.setName(name); 229 } 230 231 if (port != null) { 232 mt.setPort(Integer.parseInt(port)); 233 } 234 return new JingleTransport.RawUdp.Candidate(mt); 235 } 236 } 237}