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}