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