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