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         * Defauls 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                try {
135                    mt.setGeneration(Integer.parseInt(generation));
136                }
137                catch (Exception e) {
138                }
139            }
140
141            if (ip != null) {
142                mt.setIp(ip);
143            }
144            else {
145                return null;
146            }
147
148            if (name != null) {
149                mt.setName(name);
150            }
151
152            if (network != null) {
153                try {
154                    mt.setNetwork(Integer.parseInt(network));
155                }
156                catch (Exception e) {
157                }
158            }
159
160            if (username != null) {
161                mt.setUsername(username);
162            }
163
164            if (password != null) {
165                mt.setPassword(password);
166            }
167
168            if (port != null) {
169                try {
170                    mt.setPort(Integer.parseInt(port));
171                }
172                catch (Exception e) {
173                }
174            }
175
176            if (preference != null) {
177                try {
178                    mt.setPreference(Integer.parseInt(preference));
179                }
180                catch (Exception e) {
181                }
182            }
183
184            if (proto != null) {
185                mt.setProto(new TransportCandidate.Protocol(proto));
186            }
187
188            if (type != null) {
189                mt.setType(ICECandidate.Type.valueOf(type));
190            }
191
192            return new JingleTransport.Ice.Candidate(mt);
193        }
194    }
195
196    /**
197     * Raw UDP profile.
198     */
199    public static class RawUdp extends JingleTransportProvider {
200
201        /**
202         * Defauls constructor.
203         */
204        public RawUdp() {
205            super();
206        }
207
208        /**
209         * Obtain the corresponding TransportNegotiator.RawUdp instance.
210         *
211         * @return a new TransportNegotiator.RawUdp instance
212         */
213        @Override
214        protected JingleTransport getInstance() {
215            return new JingleTransport.RawUdp();
216        }
217
218        /**
219         * Parse a iq/jingle/transport/candidate element.
220         *
221         * @param parser the structure to parse
222         * @return a candidate element
223         */
224        @Override
225        protected JingleTransportCandidate parseCandidate(XmlPullParser parser) {
226            TransportCandidate.Fixed mt = new TransportCandidate.Fixed();
227
228            String generation = parser.getAttributeValue("", "generation");
229            String ip = parser.getAttributeValue("", "ip");
230            String name = parser.getAttributeValue("", "name");
231            String port = parser.getAttributeValue("", "port");
232
233            // LOGGER.debug();
234
235            if (generation != null) {
236                try {
237                    mt.setGeneration(Integer.parseInt(generation));
238                }
239                catch (Exception e) {
240                }
241            }
242
243            if (ip != null) {
244                mt.setIp(ip);
245            }
246
247            if (name != null) {
248                mt.setName(name);
249            }
250
251            if (port != null) {
252                try {
253                    mt.setPort(Integer.parseInt(port));
254                }
255                catch (Exception e) {
256                }
257            }
258            return new JingleTransport.RawUdp.Candidate(mt);
259        }
260    }
261}