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 List<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 List<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 @SuppressWarnings("this-escape") 188 public Audio(final JinglePayloadType pt) { 189 super(); 190 addJinglePayloadType(pt); 191 } 192 193 @Override 194 public String getNamespace() { 195 return NAMESPACE; 196 } 197 } 198 199 /** 200 * A payload type, contained in a descriptor. 201 * 202 * @author Alvaro Saurin 203 */ 204 public static class JinglePayloadType { 205 206 public static final String NODENAME = "payload-type"; 207 208 private PayloadType payload; 209 210 /** 211 * Create a payload type. 212 * 213 * @param payload the payload 214 */ 215 public JinglePayloadType(final PayloadType payload) { 216 super(); 217 this.payload = payload; 218 } 219 220 /** 221 * Create an empty payload type. 222 */ 223 public JinglePayloadType() { 224 this(null); 225 } 226 227 /** 228 * Returns the XML element name of the element. 229 * 230 * @return the XML element name of the element. 231 */ 232 public static String getElementName() { 233 return NODENAME; 234 } 235 236 /** 237 * Get the payload represented. 238 * 239 * @return the payload 240 */ 241 public PayloadType getPayloadType() { 242 return payload; 243 } 244 245 /** 246 * Set the payload represented. 247 * 248 * @param payload the payload to set 249 */ 250 public void setPayload(final PayloadType payload) { 251 this.payload = payload; 252 } 253 254 protected String getChildAttributes() { 255 return null; 256 } 257 258 public String toXML() { 259 StringBuilder buf = new StringBuilder(); 260 261 if (payload != null) { 262 buf.append('<').append(getElementName()).append(' '); 263 264 // We covert here the payload type to XML 265 if (payload.getId() != PayloadType.INVALID_PT) { 266 buf.append(" id=\"").append(payload.getId()).append('"'); 267 } 268 if (payload.getName() != null) { 269 buf.append(" name=\"").append(payload.getName()).append('"'); 270 } 271 if (payload.getChannels() != 0) { 272 buf.append(" channels=\"").append(payload.getChannels()).append('"'); 273 } 274 if (getChildAttributes() != null) { 275 buf.append(getChildAttributes()); 276 } 277 buf.append("/>"); 278 } 279 return buf.toString(); 280 } 281 282 /** 283 * Audio payload type element. 284 */ 285 public static class Audio extends JinglePayloadType { 286 public Audio(final PayloadType.Audio audio) { 287 super(audio); 288 } 289 290 @Override 291 protected String getChildAttributes() { 292 StringBuilder buf = new StringBuilder(); 293 PayloadType pt = getPayloadType(); 294 if (pt instanceof PayloadType.Audio) { 295 PayloadType.Audio pta = (PayloadType.Audio) pt; 296 297 buf.append(" clockrate=\"").append(pta.getClockRate()).append("\" "); 298 } 299 return buf.toString(); 300 } 301 } 302 } 303}