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        boolean done = false;
058        JingleTransport trans = getInstance();
059
060        while (!done) {
061            XmlPullParser.Event eventType = parser.next();
062            String name = parser.getName();
063
064            if (eventType == XmlPullParser.Event.START_ELEMENT) {
065                if (name.equals(JingleTransportCandidate.NODENAME)) {
066                    JingleTransportCandidate jtc = parseCandidate(parser);
067                    if (jtc != null) trans.addCandidate(jtc);
068                }
069                else {
070                    // TODO: Should be SmackParseException.
071                    throw new IOException("Unknown tag \"" + name + "\" in transport element.");
072                }
073            }
074            else if (eventType == XmlPullParser.Event.END_ELEMENT) {
075                if (name.equals(JingleTransport.NODENAME)) {
076                    done = true;
077                }
078            }
079        }
080
081        return trans;
082    }
083
084    protected abstract JingleTransportCandidate parseCandidate(XmlPullParser parser);
085
086    /**
087     * RTP-ICE profile.
088     */
089    public static class Ice extends JingleTransportProvider {
090
091        /**
092         * Defauls constructor.
093         */
094        public Ice() {
095            super();
096        }
097
098        /**
099         * Obtain the corresponding TransportNegotiator.Ice instance.
100         *
101         * @return a new TransportNegotiator.Ice instance
102         */
103        @Override
104        protected JingleTransport getInstance() {
105            return new JingleTransport.Ice();
106        }
107
108        /**
109         * Parse a iq/jingle/transport/candidate element.
110         *
111         * @param parser the structure to parse
112         * @return a candidate element
113         */
114        @Override
115        protected JingleTransportCandidate parseCandidate(XmlPullParser parser) {
116            ICECandidate mt = new ICECandidate();
117
118            String channel = parser.getAttributeValue("", "channel");
119            String generation = parser.getAttributeValue("", "generation");
120            String ip = parser.getAttributeValue("", "ip");
121            String name = parser.getAttributeValue("", "name");
122            String network = parser.getAttributeValue("", "network");
123            String username = parser.getAttributeValue("", "username");
124            String password = parser.getAttributeValue("", "password");
125            String port = parser.getAttributeValue("", "port");
126            String preference = parser.getAttributeValue("", "preference");
127            String proto = parser.getAttributeValue("", "proto");
128            String type = parser.getAttributeValue("", "type");
129
130            if (channel != null) {
131                mt.setChannel(new TransportCandidate.Channel(channel));
132            }
133
134            if (generation != null) {
135                try {
136                    mt.setGeneration(Integer.parseInt(generation));
137                }
138                catch (Exception e) {
139                }
140            }
141
142            if (ip != null) {
143                mt.setIp(ip);
144            }
145            else {
146                return null;
147            }
148
149            if (name != null) {
150                mt.setName(name);
151            }
152
153            if (network != null) {
154                try {
155                    mt.setNetwork(Integer.parseInt(network));
156                }
157                catch (Exception e) {
158                }
159            }
160
161            if (username != null) {
162                mt.setUsername(username);
163            }
164
165            if (password != null) {
166                mt.setPassword(password);
167            }
168
169            if (port != null) {
170                try {
171                    mt.setPort(Integer.parseInt(port));
172                }
173                catch (Exception e) {
174                }
175            }
176
177            if (preference != null) {
178                try {
179                    mt.setPreference(Integer.parseInt(preference));
180                }
181                catch (Exception e) {
182                }
183            }
184
185            if (proto != null) {
186                mt.setProto(new TransportCandidate.Protocol(proto));
187            }
188
189            if (type != null) {
190                mt.setType(ICECandidate.Type.valueOf(type));
191            }
192
193            return new JingleTransport.Ice.Candidate(mt);
194        }
195    }
196
197    /**
198     * Raw UDP profile.
199     */
200    public static class RawUdp extends JingleTransportProvider {
201
202        /**
203         * Defauls constructor.
204         */
205        public RawUdp() {
206            super();
207        }
208
209        /**
210         * Obtain the corresponding TransportNegotiator.RawUdp instance.
211         *
212         * @return a new TransportNegotiator.RawUdp instance
213         */
214        @Override
215        protected JingleTransport getInstance() {
216            return new JingleTransport.RawUdp();
217        }
218
219        /**
220         * Parse a iq/jingle/transport/candidate element.
221         *
222         * @param parser the structure to parse
223         * @return a candidate element
224         */
225        @Override
226        protected JingleTransportCandidate parseCandidate(XmlPullParser parser) {
227            TransportCandidate.Fixed mt = new TransportCandidate.Fixed();
228
229            String generation = parser.getAttributeValue("", "generation");
230            String ip = parser.getAttributeValue("", "ip");
231            String name = parser.getAttributeValue("", "name");
232            String port = parser.getAttributeValue("", "port");
233
234            // LOGGER.debug();
235
236            if (generation != null) {
237                try {
238                    mt.setGeneration(Integer.parseInt(generation));
239                }
240                catch (Exception e) {
241                }
242            }
243
244            if (ip != null) {
245                mt.setIp(ip);
246            }
247
248            if (name != null) {
249                mt.setName(name);
250            }
251
252            if (port != null) {
253                try {
254                    mt.setPort(Integer.parseInt(port));
255                }
256                catch (Exception e) {
257                }
258            }
259            return new JingleTransport.RawUdp.Candidate(mt);
260        }
261    }
262}