1 /*
2 * jSDP: A Java implementation of SDP protocol Copyright (C) 2007 Claudio Di
3 * Vita
4 */
5 package net.sourceforge.jsdp;
6
7 import java.util.ArrayList;
8 import java.util.Collection;
9 import java.util.HashMap;
10 import java.util.Iterator;
11 import java.util.LinkedList;
12 import java.util.List;
13
14 /**
15 * A <tt>SessionDescription</tt> represents the data defined by the Session
16 * Description Protocol.
17 * <p>
18 * The session description holds information about the originator of a session,
19 * the media types that a client can support and the host and port on which the
20 * client will listen for that media. It also holds timing information for the
21 * session (e.g. start, end, repeat, time zone) and bandwidth supported for the
22 * session.
23 * </p>
24 *
25 * <p>
26 * For further information please refer to <a
27 * href="http://www.ietf.org/rfc/rfc4566.txt">RFC 4566</a>.
28 * </p>
29 *
30 * @see TimeDescription
31 * @see MediaDescription
32 *
33 * @since 0.1.0
34 *
35 * @version 1.1
36 *
37 * @author <a href="mailto:cdivita@users.sourceforge.net">Claudio Di Vita</a>
38 */
39 public class SessionDescription implements Description {
40
41 /** The class Stream Unique Identifier, SUID */
42 private static final long serialVersionUID = -2804972731894656668L;
43
44 /** The version field */
45 protected Version v;
46
47 /** The origin field */
48 protected Origin o;
49
50 /** The session name field */
51 protected SessionName s;
52
53 /** The information field */
54 protected Information i;
55
56 /** The uri field */
57 protected Uri u;
58
59 /** The email fields */
60 protected ArrayList emails;
61
62 /** The phone fields */
63 protected ArrayList phones;
64
65 /** The connection field */
66 protected Connection c;
67
68 /** The bandwith fields */
69 protected HashMap bandwiths;
70
71 /** The time descriptions */
72 protected ArrayList timeDescriptions;
73
74 /** The time zone field */
75 protected TimeZone z;
76
77 /** The key field */
78 protected Key k;
79
80 /** The attribute fields */
81 protected HashMap attributes;
82
83 /** The media descriptions */
84 protected ArrayList mediaDescriptions;
85
86 /**
87 * Creates a <tt>SessionDescription</tt>.
88 */
89 protected SessionDescription() {
90
91 super();
92
93 this.emails = new ArrayList();
94 this.phones = new ArrayList();
95 this.bandwiths = new HashMap();
96 this.timeDescriptions = new ArrayList();
97 this.attributes = new HashMap();
98 this.mediaDescriptions = new ArrayList();
99 }
100
101 /**
102 * Creates a <tt>SessionDescription</tt>. This constructor is used to
103 * implement the @link #clone()} method.
104 *
105 * @param sd the <tt>SessionDescription</tt> to clone
106 */
107 protected SessionDescription(final SessionDescription sd) {
108
109 super();
110
111 this.v = (Version) sd.v.clone();
112 this.o = (Origin) sd.o.clone();
113 this.s = (SessionName) sd.s.clone();
114 this.i = (Information) sd.i.clone();
115 this.u = (Uri) sd.u.clone();
116 this.emails = (ArrayList) sd.emails.clone();
117 this.phones = (ArrayList) sd.phones.clone();
118 this.c = (Connection) sd.c.clone();
119 this.bandwiths = (HashMap) sd.bandwiths.clone();
120 this.timeDescriptions = (ArrayList) sd.timeDescriptions.clone();
121 this.z = (TimeZone) sd.z.clone();
122 this.attributes = (HashMap) sd.attributes.clone();
123 this.mediaDescriptions = (ArrayList) sd.mediaDescriptions.clone();
124 }
125
126 /**
127 * Creates a <tt>SessionDescription</tt>.
128 *
129 * @param v the version field
130 *
131 * @param o the origin field
132 *
133 * @param s the session name field
134 *
135 * @param td the time description
136 *
137 * @throws IllegalArgumentException if one or more parameters are
138 * <tt>null</tt>
139 */
140 public SessionDescription(final Version v, final Origin o, final SessionName s, final TimeDescription td) throws IllegalArgumentException {
141
142 this();
143
144 setVersion(v);
145 setOrigin(o);
146 setSessionName(s);
147
148 addTimeDescription(td);
149 }
150
151 /**
152 * Adds an attribute field. If an <tt>Attribute</tt> with the same name is
153 * already present it will be added.
154 *
155 * @param field the attribute field to set
156 *
157 * @throws IllegalArgumentException if the field is <tt>null</tt>
158 */
159 public void addAttribute(final Attribute field) throws IllegalArgumentException {
160
161 if (field == null) {
162 throw new IllegalArgumentException("An attribute field cannot be null");
163 }
164
165 /* Get attribute name */
166 String name = field.getName();
167
168 /* An object with the same name is already present */
169 if (attributes.containsKey(name)) {
170
171 List values = null;
172 Object maybe = attributes.get(name);
173
174 /* There are many attributes with that name */
175 if (maybe instanceof List) {
176
177 values = (List) maybe;
178 }
179 /* There is only an attribute with that name */
180 else {
181
182 /* Get previous attribute */
183 Attribute previous = (Attribute) maybe;
184
185 /*
186 * Create a list that contains all the attributes with the given
187 * name
188 */
189 values = new LinkedList();
190
191 /* Add the previous attribute to list */
192 values.add(previous);
193
194 attributes.put(field.getName(), values);
195 }
196
197 values.add(field);
198
199 }
200 /* An attribute with given name is not present */
201 else {
202
203 attributes.put(field.getName(), field);
204 }
205 }
206
207 /**
208 * Adds a bandwith field. If a <tt>Bandwith</tt> with the same modifier is
209 * already present it will be replaced.
210 *
211 * @param bandwith the bandwith field to set
212 *
213 * @throws IllegalArgumentException if the bandwith field is <tt>null</tt>
214 */
215 public void addBandwith(final Bandwith bandwith) throws IllegalArgumentException {
216
217 if (bandwith == null) {
218 throw new IllegalArgumentException("A bandwith field cannot be null");
219 }
220
221 bandwiths.put(bandwith.getModifier(), bandwith);
222 }
223
224 /**
225 * Adds an email field.
226 *
227 * @param field the email field to add
228 *
229 * @throws IllegalArgumentException if the field is <tt>null</tt>
230 */
231 public void addEmail(final Email field) throws IllegalArgumentException {
232
233 if (field == null) {
234 throw new IllegalArgumentException("An email field cannot be null");
235 }
236
237 emails.add(field);
238 }
239
240 /**
241 * Adds a media description.
242 *
243 * @param md the media description to add
244 *
245 * @throws IllegalArgumentException if the media description is
246 * <tt>null</tt>
247 *
248 * @throws SDPException if both session and media description doesn't have a
249 * connection field
250 */
251 public void addMediaDescription(final MediaDescription md) throws IllegalArgumentException, SDPException {
252
253 if (md == null) {
254 throw new IllegalArgumentException("A media description cannot be null");
255 }
256
257 if (!hasConnection() && !md.hasConnection()) {
258 throw new SDPException("This media description must have a connection field");
259 }
260
261 /* Add the media description */
262 mediaDescriptions.add(md);
263 }
264
265 /**
266 * Adds a phone field.
267 *
268 * @param field the phone field to add
269 *
270 * @throws IllegalArgumentException tf the field is <tt>null</tt>
271 */
272 public void addPhone(final Phone field) throws IllegalArgumentException {
273
274 if (field == null) {
275 throw new IllegalArgumentException("A phone field cannot be null");
276 }
277
278 /* Add the phone field */
279 phones.add(field);
280 }
281
282 /**
283 * Adds a time description.
284 *
285 * @param td the time description to set
286 *
287 * @throws IllegalArgumentException if the description is <tt>null</tt>
288 */
289 public void addTimeDescription(final TimeDescription td) throws IllegalArgumentException {
290
291 if (td == null) {
292 throw new IllegalArgumentException("A time description cannot be null");
293 }
294
295 timeDescriptions.add(td);
296 }
297
298 /**
299 * Remove all attribute fields contained in the description.
300 */
301 public void clearAttributes() {
302
303 attributes.clear();
304 }
305
306 /**
307 * Remove all bandwith fields contained in the session description.
308 */
309 public void clearBandwiths() {
310
311 this.bandwiths.clear();
312 }
313
314 /**
315 * Remove all email fields contained in the session description.
316 */
317 public void clearEmails() {
318
319 this.emails.clear();
320 }
321
322 /**
323 * Remove all media descriptions contained in the session description.
324 */
325 public void clearMediaDescriptions() {
326
327 this.mediaDescriptions.clear();
328 }
329
330 /**
331 * Remove all phone fields contained in the session description.
332 */
333 public void clearPhones() {
334
335 this.phones.clear();
336 }
337
338 /**
339 * Returns a clone of this description.
340 *
341 * @return a clone of this description
342 */
343 public Object clone() {
344
345 return new SessionDescription(this);
346 }
347
348 /**
349 * Returns all attribute fields.
350 *
351 * @return an array that contains the attribute fields contained in the
352 * description
353 */
354 public Attribute[] getAttributes() {
355
356 Object maybe = null;
357 List values = null;
358
359 Collection result = new LinkedList();
360
361 for (Iterator i = attributes.values().iterator(); i.hasNext();) {
362
363 maybe = i.next();
364
365 if (maybe instanceof Attribute) {
366
367 result.add(maybe);
368 }
369 else {
370
371 values = (List) maybe;
372
373 for (Iterator j = values.iterator(); j.hasNext();) {
374
375 result.add(j.next());
376 }
377 }
378 }
379
380 return (Attribute[]) result.toArray(new Attribute[result.size()]);
381 }
382
383 /**
384 * Returns the attribute with the specified name. If there are multiple
385 * occurencies of attributes with that name, the first one is returned
386 *
387 * @param name the name of the attribute
388 *
389 * @return an attribute field
390 */
391 public Attribute getAttribute(final String name) {
392
393 Attribute result = null;
394 Object maybe = attributes.get(name);
395
396 if (maybe != null) {
397
398 if (maybe instanceof List) {
399
400 List values = (List) maybe;
401
402 result = (Attribute) values.get(0);
403 }
404 else {
405
406 result = (Attribute) maybe;
407 }
408 }
409
410 return result;
411 }
412
413 /**
414 * Returns a specified occurence of an attribute with the specified name.
415 *
416 * @param name the name of the attribute
417 * @param index the occurence index
418 *
419 * @return an attribute field
420 */
421 public Attribute getAttribute(final String name, final int index) {
422
423 Attribute result = null;
424 Object maybe = attributes.get(name);
425
426 if ((maybe != null) && (maybe instanceof List)) {
427
428 List values = (List) maybe;
429
430 result = (Attribute) values.get(index);
431 }
432
433 return result;
434 }
435
436 /**
437 * Returns the attributes with the specified name.
438 *
439 * <p>
440 * If there is only an occurence of that attribute the length of returned
441 * array is <tt>1</tt>, instead if there aren't attributes with the given
442 * name the length of returned array is <tt>0</tt>
443 * </p>
444 *
445 * @param name the name of the attribute
446 *
447 * @return an array of attributes
448 */
449 public Attribute[] getAttributes(final String name) {
450
451 Attribute[] result;
452 Object maybe = attributes.get(name);
453
454 if (maybe != null) {
455
456 if (maybe instanceof List) {
457
458 List values = (List) maybe;
459
460 result = (Attribute[]) values.toArray(new Attribute[values.size()]);
461 }
462 else {
463
464 result = new Attribute[1];
465 result[0] = (Attribute) maybe;
466 }
467 }
468 else {
469 result = new Attribute[0];
470 }
471
472 return result;
473 }
474
475 /**
476 * Returns the number of attributes with a specified name
477 *
478 * @param name the name of the attribute
479 *
480 * @return an integer
481 */
482 public int getAttributesCount(final String name) {
483
484 int result = 0;
485 Object maybe = attributes.get(name);
486
487 if (maybe != null) {
488
489 if (maybe instanceof List) {
490
491 List values = (List) maybe;
492
493 result = values.size();
494 }
495 else {
496
497 result = 1;
498 }
499 }
500
501 return result;
502 }
503
504 /**
505 * Returns the bandwith field with a specified modifier.
506 *
507 * @param modifier the bandwith modifier
508 *
509 * @return the bandwith field specified by modifier if present,
510 * <tt>null</tt> otherwise
511 */
512 public Bandwith getBandwith(final String modifier) {
513
514 return (Bandwith) bandwiths.get(modifier);
515 }
516
517 /**
518 * Returns the bandwith fields.
519 *
520 * @return an array that contains the bandwith fields contained in the
521 * session description
522 */
523 public Bandwith[] getBandwiths() {
524
525 Bandwith[] values = new Bandwith[bandwiths.size()];
526 Iterator iterator = bandwiths.values().iterator();
527
528 for (int j = 0; j < values.length; j++) {
529 values[j] = (Bandwith) iterator.next();
530 }
531
532 return values;
533 }
534
535 /**
536 * Returns the connection field.
537 *
538 * @return the connection field if present, <tt>null</tt> otherwise
539 */
540 public Connection getConnection() {
541
542 return c;
543 }
544
545 /**
546 * Returns the email fields.
547 *
548 * @return an array that contains the email fields contained in the session
549 * description
550 */
551 public Email[] getEmails() {
552
553 return (Email[]) emails.toArray(new Email[emails.size()]);
554 }
555
556 /**
557 * Returns the information field.
558 *
559 * @return the information field if present, <tt>null</tt> otherwise
560 */
561 public Information getInformation() {
562
563 return i;
564 }
565
566 /**
567 * Returns the key field.
568 *
569 * @return the key field if present, <tt>null</tt> otherwise
570 */
571 public Key getKey() {
572
573 return k;
574 }
575
576 /**
577 * Returns the media descriptions.
578 *
579 * @return an array that contains the media descriptions contained in the
580 * session description
581 */
582 public MediaDescription[] getMediaDescriptions() {
583
584 return (MediaDescription[]) mediaDescriptions.toArray(new MediaDescription[mediaDescriptions.size()]);
585 }
586
587 /**
588 * Returns the number of media descriptions.
589 *
590 * @return an integer
591 */
592 public int getMediaDescriptionsCount() {
593
594 return mediaDescriptions.size();
595 }
596
597 /**
598 * Returns the origin field.
599 *
600 * @return the origin field
601 */
602 public Origin getOrigin() {
603
604 return o;
605 }
606
607 /**
608 * Returns the phone fields.
609 *
610 * @return an array that contains the phone fields contained in the session
611 * description
612 */
613 public Phone[] getPhones() {
614
615 return (Phone[]) phones.toArray(new Phone[phones.size()]);
616 }
617
618 /**
619 * Returns the session name field.
620 *
621 * @return the session name field
622 */
623 public SessionName getSessionName() {
624
625 return s;
626 }
627
628 /**
629 * Returns the time descriptions.
630 *
631 * @return an array that contains the time descriptions contained in the
632 * session description
633 */
634 public TimeDescription[] getTimeDescriptions() {
635
636 return (TimeDescription[]) timeDescriptions.toArray(new TimeDescription[timeDescriptions.size()]);
637 }
638
639 /**
640 * Returns the time zone field.
641 *
642 * @return the time zone field if present, <tt>null</tt> otherwise
643 */
644 public TimeZone getTimeZone() {
645
646 return z;
647 }
648
649 /**
650 * Returns the uri field.
651 *
652 * @return the uri field if present, <tt>null</tt> otherwise
653 */
654 public Uri getUri() {
655
656 return u;
657 }
658
659 /**
660 * Returns the version field.
661 *
662 * @return the version field
663 */
664 public Version getVersion() {
665
666 return v;
667 }
668
669 /**
670 * Indicates if an attribute with a specified name is present.
671 *
672 * @param name the name of the attribute
673 *
674 * @return <tt>true</tt> if the attribute is present,
675 * <tt>false</tt> otherwise
676 */
677 public boolean hasAttribute(String name) {
678
679 boolean result = false;
680
681 if (name != null) {
682 result = attributes.containsKey(name);
683 }
684
685 return result;
686 }
687
688 /**
689 * Indicates if the connection field is present.
690 *
691 * @return <tt>true</tt> if the connection field is present,
692 * <tt>false</tt> otherwise
693 */
694 public boolean hasConnection() {
695
696 return c != null;
697 }
698
699 /**
700 * Indicates if one or more email fields are present.
701 *
702 * @return <tt>true</tt> if one or more email fields are present,
703 * <tt>false</tt> otherwise
704 */
705 public boolean hasEmails() {
706
707 return (emails.size() > 0);
708 }
709
710 /**
711 * Indicates if the information field is present.
712 *
713 * @return <tt>true</tt> if the information field is present,
714 * <tt>false</tt> otherwise
715 */
716 public boolean hasInformation() {
717
718 return i != null;
719 }
720
721 /**
722 * Indicates if the encryption key field is present.
723 *
724 * @return <tt>true</tt> if the encryption key field is present,
725 * <tt>false</tt> otherwise
726 */
727 public boolean hasKey() {
728
729 return k != null;
730 }
731
732 /**
733 * Indicates if one or more phone fields are present.
734 *
735 * @return <tt>true</tt> if one or more phone fields are present,
736 * <tt>false</tt> otherwise
737 */
738 public boolean hasPhones() {
739
740 return (phones.size() > 0);
741 }
742
743 /**
744 * Indicates if the timezone field is present.
745 *
746 * @return <tt>true</tt> if the timezone field is present, <tt>false</tt>
747 * otherwise
748 */
749 public boolean hasTimeZone() {
750
751 return z != null;
752 }
753
754 /**
755 * Indicates if the uri field is present
756 *
757 * @return <tt>true</tt> if the uri field is present, <tt>false</tt>
758 * otherwise
759 */
760 public boolean hasUri() {
761
762 return u != null;
763 }
764
765 /**
766 * Removes the attribute field with an associated name. If there are multiple
767 * occurencies of attributes with that name, the first one is removed
768 *
769 * @param name the name of the attribute field to remove
770 *
771 * @return the removed attribute if present, <tt>null</tt>
772 * otherwise
773 */
774 public Attribute removeAttribute(final String name) {
775
776 Attribute a = null;
777 Object maybe = attributes.get(name);
778
779 if (maybe != null) {
780
781 if (maybe instanceof List) {
782
783 List values = (List) maybe;
784
785 /* Remove the first occurence of the attribute */
786 a = (Attribute) values.remove(0);
787
788 /* Remove multiple attributes values, if empty */
789 if (values.isEmpty()) {
790 attributes.remove(name);
791 }
792 }
793 else {
794 a = (Attribute) attributes.remove(name);
795 }
796 }
797
798 return a;
799 }
800
801 /**
802 * Removes a specified occurence of an attribute with the specified name.
803 *
804 * @param name the name of the attribute
805 * @param index the occurence index
806 *
807 * @return the removed attribute
808 */
809 public Attribute removeAttribute(final String name, final int index) {
810
811 Attribute a = null;
812 Object maybe = attributes.get(name);
813
814 if ((maybe != null) && (maybe instanceof List)) {
815
816 List values = (List) maybe;
817
818 a = (Attribute) values.remove(index);
819 }
820
821 return a;
822 }
823
824 /**
825 * Remove all occurencies of attributes with the specified name.
826 *
827 * @param name the name of the attribute
828 */
829 public Attribute[] removeAttributes(final String name) {
830
831 /* Get attributes with given name */
832 Attribute[] result = getAttributes(name);
833
834 /* Remove attributes */
835 attributes.remove(name);
836
837 return result;
838 }
839
840 /**
841 * Remove the bandwith field with an associated modifier
842 *
843 * @param modifier the modifier associated to the bandwith field to remove
844 *
845 * @return the removed bandwith if present, <tt>null</tt>
846 * otherwise
847 */
848 public Bandwith removeBandwith(final String modifier) {
849
850 return (Bandwith) bandwiths.remove(modifier);
851 }
852
853 /**
854 * Set attribute fields. Please note that previous attributes will be
855 * replaced
856 *
857 * @param fields the fields to set
858 *
859 * @throws IllegalArgumentException if one or more field are <tt>null</tt>
860 */
861 public void setAttributes(Attribute[] fields) {
862
863 if (fields == null) {
864 throw new IllegalArgumentException("Attribute fields cannot be null");
865 }
866
867 int length = fields.length;
868 HashMap backup = (HashMap) attributes.clone();
869
870 try {
871
872 /* Remove current attributes */
873 attributes.clear();
874
875 /* Add attributes */
876 for (int i = 0; i < length; i++) {
877 addAttribute(fields[i]);
878 }
879 }
880 catch (IllegalArgumentException exception) {
881
882 /* An error is occured, so we "rollback" */
883 attributes = backup;
884
885 /* Rethrow the exception */
886 throw exception;
887 }
888 }
889
890 /**
891 * Set bandwith fields. Please note that previous bandwiths will be
892 * replaced
893 *
894 * @param fields the fields to set
895 *
896 * @throws IllegalArgumentException if one or more field are <tt>null</tt>
897 */
898 public void setBandwiths(Bandwith[] fields) {
899
900 if (fields == null) {
901 throw new IllegalArgumentException("Bandwith fields cannot be null");
902 }
903
904 int length = fields.length;
905 HashMap backup = (HashMap) bandwiths.clone();
906
907 try {
908
909 /* Remove current bandwiths */
910 bandwiths.clear();
911
912 /* Add bandwiths */
913 for (int i = 0; i < length; i++) {
914 addBandwith(fields[i]);
915 }
916 }
917 catch (IllegalArgumentException exception) {
918
919 /* An error is occured, so we "rollback" */
920 bandwiths = backup;
921
922 /* Rethrow the exception */
923 throw exception;
924 }
925 }
926
927 /**
928 * Sets the connection field.
929 *
930 * @param c the connection field to set
931 */
932 public void setConnection(final Connection c) {
933
934 //FIXME Prevent the field removal while it isn't specified in the media descriptions
935 this.c = c;
936 }
937
938 /**
939 * Sets email fields.
940 *
941 * @param fields the email fields to set
942 *
943 * @throws IllegalArgumentException if one or more field are <tt>null</tt>
944 */
945 public void setEmails(final Email[] fields) throws IllegalArgumentException {
946
947 if (fields == null) {
948 throw new IllegalArgumentException("Email fields cannot be null");
949 }
950
951 int length = fields.length;
952 ArrayList backup = (ArrayList) emails.clone();
953
954 try {
955
956 /* Clear current email fields */
957 emails.clear();
958
959 /* Add email fields */
960 for (int i = 0; i < length; i++) {
961
962 addEmail(fields[i]);
963 }
964 }
965 catch (IllegalArgumentException exception) {
966
967 /* Rollback */
968 emails = backup;
969
970 /* Rethrow the exception */
971 throw exception;
972 }
973 }
974
975 /**
976 * Sets the information field.
977 *
978 * @param i the information field to set
979 */
980 public void setInformation(final Information i) {
981
982 this.i = i;
983 }
984
985 /**
986 * Sets the encryption key field.
987 *
988 * @param k the encryption key field to set
989 */
990 public void setKey(final Key k) {
991
992 this.k = k;
993 }
994
995 /**
996 * Sets media descriptions.
997 *
998 * @param descriptions the media descriptions to set
999 *
1000 * @throws IllegalArgumentException if one or more descriptions are
1001 * <tt>null</tt>
1002 */
1003 public void setMediaDescriptions(final MediaDescription[] descriptions) throws IllegalArgumentException, SDPException {
1004
1005 if (descriptions == null) {
1006 throw new IllegalArgumentException("Media descriptions cannot be null");
1007 }
1008
1009 int length = descriptions.length;
1010 ArrayList backup = (ArrayList) mediaDescriptions.clone();
1011
1012 try {
1013
1014 /* Clear current media descriptions */
1015 mediaDescriptions.clear();
1016
1017 /* Add media descriptions */
1018 for (int i = 0; i < length; i++) {
1019
1020 addMediaDescription(descriptions[i]);
1021 }
1022 }
1023 catch (IllegalArgumentException exception) {
1024
1025 /* Rollback */
1026 mediaDescriptions = backup;
1027
1028 /* Rethrow the exception */
1029 throw exception;
1030 }
1031 catch (SDPException sdpException) {
1032
1033 /* Rollback */
1034 mediaDescriptions = backup;
1035
1036 /* Rethrow the exception */
1037 throw sdpException;
1038 }
1039 }
1040
1041 /**
1042 * Sets the origin field.
1043 *
1044 * @param o the origin field to set
1045 *
1046 * @throws IllegalArgumentException if the field is <tt>null</tt>
1047 */
1048 public void setOrigin(final Origin o) throws IllegalArgumentException {
1049
1050 if (o == null) {
1051 throw new IllegalArgumentException("Origin field cannot be null");
1052 }
1053
1054 this.o = o;
1055 }
1056
1057 /**
1058 * Sets phone fields.
1059 *
1060 * @param fields the phone fields to set
1061 *
1062 * @throws IllegalArgumentException if one or more phone fields are
1063 * <tt>null</tt>
1064 */
1065 public void setPhones(final Phone[] fields) throws IllegalArgumentException {
1066
1067 if (fields == null) {
1068 throw new IllegalArgumentException("Phone fields cannot be null");
1069 }
1070
1071 int length = fields.length;
1072 ArrayList backup = (ArrayList) phones.clone();
1073
1074 try {
1075
1076 /* Clear current phone fields */
1077 phones.clear();
1078
1079 /* Add phone fields */
1080 for (int i = 0; i < length; i++) {
1081
1082 addPhone(fields[i]);
1083 }
1084 }
1085 catch (IllegalArgumentException exception) {
1086
1087 /* Rollback */
1088 phones = backup;
1089
1090 /* Rethrow the exception */
1091 throw exception;
1092 }
1093 }
1094
1095 /**
1096 * Sets session name field.
1097 *
1098 * @param s the session name field to set
1099 *
1100 * @throws IllegalArgumentException if the field is <tt>null</tt>
1101 */
1102 public void setSessionName(final SessionName s) throws IllegalArgumentException {
1103
1104 if (s == null) {
1105 throw new IllegalArgumentException("Session name field cannot be null");
1106 }
1107
1108 this.s = s;
1109 }
1110
1111 /**
1112 * Sets time descriptions.
1113 *
1114 * @param descriptions the time descriptions to set
1115 *
1116 * @throws IllegalArgumentException if one or more description are
1117 * <tt>null</tt>
1118 */
1119 public void setTimeDescriptions(final TimeDescription[] descriptions) throws IllegalArgumentException {
1120
1121 if (descriptions == null) {
1122 throw new IllegalArgumentException("Time descriptions cannot be null");
1123 }
1124
1125 int length = descriptions.length;
1126 ArrayList backup = (ArrayList) timeDescriptions.clone();
1127
1128 try {
1129
1130 /* Clear current time descriptions */
1131 timeDescriptions.clear();
1132
1133 /* Add time descriptions */
1134 for (int i = 0; i < length; i++) {
1135
1136 addTimeDescription(descriptions[i]);
1137 }
1138 }
1139 catch (IllegalArgumentException exception) {
1140
1141 /* Rollback */
1142 timeDescriptions = backup;
1143
1144 /* Rethrow the exception */
1145 throw exception;
1146 }
1147 }
1148
1149 /**
1150 * Sets the timezone field.
1151 *
1152 * @param z the timezone field to set
1153 */
1154 public void setTimeZone(final TimeZone z) {
1155
1156 this.z = z;
1157 }
1158
1159 /**
1160 * Sets the uri field.
1161 *
1162 * @param u the uri field to set
1163 */
1164 public void setUri(final Uri u) {
1165
1166 this.u = u;
1167 }
1168
1169 /**
1170 * Sets the version field.
1171 *
1172 * @param v the version field to set
1173 *
1174 * @throws IllegalArgumentException if the field is <tt>null</tt>
1175 */
1176 public void setVersion(final Version v) throws IllegalArgumentException {
1177
1178 if (v == null) {
1179 throw new IllegalArgumentException("Version field cannot be null");
1180 }
1181
1182 this.v = v;
1183 }
1184
1185 /**
1186 * Returns a string representation of this description.
1187 *
1188 * @return A string representation of the description
1189 */
1190 public String toString() {
1191
1192 /* Add the version field */
1193 StringBuffer result = new StringBuffer(v.toString());
1194 result.append(Field.END_OF_FIELD);
1195
1196 /* Add the origin field */
1197 result.append(o.toString());
1198 result.append(Field.END_OF_FIELD);
1199
1200 /* Add the session name field */
1201 result.append(s.toString());
1202 result.append(Field.END_OF_FIELD);
1203
1204 /* Add the information field, if present */
1205 if (i != null) {
1206 result.append(i.toString());
1207 result.append(Field.END_OF_FIELD);
1208 }
1209
1210 /* Add the uri field, if present */
1211 if (u != null) {
1212 result.append(u.toString());
1213 result.append(Field.END_OF_FIELD);
1214 }
1215
1216 /* Add the email fields, if present */
1217 for (Iterator iterator = emails.iterator(); iterator.hasNext();) {
1218 result.append(iterator.next());
1219 result.append(Field.END_OF_FIELD);
1220 }
1221
1222 /* Add the phone fields, if present */
1223 for (Iterator iterator = phones.iterator(); iterator.hasNext();) {
1224 result.append(iterator.next());
1225 result.append(Field.END_OF_FIELD);
1226 }
1227
1228 /* Add the connection field, if present */
1229 if (c != null) {
1230 result.append(c.toString());
1231 result.append(Field.END_OF_FIELD);
1232 }
1233
1234 int size = 0;
1235
1236 Bandwith[] myBandwiths = getBandwiths();
1237 size = myBandwiths.length;
1238
1239 /* Add the bandwith fields */
1240 for (int i = 0; i < size; i++) {
1241 result.append(myBandwiths[i]);
1242 result.append(Field.END_OF_FIELD);
1243 }
1244
1245 /* Add the time descriptions */
1246 for (Iterator i = timeDescriptions.iterator(); i.hasNext();) {
1247 result.append(i.next());
1248 /*
1249 * Don't append END_OF_FIELD because this element is a time
1250 * description
1251 */
1252 }
1253
1254 /* Add the timezone field, if present */
1255 if (z != null) {
1256 result.append(z.toString());
1257 result.append(Field.END_OF_FIELD);
1258 }
1259
1260 /* Add the key field, if present */
1261 if (k != null) {
1262 result.append(k.toString());
1263 result.append(Field.END_OF_FIELD);
1264 }
1265
1266 Attribute[] myAttributes = getAttributes();
1267 size = myAttributes.length;
1268
1269 /* Add the attribute fields */
1270 for (int i = 0; i < size; i++) {
1271 result.append(myAttributes[i]);
1272 result.append(Field.END_OF_FIELD);
1273 }
1274
1275 /* Add the media descriptions */
1276 for (Iterator i = mediaDescriptions.iterator(); i.hasNext();) {
1277 result.append(i.next());
1278 /*
1279 * Don't append END_OF_FIELD because this element is a media
1280 * description
1281 */
1282 }
1283
1284 return result.toString();
1285 }
1286 }