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.jingle.packet;
018
019import java.util.ArrayList;
020import java.util.Collections;
021import java.util.Iterator;
022import java.util.List;
023import java.util.logging.Logger;
024
025import org.jivesoftware.smack.packet.PacketExtension;
026import org.jivesoftware.smackx.jingle.media.PayloadType;
027
028/**
029 * Jingle content description.
030 *
031 * @author Alvaro Saurin <alvaro.saurin@gmail.com>
032 */
033public abstract class JingleDescription implements PacketExtension {
034
035        private static final Logger LOGGER = Logger.getLogger(JingleDescription.class.getName());
036
037        // static
038
039    public static final String NODENAME = "description";
040
041    // non-static
042
043    private final List<PayloadType> payloads = new ArrayList<PayloadType>();
044
045    /**
046     * Creates a content description..
047     */
048    public JingleDescription() {
049        super();
050    }
051
052    /**
053     * Returns the XML element name of the element.
054     *
055     * @return the XML element name of the element.
056     */
057    public String getElementName() {
058        return NODENAME;
059    }
060
061    /**
062     * Return the namespace.
063     *
064     * @return The namespace
065     */
066    public abstract String getNamespace();
067
068    /**
069     * Adds a audio payload type to the packet.
070     *
071     * @param pt the audio payload type to add.
072     */
073    public void addPayloadType(final PayloadType pt) {
074        synchronized (payloads) {
075            if (pt == null) {
076                LOGGER.severe("Null payload type");
077            } else {
078                payloads.add(pt);
079            }
080        }
081    }
082
083    /**
084     * Adds a list of payloads to the packet.
085     *
086     * @param pts the payloads to add.
087     */
088    public void addAudioPayloadTypes(final List<PayloadType> pts) {
089        synchronized (payloads) {
090            Iterator<PayloadType> ptIter = pts.iterator();
091            while (ptIter.hasNext()) {
092                PayloadType.Audio pt = (PayloadType.Audio) ptIter.next();
093                addPayloadType(new PayloadType.Audio(pt));
094            }
095        }
096    }
097
098    /**
099     * Returns an Iterator for the audio payloads in the packet.
100     *
101     * @return an Iterator for the audio payloads in the packet.
102     */
103    public Iterator<PayloadType> getPayloadTypes() {
104        return Collections.unmodifiableList(getPayloadTypesList()).iterator();
105    }
106
107    /**
108     * Returns a list for the audio payloads in the packet.
109     *
110     * @return a list for the audio payloads in the packet.
111     */
112    public List<PayloadType> getPayloadTypesList() {
113        synchronized (payloads) {
114            return new ArrayList<PayloadType>(payloads);
115        }
116    }
117
118    /**
119     * Return the list of Payload types contained in the description.
120     *
121     * @return a list of PayloadType.Audio
122     */
123    public List<PayloadType> getAudioPayloadTypesList() {
124        ArrayList<PayloadType> result = new ArrayList<PayloadType>();
125        Iterator<PayloadType> jinglePtsIter = getPayloadTypes();
126
127        while (jinglePtsIter.hasNext()) {
128            PayloadType jpt = (PayloadType) jinglePtsIter.next();
129            if (jpt instanceof PayloadType.Audio) {
130                PayloadType.Audio jpta = (PayloadType.Audio) jpt;
131                result.add(jpta);
132            }
133        }
134
135        return result;
136    }
137
138    /**
139     * Returns a count of the audio payloads in the Jingle packet.
140     *
141     * @return the number of audio payloads in the Jingle packet.
142     */
143    public int getPayloadTypesCount() {
144        synchronized (payloads) {
145            return payloads.size();
146        }
147    }
148
149    /**
150     * Convert a Jingle description to XML.
151     *
152     * @return a string with the XML representation
153     */
154    public String toXML() {
155        StringBuilder buf = new StringBuilder();
156
157        synchronized (payloads) {
158            if (payloads.size() > 0) {
159                buf.append("<").append(getElementName());
160                buf.append(" xmlns=\"").append(getNamespace()).append("\" >");
161
162                for (PayloadType payloadType : payloads) {
163                    if (payloadType != null) {
164                        buf.append(payloadType.toXML());
165                    }
166                }
167                buf.append("</").append(getElementName()).append(">");
168            }
169        }
170
171        return buf.toString();
172    }
173
174    /**
175     * Jingle audio description
176     */
177    public static class Audio extends JingleDescription {
178
179        public static final String NAMESPACE = "urn:xmpp:tmp:jingle:apps:rtp";
180
181        public Audio() {
182            super();
183        }
184
185        /**
186         * Utility constructor, with a PayloadType
187         */
188        public Audio(final PayloadType pt) {
189            super();
190            addPayloadType(pt);
191        }
192
193        public String getNamespace() {
194            return NAMESPACE;
195        }
196    }
197}