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; 023 024import org.jivesoftware.smack.packet.ExtensionElement; 025 026import org.jivesoftware.smackx.jingleold.media.PayloadType; 027 028/** 029 * Jingle content description. 030 * 031 * @author Alvaro Saurin 032 */ 033public abstract class JingleContentDescription implements ExtensionElement { 034 035 // static 036 037 public static final String NODENAME = "description"; 038 039 // non-static 040 041 private final List<JinglePayloadType> payloads = new ArrayList<>(); 042 043 /** 044 * Creates a content description.. 045 */ 046 public JingleContentDescription() { 047 super(); 048 } 049 050 /** 051 * Returns the XML element name of the element. 052 * 053 * @return the XML element name of the element. 054 */ 055 @Override 056 public String getElementName() { 057 return NODENAME; 058 } 059 060 /** 061 * Return the namespace. 062 * 063 * @return The namespace 064 */ 065 @Override 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 addJinglePayloadType(final JinglePayloadType pt) { 074 synchronized (payloads) { 075 payloads.add(pt); 076 } 077 } 078 079 /** 080 * Adds a list of payloads to the packet. 081 * 082 * @param pts the payloads to add. 083 */ 084 public void addAudioPayloadTypes(final List<PayloadType.Audio> pts) { 085 synchronized (payloads) { 086 Iterator<PayloadType.Audio> ptIter = pts.iterator(); 087 while (ptIter.hasNext()) { 088 PayloadType.Audio pt = ptIter.next(); 089 addJinglePayloadType(new JinglePayloadType.Audio(pt)); 090 } 091 } 092 } 093 094 /** 095 * Returns an Iterator for the audio payloads in the packet. 096 * 097 * @return an Iterator for the audio payloads in the packet. 098 */ 099 public Iterator<JinglePayloadType> getJinglePayloadTypes() { 100 return Collections.unmodifiableList(getJinglePayloadTypesList()).iterator(); 101 } 102 103 /** 104 * Returns a list for the audio payloads in the packet. 105 * 106 * @return a list for the audio payloads in the packet. 107 */ 108 public ArrayList<JinglePayloadType> getJinglePayloadTypesList() { 109 synchronized (payloads) { 110 return new ArrayList<>(payloads); 111 } 112 } 113 114 /** 115 * Return the list of Payload types contained in the description. 116 * 117 * @return a list of PayloadType.Audio 118 */ 119 public ArrayList<PayloadType.Audio> getAudioPayloadTypesList() { 120 ArrayList<PayloadType.Audio> result = new ArrayList<>(); 121 Iterator<JinglePayloadType> jinglePtsIter = getJinglePayloadTypes(); 122 123 while (jinglePtsIter.hasNext()) { 124 JinglePayloadType jpt = jinglePtsIter.next(); 125 if (jpt instanceof JinglePayloadType.Audio) { 126 JinglePayloadType.Audio jpta = (JinglePayloadType.Audio) jpt; 127 result.add((PayloadType.Audio) jpta.getPayloadType()); 128 } 129 } 130 131 return result; 132 } 133 134 /** 135 * Returns a count of the audio payloads in the Jingle packet. 136 * 137 * @return the number of audio payloads in the Jingle packet. 138 */ 139 public int getJinglePayloadTypesCount() { 140 synchronized (payloads) { 141 return payloads.size(); 142 } 143 } 144 145 /** 146 * Convert a Jingle description to XML. 147 * 148 * @return a string with the XML representation 149 */ 150 @Override 151 public String toXML(org.jivesoftware.smack.packet.XmlEnvironment enclosingNamespace) { 152 StringBuilder buf = new StringBuilder(); 153 154 synchronized (payloads) { 155 if (payloads.size() > 0) { 156 buf.append('<').append(getElementName()); 157 buf.append(" xmlns=\"").append(getNamespace()).append("\" >"); 158 159 Iterator<JinglePayloadType> pt = payloads.listIterator(); 160 while (pt.hasNext()) { 161 JinglePayloadType pte = pt.next(); 162 buf.append(pte.toXML()); 163 } 164 buf.append("</").append(getElementName()).append('>'); 165 } 166 } 167 168 return buf.toString(); 169 } 170 171 /** 172 * Jingle audio description. 173 */ 174 public static class Audio extends JingleContentDescription { 175 176 public static final String NAMESPACE = "urn:xmpp:tmp:jingle:apps:rtp"; 177 178 public Audio() { 179 super(); 180 } 181 182 /** 183 * Utility constructor, with a JinglePayloadType. 184 * 185 * @param pt the payload type. 186 */ 187 public Audio(final JinglePayloadType pt) { 188 super(); 189 addJinglePayloadType(pt); 190 } 191 192 @Override 193 public String getNamespace() { 194 return NAMESPACE; 195 } 196 } 197 198 /** 199 * A payload type, contained in a descriptor. 200 * 201 * @author Alvaro Saurin 202 */ 203 public static class JinglePayloadType { 204 205 public static final String NODENAME = "payload-type"; 206 207 private PayloadType payload; 208 209 /** 210 * Create a payload type. 211 * 212 * @param payload the payload 213 */ 214 public JinglePayloadType(final PayloadType payload) { 215 super(); 216 this.payload = payload; 217 } 218 219 /** 220 * Create an empty payload type. 221 */ 222 public JinglePayloadType() { 223 this(null); 224 } 225 226 /** 227 * Returns the XML element name of the element. 228 * 229 * @return the XML element name of the element. 230 */ 231 public static String getElementName() { 232 return NODENAME; 233 } 234 235 /** 236 * Get the payload represented. 237 * 238 * @return the payload 239 */ 240 public PayloadType getPayloadType() { 241 return payload; 242 } 243 244 /** 245 * Set the payload represented. 246 * 247 * @param payload the payload to set 248 */ 249 public void setPayload(final PayloadType payload) { 250 this.payload = payload; 251 } 252 253 protected String getChildAttributes() { 254 return null; 255 } 256 257 public String toXML() { 258 StringBuilder buf = new StringBuilder(); 259 260 if (payload != null) { 261 buf.append('<').append(getElementName()).append(' '); 262 263 // We covert here the payload type to XML 264 if (payload.getId() != PayloadType.INVALID_PT) { 265 buf.append(" id=\"").append(payload.getId()).append('"'); 266 } 267 if (payload.getName() != null) { 268 buf.append(" name=\"").append(payload.getName()).append('"'); 269 } 270 if (payload.getChannels() != 0) { 271 buf.append(" channels=\"").append(payload.getChannels()).append('"'); 272 } 273 if (getChildAttributes() != null) { 274 buf.append(getChildAttributes()); 275 } 276 buf.append("/>"); 277 } 278 return buf.toString(); 279 } 280 281 /** 282 * Audio payload type element. 283 */ 284 public static class Audio extends JinglePayloadType { 285 public Audio(final PayloadType.Audio audio) { 286 super(audio); 287 } 288 289 @Override 290 protected String getChildAttributes() { 291 StringBuilder buf = new StringBuilder(); 292 PayloadType pt = getPayloadType(); 293 if (pt instanceof PayloadType.Audio) { 294 PayloadType.Audio pta = (PayloadType.Audio) pt; 295 296 buf.append(" clockrate=\"").append(pta.getClockRate()).append("\" "); 297 } 298 return buf.toString(); 299 } 300 } 301 } 302}