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