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.media;
018
019/**
020 * Represents a payload type.
021 *
022 * @author Alvaro Saurin
023 */
024public class PayloadType {
025
026    public static final String NODENAME = "payload-type";
027
028    public static int MAX_FIXED_PT = 95;
029
030    public static int INVALID_PT = 65535;
031
032    private int id;
033
034    private String name;
035
036    private int channels;
037
038    /**
039     * Constructor with Id, name and number of channels.
040     *
041     * @param id       The identifier
042     * @param name     A name
043     * @param channels The number of channels
044     */
045    public PayloadType(int id, final String name, int channels) {
046        super();
047        this.id = id;
048        this.name = name;
049        this.channels = channels;
050    }
051
052    /**
053     * Default constructor.
054     */
055    public PayloadType() {
056        this(INVALID_PT, null, 1);
057    }
058
059    /**
060     * Constructor with Id and name.
061     *
062     * @param id   The identification
063     * @param name A name
064     */
065    public PayloadType(int id, String name) {
066        this(id, name, 1);
067    }
068
069    /**
070     * Copy constructor.
071     *
072     * @param pt The other payload type.
073     */
074    public PayloadType(PayloadType pt) {
075        this(pt.getId(), pt.getName(), pt.getChannels());
076    }
077
078    /**
079     * Get the ID.
080     *
081     * @return the ID
082     */
083    public int getId() {
084        return id;
085    }
086
087    /**
088     * Set the ID.
089     *
090     * @param id ID
091     */
092    public void setId(int id) {
093        this.id = id;
094    }
095
096    /**
097     * Get the printable name.
098     *
099     * @return printable name for the payload type
100     */
101    public String getName() {
102        return name;
103    }
104
105    /**
106     * Set the printable name.
107     *
108     * @param name the printable name
109     */
110    public void setName(String name) {
111        this.name = name;
112    }
113
114    /**
115     * Get the number of channels used by this payload type.
116     *
117     * @return the number of channels
118     */
119    public int getChannels() {
120        return channels;
121    }
122
123    /**
124     * Set the number of channels for a payload type.
125     *
126     * @param channels The number of channels
127     */
128    public void setChannels(int channels) {
129        this.channels = channels;
130    }
131
132    /**
133     * Return true if the Payload type is not valid.
134     *
135     * @return true if the payload type is invalid
136     */
137    public boolean isNull() {
138        if (getId() == INVALID_PT) {
139            return true;
140        }
141        else if (getName() == null) {
142            return true;
143        }
144        return false;
145    }
146
147    /*
148      * (non-Javadoc)
149      *
150      * @see java.lang.Object#hashCode()
151      */
152    @Override
153    public int hashCode() {
154        final int PRIME = 31;
155        int result = 1;
156        result = PRIME * result + getChannels();
157        result = PRIME * result + getId();
158        result = PRIME * result + (getName() == null ? 0 : getName().hashCode());
159        return result;
160    }
161
162    /*
163      * (non-Javadoc)
164      *
165      * @see java.lang.Object#equals(java.lang.Object)
166      */
167    @Override
168    public boolean equals(Object obj) {
169        if (this == obj) {
170            return true;
171        }
172        if (obj == null) {
173            return false;
174        }
175        if (!(obj instanceof PayloadType)) {
176            return false;
177        }
178        final PayloadType other = (PayloadType) obj;
179        if (getChannels() != other.getChannels()) {
180            return false;
181        }
182        if (getId() != other.getId()) {
183            return false;
184        }
185
186        // Compare names only for dynamic payload types
187        if (getId() > MAX_FIXED_PT) {
188            if (getName() == null) {
189                if (other.getName() != null) {
190                    return false;
191                }
192            }
193            else if (!getName().equals(other.getName())) {
194                return false;
195            }
196        }
197
198        return true;
199    }
200
201    /**
202     * Returns the XML element name of the element.
203     *
204     * @return the XML element name of the element.
205     */
206    public static String getElementName() {
207        return NODENAME;
208    }
209
210    public String toXML() {
211        StringBuilder buf = new StringBuilder();
212
213            buf.append('<').append(getElementName()).append(' ');
214
215            // We covert here the payload type to XML
216            if (this.getId() != PayloadType.INVALID_PT) {
217                buf.append(" id=\"").append(this.getId()).append('"');
218            }
219            if (this.getName() != null) {
220                buf.append(" name=\"").append(this.getName()).append('"');
221            }
222            if (this.getChannels() != 0) {
223                buf.append(" channels=\"").append(this.getChannels()).append('"');
224            }
225            if (getChildAttributes() != null) {
226                buf.append(getChildAttributes());
227            }
228            buf.append("/>");
229
230        return buf.toString();
231    }
232
233    protected String getChildAttributes() {
234        StringBuilder buf = new StringBuilder();
235        if (this instanceof PayloadType.Audio) {
236            PayloadType.Audio pta = (PayloadType.Audio) this;
237
238            buf.append(" clockrate=\"").append(pta.getClockRate()).append("\" ");
239        }
240
241        return buf.toString();
242    }
243
244    /**
245     * Audio payload type.
246     */
247    public static final class Audio extends PayloadType {
248
249        private int clockRate;
250
251        /**
252         * Constructor with all the attributes of an Audio payload type.
253         *
254         * @param id       The identifier
255         * @param name     The name assigned to this payload type
256         * @param channels The number of channels
257         * @param rate     The clock rate
258         */
259        public Audio(int id, String name, int channels, int rate) {
260            super(id, name, channels);
261            clockRate = rate;
262        }
263
264        /**
265         * Constructor with all the attributes of an Audio payload type.
266         *
267         * @param id       The identifier
268         * @param name     The name assigned to this payload type
269         * @param rate     The clock rate
270         */
271        public Audio(int id, String name, int rate) {
272            super(id, name);
273            clockRate = rate;
274        }
275
276        /**
277         * Empty constructor.
278         */
279        public Audio() {
280            super();
281            clockRate = 0;
282        }
283
284        /**
285         * Constructor with Id and name.
286         *
287         * @param id   the Id for the payload type
288         * @param name the name of the payload type
289         */
290        public Audio(int id, String name) {
291            super(id, name);
292            clockRate = 0;
293        }
294
295        /**
296         * Copy constructor.
297         *
298         * @param pt the other payload type
299         */
300        public Audio(PayloadType pt) {
301            super(pt);
302            clockRate = 0;
303        }
304
305        /**
306         * Copy constructor.
307         *
308         * @param pt the other payload type
309         */
310        public Audio(PayloadType.Audio pt) {
311            super(pt);
312            clockRate = pt.getClockRate();
313        }
314
315        /**
316         * Get the sampling clockRate for a payload type.
317         *
318         * @return The sampling clockRate
319         */
320        public int getClockRate() {
321            return clockRate;
322        }
323
324        /**
325         * Set tha sampling clockRate for a playload type.
326         *
327         * @param rate The sampling clockRate
328         */
329        public void setClockRate(int rate) {
330            clockRate = rate;
331        }
332
333        /*
334           * (non-Javadoc)
335           *
336           * @see java.lang.Object#hashCode()
337           */
338        @Override
339        public int hashCode() {
340            final int PRIME = 31;
341            int result = super.hashCode();
342            result = PRIME * result + getClockRate();
343            return result;
344        }
345
346        /*
347           * (non-Javadoc)
348           *
349           * @see java.lang.Object#equals(java.lang.Object)
350           */
351        @Override
352        public boolean equals(Object obj) {
353            if (this == obj) {
354                return true;
355            }
356            if (!super.equals(obj)) {
357                return false;
358            }
359            if (getClass() != obj.getClass()) {
360                return false;
361            }
362            final Audio other = (Audio) obj;
363            if (getClockRate() != other.getClockRate()) {
364                return false;
365            }
366            return true;
367        }
368    }
369}