001    package ezvcard;
002    
003    import java.io.File;
004    import java.io.IOException;
005    import java.io.OutputStream;
006    import java.io.Writer;
007    import java.lang.reflect.Field;
008    import java.util.ArrayList;
009    import java.util.Collection;
010    import java.util.Date;
011    import java.util.Iterator;
012    import java.util.List;
013    import java.util.Map;
014    
015    import javax.xml.transform.TransformerException;
016    
017    import ezvcard.io.VCardWriter;
018    import ezvcard.parameters.EmailTypeParameter;
019    import ezvcard.parameters.TelephoneTypeParameter;
020    import ezvcard.types.AddressType;
021    import ezvcard.types.AgentType;
022    import ezvcard.types.AnniversaryType;
023    import ezvcard.types.BirthdayType;
024    import ezvcard.types.BirthplaceType;
025    import ezvcard.types.CalendarRequestUriType;
026    import ezvcard.types.CalendarUriType;
027    import ezvcard.types.CategoriesType;
028    import ezvcard.types.ClassificationType;
029    import ezvcard.types.ClientPidMapType;
030    import ezvcard.types.DeathdateType;
031    import ezvcard.types.DeathplaceType;
032    import ezvcard.types.EmailType;
033    import ezvcard.types.ExpertiseType;
034    import ezvcard.types.FbUrlType;
035    import ezvcard.types.FormattedNameType;
036    import ezvcard.types.GenderType;
037    import ezvcard.types.GeoType;
038    import ezvcard.types.HobbyType;
039    import ezvcard.types.ImppType;
040    import ezvcard.types.InterestType;
041    import ezvcard.types.KeyType;
042    import ezvcard.types.KindType;
043    import ezvcard.types.LabelType;
044    import ezvcard.types.LanguageType;
045    import ezvcard.types.LogoType;
046    import ezvcard.types.MailerType;
047    import ezvcard.types.MemberType;
048    import ezvcard.types.NicknameType;
049    import ezvcard.types.NoteType;
050    import ezvcard.types.OrgDirectoryType;
051    import ezvcard.types.OrganizationType;
052    import ezvcard.types.PhotoType;
053    import ezvcard.types.ProdIdType;
054    import ezvcard.types.ProfileType;
055    import ezvcard.types.RawType;
056    import ezvcard.types.RelatedType;
057    import ezvcard.types.RevisionType;
058    import ezvcard.types.RoleType;
059    import ezvcard.types.SortStringType;
060    import ezvcard.types.SoundType;
061    import ezvcard.types.SourceDisplayTextType;
062    import ezvcard.types.SourceType;
063    import ezvcard.types.StructuredNameType;
064    import ezvcard.types.TelephoneType;
065    import ezvcard.types.TimezoneType;
066    import ezvcard.types.TitleType;
067    import ezvcard.types.UidType;
068    import ezvcard.types.UrlType;
069    import ezvcard.types.VCardType;
070    import ezvcard.types.XmlType;
071    import ezvcard.util.ListMultimap;
072    import freemarker.template.TemplateException;
073    
074    /*
075     Copyright (c) 2012, Michael Angstadt
076     All rights reserved.
077    
078     Redistribution and use in source and binary forms, with or without
079     modification, are permitted provided that the following conditions are met: 
080    
081     1. Redistributions of source code must retain the above copyright notice, this
082     list of conditions and the following disclaimer. 
083     2. Redistributions in binary form must reproduce the above copyright notice,
084     this list of conditions and the following disclaimer in the documentation
085     and/or other materials provided with the distribution. 
086    
087     THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
088     ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
089     WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
090     DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
091     ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
092     (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
093     LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
094     ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
095     (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
096     SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
097    
098     The views and conclusions contained in the software and documentation are those
099     of the authors and should not be interpreted as representing official policies, 
100     either expressed or implied, of the FreeBSD Project.
101     */
102    
103    /**
104     * Represents the data in a vCard.
105     * @author Michael Angstadt
106     */
107    public class VCard implements Iterable<VCardType> {
108            private VCardVersion version = VCardVersion.V3_0;
109            private KindType kind;
110            private GenderType gender;
111            private List<MemberType> members = new ArrayList<MemberType>();
112            private ProfileType profile;
113            private ClassificationType classification;
114            private List<SourceType> sources = new ArrayList<SourceType>();
115            private SourceDisplayTextType sourceDisplayText;
116            private List<FormattedNameType> formattedNames = new ArrayList<FormattedNameType>();
117            private List<StructuredNameType> structuredNames = new ArrayList<StructuredNameType>();
118            private List<NicknameType> nicknames = new ArrayList<NicknameType>();
119            private SortStringType sortString;
120            private List<TitleType> titles = new ArrayList<TitleType>();
121            private List<RoleType> roles = new ArrayList<RoleType>();
122            private List<PhotoType> photos = new ArrayList<PhotoType>();
123            private List<LogoType> logos = new ArrayList<LogoType>();
124            private List<SoundType> sounds = new ArrayList<SoundType>();
125            private List<BirthplaceType> birthplaces = new ArrayList<BirthplaceType>();
126            private List<DeathplaceType> deathplaces = new ArrayList<DeathplaceType>();
127            private List<DeathdateType> deathdates = new ArrayList<DeathdateType>();
128            private List<BirthdayType> birthdays = new ArrayList<BirthdayType>();
129            private List<AnniversaryType> anniversaries = new ArrayList<AnniversaryType>();
130            private RevisionType rev;
131            private ProdIdType prodId;
132            private List<AddressType> addresses = new ArrayList<AddressType>();
133            private List<LabelType> labels = new ArrayList<LabelType>();
134            private List<EmailType> emails = new ArrayList<EmailType>();
135            private List<TelephoneType> telephoneNumbers = new ArrayList<TelephoneType>();
136            private MailerType mailer;
137            private List<UrlType> urls = new ArrayList<UrlType>();
138            private List<TimezoneType> timezones = new ArrayList<TimezoneType>();
139            private List<GeoType> geos = new ArrayList<GeoType>();
140            private List<OrganizationType> organizations = new ArrayList<OrganizationType>();
141            private List<CategoriesType> categories = new ArrayList<CategoriesType>();
142            private AgentType agent;
143            private List<NoteType> notes = new ArrayList<NoteType>();
144            private UidType uid;
145            private List<KeyType> keys = new ArrayList<KeyType>();
146            private List<ImppType> impps = new ArrayList<ImppType>();
147            private List<RelatedType> relations = new ArrayList<RelatedType>();
148            private List<LanguageType> languages = new ArrayList<LanguageType>();
149            private List<CalendarRequestUriType> calendarRequestUris = new ArrayList<CalendarRequestUriType>();
150            private List<CalendarUriType> calendarUris = new ArrayList<CalendarUriType>();
151            private List<FbUrlType> fbUrls = new ArrayList<FbUrlType>();
152            private List<ClientPidMapType> clientPidMaps = new ArrayList<ClientPidMapType>();
153            private List<XmlType> xmls = new ArrayList<XmlType>();
154            private List<ExpertiseType> expertises = new ArrayList<ExpertiseType>();
155            private List<HobbyType> hobbies = new ArrayList<HobbyType>();
156            private List<InterestType> interests = new ArrayList<InterestType>();
157            private List<OrgDirectoryType> orgDirectories = new ArrayList<OrgDirectoryType>();
158            private ListMultimap<String, VCardType> extendedTypes = new ListMultimap<String, VCardType>();
159    
160            /**
161             * <p>
162             * Marshals this vCard to its text representation.
163             * </p>
164             * <p>
165             * The vCard will be marshalled to whatever version is attached to this
166             * VCard object (see {@link #setVersion(VCardVersion)}). If no version is
167             * set, then it will be marshalled to 3.0.
168             * </p>
169             * <p>
170             * Use the {@link Ezvcard} class to customize the marshalling process and to
171             * write multiple vCards to the same stream.
172             * </p>
173             * @return the vCard string
174             * @see Ezvcard
175             * @see <a href="http://www.imc.org/pdi/vcard-21.rtf">vCard 2.1</a>
176             * @see <a href="http://tools.ietf.org/html/rfc2426">RFC 2426 (3.0)</a>
177             * @see <a href="http://tools.ietf.org/html/rfc6350">RFC 6350 (4.0)</a>
178             */
179            public String write() {
180                    return Ezvcard.write(this).go();
181            }
182    
183            /**
184             * <p>
185             * Marshals this vCard to its text representation.
186             * </p>
187             * <p>
188             * The vCard will be marshalled to whatever version is attached to this
189             * VCard object (see {@link #setVersion(VCardVersion)}). If no version is
190             * set, then it will be marshalled to 3.0.
191             * </p>
192             * <p>
193             * Use the {@link Ezvcard} class to customize the marshalling process and to
194             * write multiple vCards to the same stream.
195             * </p>
196             * @param file the file to write the vCard to
197             * @throws IOException if there's a problem writing to the file
198             * @see Ezvcard
199             * @see <a href="http://www.imc.org/pdi/vcard-21.rtf">vCard 2.1</a>
200             * @see <a href="http://tools.ietf.org/html/rfc2426">RFC 2426 (3.0)</a>
201             * @see <a href="http://tools.ietf.org/html/rfc6350">RFC 6350 (4.0)</a>
202             */
203            public void write(File file) throws IOException {
204                    Ezvcard.write(this).go(file);
205            }
206    
207            /**
208             * <p>
209             * Marshals this vCard to its text representation.
210             * </p>
211             * <p>
212             * The vCard will be marshalled to whatever version is attached to this
213             * VCard object (see {@link #setVersion(VCardVersion)}). If no version is
214             * set, then it will be marshalled to 3.0.
215             * </p>
216             * <p>
217             * Use the {@link Ezvcard} class to customize the marshalling process and to
218             * write multiple vCards to the same stream.
219             * </p>
220             * @param out the output stream to write the vCard to
221             * @see Ezvcard
222             * @throws IOException if there's a problem writing to the output stream
223             * @see <a href="http://www.imc.org/pdi/vcard-21.rtf">vCard 2.1</a>
224             * @see <a href="http://tools.ietf.org/html/rfc2426">RFC 2426 (3.0)</a>
225             * @see <a href="http://tools.ietf.org/html/rfc6350">RFC 6350 (4.0)</a>
226             */
227            public void write(OutputStream out) throws IOException {
228                    Ezvcard.write(this).go(out);
229            }
230    
231            /**
232             * <p>
233             * Marshals this vCard to its text representation.
234             * </p>
235             * <p>
236             * The vCard will be marshalled to whatever version is attached to this
237             * VCard object (see {@link #setVersion(VCardVersion)}). If no version is
238             * set, then it will be marshalled to 3.0.
239             * </p>
240             * <p>
241             * Use the {@link Ezvcard} class to customize the marshalling process and to
242             * write multiple vCards to the same stream.
243             * </p>
244             * @param writer the writer to write the vCard to
245             * @throws IOException if there's a problem writing to the writer
246             * @see Ezvcard
247             * @see <a href="http://www.imc.org/pdi/vcard-21.rtf">vCard 2.1</a>
248             * @see <a href="http://tools.ietf.org/html/rfc2426">RFC 2426 (3.0)</a>
249             * @see <a href="http://tools.ietf.org/html/rfc6350">RFC 6350 (4.0)</a>
250             */
251            public void write(Writer writer) throws IOException {
252                    Ezvcard.write(this).go(writer);
253            }
254    
255            /**
256             * <p>
257             * Marshals this vCard to its XML representation (xCard).
258             * </p>
259             * <p>
260             * Use the {@link Ezvcard} class to customize the marshalling process and to
261             * write multiple vCards to the same stream.
262             * </p>
263             * @return the vCard XML document
264             * @see Ezvcard
265             * @see <a href="http://tools.ietf.org/html/rfc6351">RFC 6351</a>
266             */
267            public String writeXml() {
268                    return Ezvcard.writeXml(this).indent(2).go();
269            }
270    
271            /**
272             * <p>
273             * Marshals this vCard to its XML representation (xCard).
274             * </p>
275             * <p>
276             * Use the {@link Ezvcard} class to customize the marshalling process and to
277             * write multiple vCards to the same stream.
278             * </p>
279             * @param file the file to write to
280             * @throws IOException if there's a problem writing to the file
281             * @throws TransformerException if there's a problem writing the vCard
282             * @see Ezvcard
283             * @see <a href="http://tools.ietf.org/html/rfc6351">RFC 6351</a>
284             */
285            public void writeXml(File file) throws IOException, TransformerException {
286                    Ezvcard.writeXml(this).indent(2).go(file);
287            }
288    
289            /**
290             * <p>
291             * Marshals this vCard to its XML representation (xCard).
292             * </p>
293             * <p>
294             * Use the {@link Ezvcard} class to customize the marshalling process and to
295             * write multiple vCards to the same stream.
296             * </p>
297             * @param out the output stream to write the vCard to
298             * @throws TransformerException if there's a problem writing to the output
299             * stream
300             * @see Ezvcard
301             * @see <a href="http://tools.ietf.org/html/rfc6351">RFC 6351</a>
302             */
303            public void writeXml(OutputStream out) throws TransformerException {
304                    Ezvcard.writeXml(this).indent(2).go(out);
305            }
306    
307            /**
308             * <p>
309             * Marshals this vCard to its XML representation (xCard).
310             * </p>
311             * <p>
312             * Use the {@link Ezvcard} class to customize the marshalling process and to
313             * write multiple vCards to the same stream.
314             * </p>
315             * @param writer the writer to write the vCard to
316             * @throws TransformerException if there's a problem writing to the writer
317             * @see Ezvcard
318             * @see <a href="http://tools.ietf.org/html/rfc6351">RFC 6351</a>
319             */
320            public void writeXml(Writer writer) throws TransformerException {
321                    Ezvcard.writeXml(this).indent(2).go(writer);
322            }
323    
324            /**
325             * <p>
326             * Marshals this vCard to a basic HTML page (hCard).
327             * </p>
328             * <p>
329             * Use the {@link Ezvcard} class to customize the marshalling process and to
330             * write multiple vCards to the same stream.
331             * </p>
332             * @return the HTML page
333             * @see Ezvcard
334             * @see <a href="http://microformats.org/wiki/hcard">hCard 1.0</a>
335             */
336            public String writeHtml() throws TemplateException {
337                    return Ezvcard.writeHtml(this).go();
338            }
339    
340            /**
341             * <p>
342             * Marshals this vCard to a basic HTML page (hCard).
343             * </p>
344             * <p>
345             * Use the {@link Ezvcard} class to customize the marshalling process and to
346             * write multiple vCards to the same stream.
347             * </p>
348             * @param file the file to write to
349             * @throws IOException if there's a problem writing to the file
350             * @throws TemplateException if there's a problem with the freemarker
351             * template
352             * @see Ezvcard
353             * @see <a href="http://microformats.org/wiki/hcard">hCard 1.0</a>
354             */
355            public void writeHtml(File file) throws IOException, TemplateException {
356                    Ezvcard.writeHtml(this).go(file);
357            }
358    
359            /**
360             * <p>
361             * Marshals this vCard to a basic HTML page (hCard).
362             * </p>
363             * <p>
364             * Use the {@link Ezvcard} class to customize the marshalling process and to
365             * write multiple vCards to the same stream.
366             * </p>
367             * @param out the output stream to write to
368             * @throws IOException if there's a problem writing to the output stream
369             * @throws TemplateException if there's a problem with the freemarker
370             * template
371             * @see Ezvcard
372             * @see <a href="http://microformats.org/wiki/hcard">hCard 1.0</a>
373             */
374            public void writeHtml(OutputStream out) throws IOException, TemplateException {
375                    Ezvcard.writeHtml(this).go(out);
376            }
377    
378            /**
379             * <p>
380             * Marshals this vCard to a basic HTML page (hCard).
381             * </p>
382             * <p>
383             * Use the {@link Ezvcard} class to customize the marshalling process and to
384             * write multiple vCards to the same stream.
385             * </p>
386             * @param writer the writer to write to
387             * @throws IOException if there's a problem writing to the writer
388             * @throws TemplateException if there's a problem with the freemarker
389             * template
390             * @see Ezvcard
391             * @see <a href="http://microformats.org/wiki/hcard">hCard 1.0</a>
392             */
393            public void writeHtml(Writer writer) throws IOException, TemplateException {
394                    Ezvcard.writeHtml(this).go(writer);
395            }
396    
397            /**
398             * Gets the version attached to this vCard.
399             * @return the vCard version
400             */
401            public VCardVersion getVersion() {
402                    return version;
403            }
404    
405            /**
406             * Sets the version of this vCard. When marshalling a vCard with the
407             * {@link VCardWriter} class, use the {@link VCardWriter#setTargetVersion
408             * setTargetVersion} method to define what version the vCard should be
409             * marshalled as. {@link VCardWriter} <b>does not</b> look at the version
410             * that is set on the VCard object.
411             * @param version the vCard version
412             */
413            public void setVersion(VCardVersion version) {
414                    this.version = version;
415            }
416    
417            /**
418             * Gets the type of entity this vCard represents.
419             * <p>
420             * vCard property name: KIND
421             * </p>
422             * <p>
423             * vCard versions: 4.0
424             * </p>
425             * @return the kind
426             */
427            public KindType getKind() {
428                    return kind;
429            }
430    
431            /**
432             * Sets the type of entity this vCard represents.
433             * <p>
434             * vCard property name: KIND
435             * </p>
436             * <p>
437             * vCard versions: 4.0
438             * </p>
439             * @param kind the kind
440             */
441            public void setKind(KindType kind) {
442                    this.kind = kind;
443            }
444    
445            /**
446             * Gets the gender of the person.
447             * <p>
448             * vCard property name: GENDER
449             * </p>
450             * <p>
451             * vCard versions: 4.0
452             * </p>
453             * @return the gender
454             */
455            public GenderType getGender() {
456                    return gender;
457            }
458    
459            /**
460             * Sets the gender of the person.
461             * <p>
462             * vCard property name: GENDER
463             * </p>
464             * <p>
465             * vCard versions: 4.0
466             * </p>
467             * @param gender the gender
468             */
469            public void setGender(GenderType gender) {
470                    this.gender = gender;
471            }
472    
473            /**
474             * Gets the members of the group. Only valid if the KIND property is set to
475             * "group".
476             * 
477             * <p>
478             * 
479             * <pre>
480             * VCard vcard = ...
481             * KindType kind = vcard.getKind();
482             * if (kind != null && kind.isGroup()){
483             *   for (MemberType member : vcard.getMembers(){
484             *     ...
485             *   }
486             * }
487             * </pre>
488             * 
489             * </p>
490             * 
491             * <p>
492             * vCard property name: MEMBER
493             * </p>
494             * <p>
495             * vCard versions: 4.0
496             * </p>
497             * @return the members
498             */
499            public List<MemberType> getMembers() {
500                    return members;
501            }
502    
503            /**
504             * Adds a member to the group. Only valid if the KIND property is set to
505             * "group".
506             * 
507             * <p>
508             * 
509             * <pre>
510             * VCard vcard = new VCard();
511             * vcard.setKind(KindType.group());
512             * vcard.addMember(...);
513             * </pre>
514             * 
515             * </p>
516             * 
517             * <p>
518             * vCard property name: MEMBER
519             * </p>
520             * <p>
521             * vCard versions: 4.0
522             * </p>
523             * @param member the member to add
524             */
525            public void addMember(MemberType member) {
526                    members.add(member);
527            }
528    
529            /**
530             * Gets the PROFILE property.
531             * <p>
532             * vCard property name: PROFILE
533             * </p>
534             * <p>
535             * vCard versions: 3.0
536             * </p>
537             * @return the property
538             */
539            public ProfileType getProfile() {
540                    return profile;
541            }
542    
543            /**
544             * Sets the PROFILE property.
545             * <p>
546             * vCard property name: PROFILE
547             * </p>
548             * <p>
549             * vCard versions: 3.0
550             * </p>
551             * @param profile the property
552             */
553            public void setProfile(ProfileType profile) {
554                    this.profile = profile;
555            }
556    
557            /**
558             * Gets the classification of the vCard, which describes the sensitivity of
559             * the information in the vCard.
560             * <p>
561             * vCard property name: CLASS
562             * </p>
563             * <p>
564             * vCard versions: 3.0
565             * </p>
566             * @return the classification
567             */
568            public ClassificationType getClassification() {
569                    return classification;
570            }
571    
572            /**
573             * Sets the classification of the vCard, which describes the sensitivity of
574             * the information in the vCard.
575             * <p>
576             * vCard property name: CLASS
577             * </p>
578             * <p>
579             * vCard versions: 3.0
580             * </p>
581             * @param classification the classification
582             */
583            public void setClassification(ClassificationType classification) {
584                    this.classification = classification;
585            }
586    
587            /**
588             * Sets the classification of the vCard, which describes the sensitivity of
589             * the information in the vCard. This is a convenience method for
590             * {@link #setClassification(ClassificationType)}.
591             * <p>
592             * </p>
593             * <p>
594             * vCard property name: CLASS
595             * </p>
596             * <p>
597             * vCard versions: 3.0
598             * </p>
599             * @param classification the classification (e.g. "PUBLIC", "PRIVATE",
600             * "CONFIDENTIAL")
601             * @return the type object that was created
602             */
603            public ClassificationType setClassification(String classification) {
604                    ClassificationType type = new ClassificationType(classification);
605                    setClassification(type);
606                    return type;
607            }
608    
609            /**
610             * Gets the URIs that can be used to retrieve the most up-to-date version of
611             * the person's vCard.
612             * <p>
613             * vCard property name: SOURCE
614             * </p>
615             * <p>
616             * vCard versions: 3.0, 4.0
617             * </p>
618             * @return the sources
619             */
620            public List<SourceType> getSources() {
621                    return sources;
622            }
623    
624            /**
625             * Adds a URI that can be used to retrieve the most up-to-date version of
626             * the person's vCard.
627             * <p>
628             * vCard property name: SOURCE
629             * </p>
630             * <p>
631             * vCard versions: 3.0, 4.0
632             * </p>
633             * @param source the source
634             */
635            public void addSource(SourceType source) {
636                    sources.add(source);
637            }
638    
639            /**
640             * Adds a URI that can be used to retrieve the most up-to-date version of
641             * the person's vCard. This is a convenience method for
642             * {@link #addSource(SourceType)} .
643             * <p>
644             * vCard property name: SOURCE
645             * </p>
646             * <p>
647             * vCard versions: 3.0, 4.0
648             * </p>
649             * @param source the source URI (e.g. "http://example.com/vcard.vcf")
650             * @return the type object that was created
651             */
652            public SourceType addSource(String source) {
653                    SourceType type = new SourceType(source);
654                    addSource(type);
655                    return type;
656            }
657    
658            /**
659             * Gets a textual representation of the SOURCE property.
660             * <p>
661             * vCard property name: NAME
662             * </p>
663             * <p>
664             * vCard versions: 3.0
665             * </p>
666             * @return a textual representation of the vCard source
667             */
668            public SourceDisplayTextType getSourceDisplayText() {
669                    return sourceDisplayText;
670            }
671    
672            /**
673             * Sets a textual representation of the SOURCE property.
674             * <p>
675             * vCard property name: NAME
676             * </p>
677             * <p>
678             * vCard versions: 3.0
679             * </p>
680             * @param sourceDisplayText a textual representation of the vCard source
681             */
682            public void setSourceDisplayText(SourceDisplayTextType sourceDisplayText) {
683                    this.sourceDisplayText = sourceDisplayText;
684            }
685    
686            /**
687             * Sets a textual representation of the SOURCE property. This is a
688             * convenience method for
689             * {@link #setSourceDisplayText(SourceDisplayTextType)}.
690             * <p>
691             * vCard property name: NAME
692             * </p>
693             * <p>
694             * vCard versions: 3.0
695             * </p>
696             * @param sourceDisplayText a textual representation of the vCard source
697             * @return the type object that was created
698             */
699            public SourceDisplayTextType setSourceDisplayText(String sourceDisplayText) {
700                    SourceDisplayTextType type = new SourceDisplayTextType(sourceDisplayText);
701                    setSourceDisplayText(type);
702                    return type;
703            }
704    
705            /**
706             * <p>
707             * Gets the text values for displaying the person's name.
708             * </p>
709             * <p>
710             * This method should only be used on the rare occasion when there are
711             * alternative representations of this property (see:
712             * {@link VCardSubTypes#getAltId explanation of ALTID}). Otherwise, use
713             * {@link #getFormattedName}.
714             * </p>
715             * <p>
716             * vCard property name: FN
717             * </p>
718             * <p>
719             * vCard versions: 2.1, 3.0, 4.0
720             * </p>
721             * @return the formatted name property
722             * @see FormattedNameType#getAltId
723             */
724            public List<FormattedNameType> getFormattedNames() {
725                    return formattedNames;
726            }
727    
728            /**
729             * <p>
730             * Gets the text value used for displaying the person's name.
731             * </p>
732             * <p>
733             * Use {@link #getFormattedNames} to get the alternative representations of
734             * this property (see: {@link VCardSubTypes#getAltId explanation of ALTID}).
735             * </p>
736             * <p>
737             * vCard property name: FN
738             * </p>
739             * <p>
740             * vCard versions: 2.1, 3.0, 4.0
741             * </p>
742             * @return the formatted name property
743             */
744            public FormattedNameType getFormattedName() {
745                    return formattedNames.isEmpty() ? null : formattedNames.get(0);
746            }
747    
748            /**
749             * <p>
750             * Adds a text value used for displaying the person's name.
751             * </p>
752             * <p>
753             * This method should only be used on the rare occasion when alternative
754             * representations of this property are needed (see:
755             * {@link VCardSubTypes#getAltId explanation of ALTID}). Otherwise, use
756             * {@link #setFormattedName(FormattedNameType)}.
757             * </p>
758             * <p>
759             * vCard property name: FN
760             * </p>
761             * <p>
762             * vCard versions: 2.1, 3.0, 4.0
763             * </p>
764             * @param formattedName the formatted name property
765             * @see FormattedNameType#setAltId
766             */
767            public void addFormattedName(FormattedNameType formattedName) {
768                    formattedNames.add(formattedName);
769            }
770    
771            /**
772             * <p>
773             * Sets the text value used for displaying the person's name.
774             * </p>
775             * <p>
776             * Use {@link #addFormattedName} to add alternative representations of this
777             * property (see: {@link VCardSubTypes#getAltId explanation of ALTID}).
778             * </p>
779             * <p>
780             * vCard property name: FN
781             * </p>
782             * <p>
783             * vCard versions: 2.1, 3.0, 4.0
784             * </p>
785             * @param formattedName the formatted name property
786             */
787            public void setFormattedName(FormattedNameType formattedName) {
788                    formattedNames.clear();
789                    addFormattedName(formattedName);
790            }
791    
792            /**
793             * <p>
794             * Sets the text value used for displaying the person's name. This is a
795             * convenience method for {@link #setFormattedName(FormattedNameType)}.
796             * </p>
797             * <p>
798             * Use {@link #addFormattedName} to add alternative representations of this
799             * property (see: {@link VCardSubTypes#getAltId explanation of ALTID}).
800             * </p>
801             * <p>
802             * vCard property name: FN
803             * </p>
804             * <p>
805             * vCard versions: 2.1, 3.0, 4.0
806             * </p>
807             * @param formattedName the formatted name (e.g. "John Doe")
808             * @return the type object that was created
809             */
810            public FormattedNameType setFormattedName(String formattedName) {
811                    FormattedNameType type = new FormattedNameType(formattedName);
812                    setFormattedName(type);
813                    return type;
814            }
815    
816            /**
817             * <p>
818             * Gets all structured name properties.
819             * </p>
820             * <p>
821             * This method should only be used on the rare occasion when there are
822             * alternative representations of this property (see:
823             * {@link VCardSubTypes#getAltId explanation of ALTID}). Otherwise, use
824             * {@link #getStructuredName}.
825             * </p>
826             * <p>
827             * vCard property name: N
828             * </p>
829             * <p>
830             * vCard versions: 2.1, 3.0, 4.0
831             * </p>
832             * @return the N properties
833             * @see StructuredNameType#getAltId
834             */
835            public List<StructuredNameType> getStructuredNames() {
836                    return structuredNames;
837            }
838    
839            /**
840             * <p>
841             * Gets the individual components of the person's name.
842             * </p>
843             * <p>
844             * Use {@link #getStructuredNames} to get the alternative representations of
845             * this property (see: {@link VCardSubTypes#getAltId explanation of ALTID}).
846             * </p>
847             * <p>
848             * vCard property name: N
849             * </p>
850             * <p>
851             * vCard versions: 2.1, 3.0, 4.0
852             * </p>
853             * @return the components of the person's name
854             */
855            public StructuredNameType getStructuredName() {
856                    return structuredNames.isEmpty() ? null : structuredNames.get(0);
857            }
858    
859            /**
860             * <p>
861             * Adds a property that contains the individual components of the person's
862             * name.
863             * </p>
864             * <p>
865             * This method should only be used on the rare occasion when alternative
866             * representations of this property are needed (see:
867             * {@link VCardSubTypes#getAltId explanation of ALTID}). Otherwise, use
868             * {@link #setStructuredName}.
869             * </p>
870             * <p>
871             * vCard property name: N
872             * </p>
873             * <p>
874             * vCard versions: 2.1, 3.0, 4.0
875             * </p>
876             * @param structuredName the components of the person's name
877             * @see StructuredNameType#setAltId
878             */
879            public void addStructuredName(StructuredNameType structuredName) {
880                    structuredNames.add(structuredName);
881            }
882    
883            /**
884             * Sets the individual components of the person's name.
885             * <p>
886             * vCard property name: N
887             * </p>
888             * <p>
889             * vCard versions: 2.1, 3.0, 4.0
890             * </p>
891             * @param structuredName the components of the person's name
892             */
893            public void setStructuredName(StructuredNameType structuredName) {
894                    structuredNames.clear();
895                    addStructuredName(structuredName);
896            }
897    
898            /**
899             * <p>
900             * Gets all instances of the NICKNAME property.
901             * </p>
902             * <p>
903             * This method should only be used on the rare occasion when there are
904             * alternative representations of this property (see:
905             * {@link VCardSubTypes#getAltId explanation of ALTID}). Otherwise, use
906             * {@link #getNickname}.
907             * </p>
908             * <p>
909             * vCard property name: NICKNAME
910             * </p>
911             * <p>
912             * vCard versions: 3.0, 4.0
913             * </p>
914             * @return the person's nicknames
915             * @see NicknameType#getAltId
916             */
917            public List<NicknameType> getNicknames() {
918                    return nicknames;
919            }
920    
921            /**
922             * <p>
923             * Gets the person's nicknames.
924             * </p>
925             * <p>
926             * Use {@link #getNicknames} to get the alternative representations of this
927             * property (see: {@link VCardSubTypes#getAltId explanation of ALTID}).
928             * </p>
929             * <p>
930             * vCard property name: NICKNAME
931             * </p>
932             * <p>
933             * vCard versions: 3.0, 4.0
934             * </p>
935             * @return the person's nicknames
936             */
937            public NicknameType getNickname() {
938                    return nicknames.isEmpty() ? null : nicknames.get(0);
939            }
940    
941            /**
942             * <p>
943             * Adds an instance of the NICKNAME property to the vCard.
944             * </p>
945             * <p>
946             * This method should only be used on the rare occasion when alternative
947             * representations of this property are needed (see:
948             * {@link VCardSubTypes#getAltId explanation of ALTID}). Otherwise, use
949             * {@link #setNickname(NicknameType)}.
950             * </p>
951             * <p>
952             * vCard property name: NICKNAME
953             * </p>
954             * <p>
955             * vCard versions: 3.0, 4.0
956             * </p>
957             * @param nickname the NICKNAME property to add
958             * @see NicknameType#setAltId
959             */
960            public void addNickname(NicknameType nickname) {
961                    nicknames.add(nickname);
962            }
963    
964            /**
965             * <p>
966             * Sets one or more nicknames.
967             * </p>
968             * <p>
969             * Use {@link #addNickname} to add alternative representations of this
970             * property (see: {@link VCardSubTypes#getAltId explanation of ALTID}).
971             * </p>
972             * <p>
973             * vCard property name: NICKNAME
974             * </p>
975             * <p>
976             * vCard versions: 3.0, 4.0
977             * </p>
978             * @param nickname the nicknames (multiple nicknames can be added to this
979             * object)
980             */
981            public void setNickname(NicknameType nickname) {
982                    nicknames.clear();
983                    addNickname(nickname);
984            }
985    
986            /**
987             * <p>
988             * Sets one or more nicknames. This is a convenience method for
989             * {@link #setNickname(NicknameType)}.
990             * </p>
991             * <p>
992             * Use {@link #addNickname} to add alternative representations of this
993             * property (see: {@link VCardSubTypes#getAltId explanation of ALTID}).
994             * </p>
995             * <p>
996             * vCard property name: NICKNAME
997             * </p>
998             * <p>
999             * vCard versions: 3.0, 4.0
1000             * </p>
1001             * @param nicknames the nickname(s)
1002             * @return the type object that was created
1003             */
1004            public NicknameType setNickname(String... nicknames) {
1005                    NicknameType type = new NicknameType();
1006                    for (String nickname : nicknames) {
1007                            type.addValue(nickname);
1008                    }
1009                    setNickname(type);
1010                    return type;
1011            }
1012    
1013            /**
1014             * <p>
1015             * Gets the string that should be used to sort the vCard.
1016             * </p>
1017             * <p>
1018             * For 4.0 vCards, use the {@link StructuredNameType#getSortAs} and/or
1019             * {@link OrganizationType#getSortAs} methods.
1020             * </p>
1021             * <p>
1022             * vCard property name: SORT-STRING
1023             * </p>
1024             * <p>
1025             * vCard versions: 2.1, 3.0
1026             * </p>
1027             * @return the sort string
1028             */
1029            public SortStringType getSortString() {
1030                    return sortString;
1031            }
1032    
1033            /**
1034             * <p>
1035             * Sets the string that should be used to sort the vCard.
1036             * </p>
1037             * <p>
1038             * For 4.0 vCards, use the {@link StructuredNameType#setSortAs} and/or
1039             * {@link OrganizationType#setSortAs} methods.
1040             * </p>
1041             * <p>
1042             * vCard property name: SORT-STRING
1043             * </p>
1044             * <p>
1045             * vCard versions: 2.1, 3.0
1046             * </p>
1047             * @param sortString the sort string
1048             */
1049            public void setSortString(SortStringType sortString) {
1050                    this.sortString = sortString;
1051            }
1052    
1053            /**
1054             * <p>
1055             * Sets the string that should be used to sort the vCard. This is a
1056             * convenience method for {@link #setSortString(SortStringType)}.
1057             * </p>
1058             * <p>
1059             * For 4.0 vCards, use the {@link StructuredNameType#setSortAs} and/or
1060             * {@link OrganizationType#setSortAs} methods.
1061             * </p>
1062             * <p>
1063             * vCard property name: SORT-STRING
1064             * </p>
1065             * <p>
1066             * vCard versions: 2.1, 3.0
1067             * </p>
1068             * @param sortString the sort string (e.g. "Armour" if the person's last
1069             * name is "d'Armour")
1070             * @return the type object that was created
1071             */
1072            public SortStringType setSortString(String sortString) {
1073                    SortStringType type = new SortStringType(sortString);
1074                    setSortString(type);
1075                    return type;
1076            }
1077    
1078            /**
1079             * Gets the titles associated with the person.
1080             * <p>
1081             * vCard property name: TITLE
1082             * </p>
1083             * <p>
1084             * vCard versions: 2.1, 3.0, 4.0
1085             * </p>
1086             * @return the titles
1087             */
1088            public List<TitleType> getTitles() {
1089                    return titles;
1090            }
1091    
1092            /**
1093             * Adds a title associated with the person.
1094             * <p>
1095             * vCard property name: TITLE
1096             * </p>
1097             * <p>
1098             * vCard versions: 2.1, 3.0, 4.0
1099             * </p>
1100             * @param title the title
1101             */
1102            public void addTitle(TitleType title) {
1103                    titles.add(title);
1104            }
1105    
1106            /**
1107             * Adds a title associated with the person. This is a convenience method for
1108             * {@link #addTitle(TitleType)}.
1109             * <p>
1110             * vCard property name: TITLE
1111             * </p>
1112             * <p>
1113             * vCard versions: 2.1, 3.0, 4.0
1114             * </p>
1115             * @param title the title (e.g. "V.P. Research and Development")
1116             * @return the type object that was created
1117             */
1118            public TitleType addTitle(String title) {
1119                    TitleType type = new TitleType(title);
1120                    addTitle(type);
1121                    return type;
1122            }
1123    
1124            /**
1125             * Gets the roles associated with the person.
1126             * <p>
1127             * vCard property name: ROLE
1128             * </p>
1129             * <p>
1130             * vCard versions: 2.1, 3.0, 4.0
1131             * </p>
1132             * @return the roles
1133             */
1134            public List<RoleType> getRoles() {
1135                    return roles;
1136            }
1137    
1138            /**
1139             * Adds a role associated with the person.
1140             * <p>
1141             * vCard property name: ROLE
1142             * </p>
1143             * <p>
1144             * vCard versions: 2.1, 3.0, 4.0
1145             * </p>
1146             * @param role the role
1147             */
1148            public void addRole(RoleType role) {
1149                    roles.add(role);
1150            }
1151    
1152            /**
1153             * Adds a role associated with the person. This is a convenience method for
1154             * {@link #addRole(RoleType)}.
1155             * <p>
1156             * vCard property name: ROLE
1157             * </p>
1158             * <p>
1159             * vCard versions: 2.1, 3.0, 4.0
1160             * </p>
1161             * @param role the role (e.g. "Executive")
1162             * @return the type object that was created
1163             */
1164            public RoleType addRole(String role) {
1165                    RoleType type = new RoleType(role);
1166                    addRole(type);
1167                    return type;
1168            }
1169    
1170            /**
1171             * Gets the photos attached to the vCard, such as a picture of the person's
1172             * face.
1173             * <p>
1174             * vCard property name: PHOTO
1175             * </p>
1176             * <p>
1177             * vCard versions: 2.1, 3.0, 4.0
1178             * </p>
1179             * @return the photos
1180             */
1181            public List<PhotoType> getPhotos() {
1182                    return photos;
1183            }
1184    
1185            /**
1186             * Adds a photo to the vCard, such as a picture of the person's face.
1187             * <p>
1188             * vCard property name: PHOTO
1189             * </p>
1190             * <p>
1191             * vCard versions: 2.1, 3.0, 4.0
1192             * </p>
1193             * @param photo the photo to add
1194             */
1195            public void addPhoto(PhotoType photo) {
1196                    photos.add(photo);
1197            }
1198    
1199            /**
1200             * Gets the logos attached to the vCard, such a company logo.
1201             * <p>
1202             * vCard property name: LOGO
1203             * </p>
1204             * <p>
1205             * vCard versions: 2.1, 3.0, 4.0
1206             * </p>
1207             * @return the logos
1208             */
1209            public List<LogoType> getLogos() {
1210                    return logos;
1211            }
1212    
1213            /**
1214             * Adds a logo to the vCard, such as a company logo.
1215             * <p>
1216             * vCard property name: LOGO
1217             * </p>
1218             * <p>
1219             * vCard versions: 2.1, 3.0, 4.0
1220             * </p>
1221             * @param logo the logo to add
1222             */
1223            public void addLogo(LogoType logo) {
1224                    logos.add(logo);
1225            }
1226    
1227            /**
1228             * Gets the sounds attached to the vCard, such as a pronunciation of the
1229             * person's name.
1230             * <p>
1231             * vCard property name: SOUND
1232             * </p>
1233             * <p>
1234             * vCard versions: 2.1, 3.0, 4.0
1235             * </p>
1236             * @return the sounds
1237             */
1238            public List<SoundType> getSounds() {
1239                    return sounds;
1240            }
1241    
1242            /**
1243             * Adds a sound to the vCard, such as a pronunciation of the person's name.
1244             * <p>
1245             * vCard property name: SOUND
1246             * </p>
1247             * <p>
1248             * vCard versions: 2.1, 3.0, 4.0
1249             * </p>
1250             * @param sound the sound to add
1251             */
1252            public void addSound(SoundType sound) {
1253                    sounds.add(sound);
1254            }
1255    
1256            /**
1257             * <p>
1258             * Gets all birthplace property instances.
1259             * </p>
1260             * <p>
1261             * This method should only be used on the rare occasion when there are
1262             * alternative representations of this property (see:
1263             * {@link VCardSubTypes#getAltId explanation of ALTID}). Otherwise, use
1264             * {@link #getBirthplace}.
1265             * </p>
1266             * <p>
1267             * vCard property name: BIRTHPLACE
1268             * </p>
1269             * <p>
1270             * vCard versions: 4.0
1271             * </p>
1272             * @return the birthplace properties
1273             * @see BirthplaceType#getAltId
1274             * @see <a href="http://tools.ietf.org/html/rfc6474">RFC 6474</a>
1275             */
1276            public List<BirthplaceType> getBirthplaces() {
1277                    return birthplaces;
1278            }
1279    
1280            /**
1281             * <p>
1282             * Adds a birthplace property.
1283             * </p>
1284             * <p>
1285             * This method should only be used on the rare occasion when alternative
1286             * representations of this property are needed (see:
1287             * {@link VCardSubTypes#getAltId explanation of ALTID}). Otherwise, use
1288             * {@link #setBirthplace}.
1289             * </p>
1290             * <p>
1291             * vCard property name: BIRTHPLACE
1292             * </p>
1293             * <p>
1294             * vCard versions: 4.0
1295             * </p>
1296             * @param birthplace the birthplace to add
1297             * @see BirthplaceType#setAltId
1298             * @see <a href="http://tools.ietf.org/html/rfc6474">RFC 6474</a>
1299             */
1300            public void addBirthplace(BirthplaceType birthplace) {
1301                    birthplaces.add(birthplace);
1302            }
1303    
1304            /**
1305             * <p>
1306             * Gets the person's birthplace.
1307             * </p>
1308             * <p>
1309             * Use {@link #getBirthplaces} to get the alternative representations of
1310             * this property (see: {@link VCardSubTypes#getAltId explanation of ALTID}).
1311             * </p>
1312             * <p>
1313             * vCard property name: BIRTHPLACE
1314             * </p>
1315             * <p>
1316             * vCard versions: 4.0
1317             * </p>
1318             * @return the birthplace
1319             * @see <a href="http://tools.ietf.org/html/rfc6474">RFC 6474</a>
1320             */
1321            public BirthplaceType getBirthplace() {
1322                    return birthplaces.isEmpty() ? null : birthplaces.get(0);
1323            }
1324    
1325            /**
1326             * <p>
1327             * Sets the person's birthplace.
1328             * </p>
1329             * <p>
1330             * Use {@link #addBirthplace} to add alternative representations of this
1331             * property (see: {@link VCardSubTypes#getAltId explanation of ALTID}).
1332             * </p>
1333             * <p>
1334             * vCard property name: BIRTHPLACE
1335             * </p>
1336             * <p>
1337             * vCard versions: 4.0
1338             * </p>
1339             * @param birthplace the birthplace
1340             * @see <a href="http://tools.ietf.org/html/rfc6474">RFC 6474</a>
1341             */
1342            public void setBirthplace(BirthplaceType birthplace) {
1343                    birthplaces.clear();
1344                    addBirthplace(birthplace);
1345            }
1346    
1347            /**
1348             * <p>
1349             * Gets all deathplace property instances.
1350             * </p>
1351             * <p>
1352             * This method should only be used on the rare occasion when there are
1353             * alternative representations of this property (see:
1354             * {@link VCardSubTypes#getAltId explanation of ALTID}). Otherwise, use
1355             * {@link #getDeathplace}.
1356             * </p>
1357             * <p>
1358             * vCard property name: DEATHPLACE
1359             * </p>
1360             * <p>
1361             * vCard versions: 4.0
1362             * </p>
1363             * @return the deathplace properties
1364             * @see DeathplaceType#getAltId
1365             * @see <a href="http://tools.ietf.org/html/rfc6474">RFC 6474</a>
1366             */
1367            public List<DeathplaceType> getDeathplaces() {
1368                    return deathplaces;
1369            }
1370    
1371            /**
1372             * <p>
1373             * Adds a deathplace property.
1374             * </p>
1375             * <p>
1376             * This method should only be used on the rare occasion when alternative
1377             * representations of this property are needed (see:
1378             * {@link VCardSubTypes#getAltId explanation of ALTID}). Otherwise, use
1379             * {@link #setDeathplace}.
1380             * </p>
1381             * <p>
1382             * vCard property name: DEATHPLACE
1383             * </p>
1384             * <p>
1385             * vCard versions: 4.0
1386             * </p>
1387             * @param deathplace the deathplace to add
1388             * @see DeathplaceType#setAltId
1389             * @see <a href="http://tools.ietf.org/html/rfc6474">RFC 6474</a>
1390             */
1391            public void addDeathplace(DeathplaceType deathplace) {
1392                    deathplaces.add(deathplace);
1393            }
1394    
1395            /**
1396             * <p>
1397             * Gets the person's deathplace.
1398             * </p>
1399             * <p>
1400             * Use {@link #getDeathplaces} to get the alternative representations of
1401             * this property (see: {@link VCardSubTypes#getAltId explanation of ALTID}).
1402             * </p>
1403             * <p>
1404             * vCard property name: DEATHPLACE
1405             * </p>
1406             * <p>
1407             * vCard versions: 4.0
1408             * </p>
1409             * @return the deathplace
1410             * @see <a href="http://tools.ietf.org/html/rfc6474">RFC 6474</a>
1411             */
1412            public DeathplaceType getDeathplace() {
1413                    return deathplaces.isEmpty() ? null : deathplaces.get(0);
1414            }
1415    
1416            /**
1417             * <p>
1418             * Sets the person's deathplace.
1419             * </p>
1420             * <p>
1421             * Use {@link #addDeathplace} to add alternative representations of this
1422             * property (see: {@link VCardSubTypes#getAltId explanation of ALTID}).
1423             * </p>
1424             * <p>
1425             * vCard property name: DEATHPLACE
1426             * </p>
1427             * <p>
1428             * vCard versions: 4.0
1429             * </p>
1430             * @param deathplace the deathplace
1431             * @see <a href="http://tools.ietf.org/html/rfc6474">RFC 6474</a>
1432             */
1433            public void setDeathplace(DeathplaceType deathplace) {
1434                    deathplaces.clear();
1435                    addDeathplace(deathplace);
1436            }
1437    
1438            /**
1439             * <p>
1440             * Gets all death date property instances.
1441             * </p>
1442             * <p>
1443             * This method should only be used on the rare occasion when there are
1444             * alternative representations of this property (see:
1445             * {@link VCardSubTypes#getAltId explanation of ALTID}). Otherwise, use
1446             * {@link #getDeathdate}.
1447             * </p>
1448             * <p>
1449             * vCard property name: DEATHDATE
1450             * </p>
1451             * <p>
1452             * vCard versions: 4.0
1453             * </p>
1454             * @return the death date properties
1455             * @see DeathdateType#getAltId
1456             * @see <a href="http://tools.ietf.org/html/rfc6474">RFC 6474</a>
1457             */
1458            public List<DeathdateType> getDeathdates() {
1459                    return deathdates;
1460            }
1461    
1462            /**
1463             * <p>
1464             * Adds a death date property.
1465             * </p>
1466             * <p>
1467             * This method should only be used on the rare occasion when alternative
1468             * representations of this property are needed (see:
1469             * {@link VCardSubTypes#getAltId explanation of ALTID}). Otherwise, use
1470             * {@link #setDeathdate}.
1471             * </p>
1472             * <p>
1473             * vCard property name: DEATHDATE
1474             * </p>
1475             * <p>
1476             * vCard versions: 4.0
1477             * </p>
1478             * @param deathdate the death date to add
1479             * @see DeathdateType#setAltId
1480             * @see <a href="http://tools.ietf.org/html/rfc6474">RFC 6474</a>
1481             */
1482            public void addDeathdate(DeathdateType deathdate) {
1483                    deathdates.add(deathdate);
1484            }
1485    
1486            /**
1487             * <p>
1488             * Gets the person's time of death.
1489             * </p>
1490             * <p>
1491             * Use {@link #getDeathdates} to get the alternative representations of this
1492             * property (see: {@link VCardSubTypes#getAltId explanation of ALTID}).
1493             * </p>
1494             * <p>
1495             * vCard property name: DEATHDATE
1496             * </p>
1497             * <p>
1498             * vCard versions: 4.0
1499             * </p>
1500             * @return the time of death
1501             * @see <a href="http://tools.ietf.org/html/rfc6474">RFC 6474</a>
1502             */
1503            public DeathdateType getDeathdate() {
1504                    return deathdates.isEmpty() ? null : deathdates.get(0);
1505            }
1506    
1507            /**
1508             * <p>
1509             * Sets the person's time of death.
1510             * </p>
1511             * <p>
1512             * Use {@link #addDeathdate} to add alternative representations of this
1513             * property (see: {@link VCardSubTypes#getAltId explanation of ALTID}).
1514             * </p>
1515             * <p>
1516             * vCard property name: DEATHDATE
1517             * </p>
1518             * <p>
1519             * vCard versions: 4.0
1520             * </p>
1521             * @param deathdate the time of death
1522             * @see <a href="http://tools.ietf.org/html/rfc6474">RFC 6474</a>
1523             */
1524            public void setDeathdate(DeathdateType deathdate) {
1525                    deathdates.clear();
1526                    addDeathdate(deathdate);
1527            }
1528    
1529            /**
1530             * <p>
1531             * Gets all birthday property instances.
1532             * </p>
1533             * <p>
1534             * This method should only be used on the rare occasion when there are
1535             * alternative representations of this property (see:
1536             * {@link VCardSubTypes#getAltId explanation of ALTID}). Otherwise, use
1537             * {@link #getBirthday}.
1538             * </p>
1539             * <p>
1540             * vCard property name: BDAY
1541             * </p>
1542             * <p>
1543             * vCard versions: 2.1, 3.0, 4.0
1544             * </p>
1545             * @return the birthday properties
1546             * @see BirthdayType#getAltId
1547             */
1548            public List<BirthdayType> getBirthdays() {
1549                    return birthdays;
1550            }
1551    
1552            /**
1553             * <p>
1554             * Adds a birthday property.
1555             * </p>
1556             * <p>
1557             * This method should only be used on the rare occasion when alternative
1558             * representations of this property are needed (see:
1559             * {@link VCardSubTypes#getAltId explanation of ALTID}). Otherwise, use
1560             * {@link #setBirthday}.
1561             * </p>
1562             * <p>
1563             * vCard property name: BDAY
1564             * </p>
1565             * <p>
1566             * vCard versions: 2.1, 3.0, 4.0
1567             * </p>
1568             * @param birthday the birthday to add
1569             * @see BirthdayType#setAltId
1570             */
1571            public void addBirthday(BirthdayType birthday) {
1572                    birthdays.add(birthday);
1573            }
1574    
1575            /**
1576             * <p>
1577             * Gets the person's birthday.
1578             * </p>
1579             * <p>
1580             * Use {@link #getBirthdays} to get the alternative representations of this
1581             * property (see: {@link VCardSubTypes#getAltId explanation of ALTID}).
1582             * </p>
1583             * <p>
1584             * vCard property name: BDAY
1585             * </p>
1586             * <p>
1587             * vCard versions: 2.1, 3.0, 4.0
1588             * </p>
1589             * @return the birthday
1590             */
1591            public BirthdayType getBirthday() {
1592                    return birthdays.isEmpty() ? null : birthdays.get(0);
1593            }
1594    
1595            /**
1596             * <p>
1597             * Sets the person's birthday.
1598             * </p>
1599             * <p>
1600             * Use {@link #addBirthday} to add alternative representations of this
1601             * property (see: {@link VCardSubTypes#getAltId explanation of ALTID}).
1602             * </p>
1603             * <p>
1604             * vCard property name: BDAY
1605             * </p>
1606             * <p>
1607             * vCard versions: 2.1, 3.0, 4.0
1608             * </p>
1609             * @param birthday the birthday
1610             */
1611            public void setBirthday(BirthdayType birthday) {
1612                    birthdays.clear();
1613                    addBirthday(birthday);
1614            }
1615    
1616            /**
1617             * <p>
1618             * Gets all anniversary property instances.
1619             * </p>
1620             * <p>
1621             * This method should only be used on the rare occasion when there are
1622             * alternative representations of this property (see:
1623             * {@link VCardSubTypes#getAltId explanation of ALTID}). Otherwise, use
1624             * {@link #getAnniversary}.
1625             * </p>
1626             * <p>
1627             * vCard property name: ANNIVERSARY
1628             * </p>
1629             * <p>
1630             * vCard versions: 4.0
1631             * </p>
1632             * @return the death date properties
1633             * @see AnniversaryType#getAltId
1634             */
1635            public List<AnniversaryType> getAnniversaries() {
1636                    return anniversaries;
1637            }
1638    
1639            /**
1640             * <p>
1641             * Adds an anniversary property.
1642             * </p>
1643             * <p>
1644             * This method should only be used on the rare occasion when alternative
1645             * representations of this property are needed (see:
1646             * {@link VCardSubTypes#getAltId explanation of ALTID}). Otherwise, use
1647             * {@link #setAnniversary}.
1648             * </p>
1649             * <p>
1650             * vCard property name: ANNIVERSARY
1651             * </p>
1652             * <p>
1653             * vCard versions: 4.0
1654             * </p>
1655             * @param anniversary the anniversary to add
1656             * @see AnniversaryType#setAltId
1657             */
1658            public void addAnniversary(AnniversaryType anniversary) {
1659                    anniversaries.add(anniversary);
1660            }
1661    
1662            /**
1663             * <p>
1664             * Gets the person's anniversary.
1665             * </p>
1666             * <p>
1667             * Use {@link #getAnniversaries} to get the alternative representations of
1668             * this property (see: {@link VCardSubTypes#getAltId explanation of ALTID}).
1669             * </p>
1670             * <p>
1671             * vCard property name: ANNIVERSARY
1672             * </p>
1673             * <p>
1674             * vCard versions: 4.0
1675             * </p>
1676             * @return the anniversary
1677             */
1678            public AnniversaryType getAnniversary() {
1679                    return anniversaries.isEmpty() ? null : anniversaries.get(0);
1680            }
1681    
1682            /**
1683             * <p>
1684             * Sets the person's anniversary.
1685             * </p>
1686             * <p>
1687             * Use {@link #addAnniversary} to add alternative representations of this
1688             * property (see: {@link VCardSubTypes#getAltId explanation of ALTID}).
1689             * </p>
1690             * <p>
1691             * vCard property name: ANNIVERSARY
1692             * </p>
1693             * <p>
1694             * vCard versions: 4.0
1695             * </p>
1696             * @param anniversary the anniversary
1697             */
1698            public void setAnniversary(AnniversaryType anniversary) {
1699                    anniversaries.clear();
1700                    addAnniversary(anniversary);
1701            }
1702    
1703            /**
1704             * Gets the time that the vCard was last modified.
1705             * <p>
1706             * vCard property name: REV
1707             * </p>
1708             * <p>
1709             * vCard versions: 2.1, 3.0, 4.0
1710             * </p>
1711             * @return the last modified time
1712             */
1713            public RevisionType getRevision() {
1714                    return rev;
1715            }
1716    
1717            /**
1718             * Sets the time that the vCard was last modified.
1719             * <p>
1720             * vCard property name: REV
1721             * </p>
1722             * <p>
1723             * vCard versions: 2.1, 3.0, 4.0
1724             * </p>
1725             * @param rev the last modified time
1726             */
1727            public void setRevision(RevisionType rev) {
1728                    this.rev = rev;
1729            }
1730    
1731            /**
1732             * Sets the time that the vCard was last modified. This is a convenience
1733             * method for {@link #setRevision(RevisionType)}.
1734             * <p>
1735             * vCard property name: REV
1736             * </p>
1737             * <p>
1738             * vCard versions: 2.1, 3.0, 4.0
1739             * </p>
1740             * @param rev the last modified time
1741             * @return the type object that was created
1742             */
1743            public RevisionType setRevision(Date rev) {
1744                    RevisionType type = new RevisionType(rev);
1745                    setRevision(type);
1746                    return type;
1747            }
1748    
1749            /**
1750             * Gets the product ID, which identifies the software that created the
1751             * vCard.
1752             * <p>
1753             * vCard property name: PRODID
1754             * </p>
1755             * <p>
1756             * vCard versions: 3.0, 4.0
1757             * </p>
1758             * @return the product ID
1759             */
1760            public ProdIdType getProdId() {
1761                    return prodId;
1762            }
1763    
1764            /**
1765             * Sets the product ID, which identifies the software that created the
1766             * vCard.
1767             * <p>
1768             * vCard property name: PRODID
1769             * </p>
1770             * <p>
1771             * vCard versions: 3.0, 4.0
1772             * </p>
1773             * @param prodId the product ID
1774             */
1775            public void setProdId(ProdIdType prodId) {
1776                    this.prodId = prodId;
1777            }
1778    
1779            /**
1780             * Sets the product ID, which identifies the software that created the
1781             * vCard. This is a convenience method for {@link #setProdId(ProdIdType)}.
1782             * <p>
1783             * vCard property name: PRODID
1784             * </p>
1785             * <p>
1786             * vCard versions: 3.0, 4.0
1787             * </p>
1788             * @param prodId the product ID (e.g. "ez-vcard 1.0")
1789             * @return the type object that was created
1790             */
1791            public ProdIdType setProdId(String prodId) {
1792                    ProdIdType type = new ProdIdType(prodId);
1793                    setProdId(type);
1794                    return type;
1795            }
1796    
1797            /**
1798             * Gets the mailing addresses.
1799             * <p>
1800             * vCard property name: ADR
1801             * </p>
1802             * <p>
1803             * vCard versions: 2.1, 3.0, 4.0
1804             * </p>
1805             * @return the mailing addresses
1806             */
1807            public List<AddressType> getAddresses() {
1808                    return addresses;
1809            }
1810    
1811            /**
1812             * Adds a mailing address.
1813             * <p>
1814             * vCard property name: ADR
1815             * </p>
1816             * <p>
1817             * vCard versions: 2.1, 3.0, 4.0
1818             * </p>
1819             * @param address the mailing address to add
1820             */
1821            public void addAddress(AddressType address) {
1822                    addresses.add(address);
1823            }
1824    
1825            /**
1826             * Gets all mailing labels that could not be assigned to an address. Use
1827             * {@link AddressType#getLabel} to get a label that has been assigned to an
1828             * address.
1829             * <p>
1830             * vCard property name: LABEL
1831             * </p>
1832             * <p>
1833             * vCard versions: 2.1, 3.0
1834             * </p>
1835             * @return the orphaned labels
1836             */
1837            public List<LabelType> getOrphanedLabels() {
1838                    return labels;
1839            }
1840    
1841            /**
1842             * Adds a mailing label which is not associated with any address. Use of
1843             * this method is discouraged. To add a mailing label to an address, use the
1844             * {@link AddressType#setLabel} method.
1845             * <p>
1846             * vCard property name: LABEL
1847             * </p>
1848             * <p>
1849             * vCard versions: 2.1, 3.0
1850             * </p>
1851             * @param label the orphaned label to add
1852             */
1853            public void addOrphanedLabel(LabelType label) {
1854                    labels.add(label);
1855            }
1856    
1857            /**
1858             * Gets the email addresses.
1859             * <p>
1860             * vCard property name: EMAIL
1861             * </p>
1862             * <p>
1863             * vCard versions: 2.1, 3.0, 4.0
1864             * </p>
1865             * @return the email addresses
1866             */
1867            public List<EmailType> getEmails() {
1868                    return emails;
1869            }
1870    
1871            /**
1872             * Adds an email address.
1873             * <p>
1874             * vCard property name: EMAIL
1875             * </p>
1876             * <p>
1877             * vCard versions: 2.1, 3.0, 4.0
1878             * </p>
1879             * @param email the email address to add
1880             */
1881            public void addEmail(EmailType email) {
1882                    emails.add(email);
1883            }
1884    
1885            /**
1886             * Adds an email address. This is a convenience method for
1887             * {@link #addEmail(EmailType)}.
1888             * <p>
1889             * vCard property name: EMAIL
1890             * </p>
1891             * <p>
1892             * vCard versions: 2.1, 3.0, 4.0
1893             * </p>
1894             * @param email the email address to add (e.g. "johndoe@aol.com")
1895             * @param types the type(s) to assign to the email
1896             * @return the type object that was created
1897             */
1898            public EmailType addEmail(String email, EmailTypeParameter... types) {
1899                    EmailType type = new EmailType(email);
1900                    for (EmailTypeParameter t : types) {
1901                            type.addType(t);
1902                    }
1903                    addEmail(type);
1904                    return type;
1905            }
1906    
1907            /**
1908             * Gets the telephone numbers.
1909             * <p>
1910             * vCard property name: TEL
1911             * </p>
1912             * <p>
1913             * vCard versions: 2.1, 3.0, 4.0
1914             * </p>
1915             * @return the telephone numbers
1916             */
1917            public List<TelephoneType> getTelephoneNumbers() {
1918                    return telephoneNumbers;
1919            }
1920    
1921            /**
1922             * Adds a telephone number.
1923             * <p>
1924             * vCard property name: TEL
1925             * </p>
1926             * <p>
1927             * vCard versions: 2.1, 3.0, 4.0
1928             * </p>
1929             * @param telephoneNumber the telephone number to add
1930             */
1931            public void addTelephoneNumber(TelephoneType telephoneNumber) {
1932                    telephoneNumbers.add(telephoneNumber);
1933            }
1934    
1935            /**
1936             * Adds a telephone number. This is a convenience method for
1937             * {@link #addTelephoneNumber(TelephoneType)}.
1938             * <p>
1939             * vCard property name: TEL
1940             * </p>
1941             * <p>
1942             * vCard versions: 2.1, 3.0, 4.0
1943             * </p>
1944             * @param telephoneNumber the telephone number to add (e.g.
1945             * "+1 555-555-5555")
1946             * @param types the type(s) to assign to the telephone number (e.g. "cell",
1947             * "work", etc)
1948             * @return the type object that was created
1949             */
1950            public TelephoneType addTelephoneNumber(String telephoneNumber, TelephoneTypeParameter... types) {
1951                    TelephoneType type = new TelephoneType(telephoneNumber);
1952                    for (TelephoneTypeParameter t : types) {
1953                            type.addType(t);
1954                    }
1955                    addTelephoneNumber(type);
1956                    return type;
1957            }
1958    
1959            /**
1960             * Gets the email client that the person uses.
1961             * <p>
1962             * vCard property name: MAILER
1963             * </p>
1964             * <p>
1965             * vCard versions: 2.1, 3.0
1966             * </p>
1967             * @return the email client
1968             */
1969            public MailerType getMailer() {
1970                    return mailer;
1971            }
1972    
1973            /**
1974             * Sets the email client that the person uses.
1975             * <p>
1976             * vCard property name: MAILER
1977             * </p>
1978             * <p>
1979             * vCard versions: 2.1, 3.0
1980             * </p>
1981             * @param mailer the email client
1982             */
1983            public void setMailer(MailerType mailer) {
1984                    this.mailer = mailer;
1985            }
1986    
1987            /**
1988             * Sets the email client that the person uses. This is a convenience method
1989             * for {@link #setMailer(MailerType)}.
1990             * <p>
1991             * vCard property name: MAILER
1992             * </p>
1993             * <p>
1994             * vCard versions: 2.1, 3.0
1995             * </p>
1996             * @param mailer the email client (e.g. "Thunderbird")
1997             * @return the type object that was created
1998             */
1999            public MailerType setMailer(String mailer) {
2000                    MailerType type = new MailerType(mailer);
2001                    setMailer(type);
2002                    return type;
2003            }
2004    
2005            /**
2006             * Gets the URLs. URLs can point to websites such as a personal homepage or
2007             * business website.
2008             * <p>
2009             * vCard property name: URL
2010             * </p>
2011             * <p>
2012             * vCard versions: 2.1, 3.0, 4.0
2013             * </p>
2014             * @return the URLs
2015             */
2016            public List<UrlType> getUrls() {
2017                    return urls;
2018            }
2019    
2020            /**
2021             * Adds a URL. URLs can point to websites such as a personal homepage or
2022             * business website.
2023             * <p>
2024             * vCard property name: URL
2025             * </p>
2026             * <p>
2027             * vCard versions: 2.1, 3.0, 4.0
2028             * </p>
2029             * @param url the URL to add
2030             */
2031            public void addUrl(UrlType url) {
2032                    urls.add(url);
2033            }
2034    
2035            /**
2036             * Adds a URL. URLs can point to websites such as a personal homepage or
2037             * business website. This is a convenience method for
2038             * {@link #addUrl(UrlType)}.
2039             * <p>
2040             * vCard property name: URL
2041             * </p>
2042             * <p>
2043             * vCard versions: 2.1, 3.0, 4.0
2044             * </p>
2045             * @param url the URL to add (e.g. "http://example.com")
2046             * @return the type object that was created
2047             */
2048            public UrlType addUrl(String url) {
2049                    UrlType type = new UrlType(url);
2050                    addUrl(type);
2051                    return type;
2052            }
2053    
2054            /**
2055             * <p>
2056             * Gets all instances of the timezone property.
2057             * </p>
2058             * <p>
2059             * This method should only be used on the rare occasion when there are
2060             * alternative representations of this property (see:
2061             * {@link VCardSubTypes#getAltId explanation of ALTID}). Otherwise, use
2062             * {@link #getTimezone}.
2063             * </p>
2064             * <p>
2065             * vCard property name: TZ
2066             * </p>
2067             * <p>
2068             * vCard versions: 2.1, 3.0, 4.0
2069             * </p>
2070             * @return the timezones
2071             * @see TimezoneType#getAltId
2072             */
2073            public List<TimezoneType> getTimezones() {
2074                    return timezones;
2075            }
2076    
2077            /**
2078             * <p>
2079             * Gets the timezone the person lives/works in.
2080             * </p>
2081             * <p>
2082             * Use {@link #getTimezones} to get the alternative representations of this
2083             * property (see: {@link VCardSubTypes#getAltId explanation of ALTID}).
2084             * </p>
2085             * <p>
2086             * vCard property name: TZ
2087             * </p>
2088             * <p>
2089             * vCard versions: 2.1, 3.0, 4.0
2090             * </p>
2091             * @return the timezone
2092             */
2093            public TimezoneType getTimezone() {
2094                    return timezones.isEmpty() ? null : timezones.get(0);
2095            }
2096    
2097            /**
2098             * <p>
2099             * Sets the timezone the person lives/works in.
2100             * </p>
2101             * <p>
2102             * Use {@link #addTimezone} to add alternative representations of this
2103             * property (see: {@link VCardSubTypes#getAltId explanation of ALTID}).
2104             * </p>
2105             * <p>
2106             * vCard property name: TZ
2107             * </p>
2108             * <p>
2109             * vCard versions: 2.1, 3.0, 4.0
2110             * </p>
2111             * @param timezone the timezone
2112             */
2113            public void setTimezone(TimezoneType timezone) {
2114                    timezones.clear();
2115                    addTimezone(timezone);
2116            }
2117    
2118            /**
2119             * <p>
2120             * Adds a timezone to the vCard.
2121             * </p>
2122             * <p>
2123             * This method should only be used on the rare occasion when alternative
2124             * representations of this property are needed (see:
2125             * {@link VCardSubTypes#getAltId explanation of ALTID}). Otherwise, use
2126             * {@link #setTimezone}.
2127             * </p>
2128             * <p>
2129             * vCard property name: TZ
2130             * </p>
2131             * <p>
2132             * vCard versions: 2.1, 3.0, 4.0
2133             * </p>
2134             * @param timezone the timezone to add
2135             * @see TimezoneType#setAltId
2136             */
2137            public void addTimezone(TimezoneType timezone) {
2138                    timezones.add(timezone);
2139            }
2140    
2141            /**
2142             * <p>
2143             * Gets all geographical position properties.
2144             * </p>
2145             * <p>
2146             * This method should only be used on the rare occasion when there are
2147             * alternative representations of this property (see:
2148             * {@link VCardSubTypes#getAltId explanation of ALTID}). Otherwise, use
2149             * {@link #getGeo}.
2150             * </p>
2151             * <p>
2152             * vCard property name: GEO
2153             * </p>
2154             * <p>
2155             * vCard versions: 2.1, 3.0, 4.0
2156             * </p>
2157             * @return the geographical positions
2158             * @see GeoType#getAltId
2159             */
2160            public List<GeoType> getGeos() {
2161                    return geos;
2162            }
2163    
2164            /**
2165             * <p>
2166             * Gets the geographical position of where the person lives/works.
2167             * </p>
2168             * <p>
2169             * Use {@link #getGeos} to get the alternative representations of this
2170             * property (see: {@link VCardSubTypes#getAltId explanation of ALTID}).
2171             * </p>
2172             * <p>
2173             * vCard property name: GEO
2174             * </p>
2175             * <p>
2176             * vCard versions: 2.1, 3.0, 4.0
2177             * </p>
2178             * @return the geographical position
2179             */
2180            public GeoType getGeo() {
2181                    return geos.isEmpty() ? null : geos.get(0);
2182            }
2183    
2184            /**
2185             * <p>
2186             * Sets the geographical position of where the person lives/works.
2187             * </p>
2188             * <p>
2189             * Use {@link #addGeo} to add alternative representations of this property
2190             * (see: {@link VCardSubTypes#getAltId explanation of ALTID}).
2191             * </p>
2192             * <p>
2193             * vCard property name: GEO
2194             * </p>
2195             * <p>
2196             * vCard versions: 2.1, 3.0, 4.0
2197             * </p>
2198             * @param geo the geographical position
2199             */
2200            public void setGeo(GeoType geo) {
2201                    geos.clear();
2202                    addGeo(geo);
2203            }
2204    
2205            /**
2206             * <p>
2207             * Sets the geographical position of where the person lives/works. This is a
2208             * convenience method for {@link #setGeo(GeoType)}.
2209             * </p>
2210             * <p>
2211             * Use {@link #addGeo} to add alternative representations of this property
2212             * (see: {@link VCardSubTypes#getAltId explanation of ALTID}).
2213             * </p>
2214             * <p>
2215             * vCard property name: GEO
2216             * </p>
2217             * <p>
2218             * vCard versions: 2.1, 3.0, 4.0
2219             * </p>
2220             * @param latitude the latitude
2221             * @param longitude the longitude
2222             * @return the type object that was created
2223             */
2224            public GeoType setGeo(double latitude, double longitude) {
2225                    GeoType type = new GeoType(latitude, longitude);
2226                    setGeo(type);
2227                    return type;
2228            }
2229    
2230            /**
2231             * <p>
2232             * Adds a geographical position to the vCard.
2233             * </p>
2234             * <p>
2235             * This method should only be used on the rare occasion when alternative
2236             * representations of this property are needed (see:
2237             * {@link VCardSubTypes#getAltId explanation of ALTID}). Otherwise, use
2238             * {@link #setGeo(GeoType)}.
2239             * </p>
2240             * <p>
2241             * vCard property name: GEO
2242             * </p>
2243             * <p>
2244             * vCard versions: 2.1, 3.0, 4.0
2245             * </p>
2246             * @param geo the geographical position to add
2247             * @see GeoType#setAltId
2248             */
2249            public void addGeo(GeoType geo) {
2250                    geos.add(geo);
2251            }
2252    
2253            /**
2254             * <p>
2255             * Gets the hierarchy of department(s) to which the person belongs.
2256             * </p>
2257             * <p>
2258             * Use {@link #getOrganizations} to get the alternative representations of
2259             * this property (see: {@link VCardSubTypes#getAltId explanation of ALTID}).
2260             * </p>
2261             * <p>
2262             * vCard property name: ORG
2263             * </p>
2264             * <p>
2265             * vCard versions: 2.1, 3.0, 4.0
2266             * </p>
2267             * @return the department(s)
2268             */
2269            public OrganizationType getOrganization() {
2270                    return organizations.isEmpty() ? null : organizations.get(0);
2271            }
2272    
2273            /**
2274             * <p>
2275             * Gets all organization properties.
2276             * </p>
2277             * <p>
2278             * This method should only be used on the rare occasion when there are
2279             * alternative representations of this property (see:
2280             * {@link VCardSubTypes#getAltId explanation of ALTID}). Otherwise, use
2281             * {@link #getOrganization}.
2282             * </p>
2283             * <p>
2284             * vCard property name: ORG
2285             * </p>
2286             * <p>
2287             * vCard versions: 2.1, 3.0, 4.0
2288             * </p>
2289             * @return the organization properties
2290             * @see OrganizationType#getAltId
2291             */
2292            public List<OrganizationType> getOrganizations() {
2293                    return organizations;
2294            }
2295    
2296            /**
2297             * <p>
2298             * Adds an organization property to the vCard.
2299             * </p>
2300             * <p>
2301             * This method should only be used on the rare occasion when alternative
2302             * representations of this property are needed (see:
2303             * {@link VCardSubTypes#getAltId explanation of ALTID}). Otherwise, use
2304             * {@link #setOrganization(OrganizationType)}.
2305             * </p>
2306             * <p>
2307             * vCard property name: ORG
2308             * </p>
2309             * <p>
2310             * vCard versions: 2.1, 3.0, 4.0
2311             * </p>
2312             * @param organization the organization type object to add
2313             * @see OrganizationType#setAltId
2314             */
2315            public void addOrganization(OrganizationType organization) {
2316                    organizations.add(organization);
2317            }
2318    
2319            /**
2320             * <p>
2321             * Sets the hierarchy of departments to which the person belongs.
2322             * </p>
2323             * <p>
2324             * Use {@link #addOrganization} to add alternative representations of this
2325             * property (see: {@link VCardSubTypes#getAltId explanation of ALTID}).
2326             * </p>
2327             * <p>
2328             * vCard property name: ORG
2329             * </p>
2330             * <p>
2331             * vCard versions: 2.1, 3.0, 4.0
2332             * </p>
2333             * @param organization the organization type object
2334             */
2335            public void setOrganization(OrganizationType organization) {
2336                    organizations.clear();
2337                    addOrganization(organization);
2338            }
2339    
2340            /**
2341             * <p>
2342             * Sets the hierarchy of departments to which the person belongs. This is a
2343             * convenience method for {@link #setOrganization(OrganizationType)}.
2344             * </p>
2345             * <p>
2346             * Use {@link #addOrganization} to add alternative representations of this
2347             * property (see: {@link VCardSubTypes#getAltId explanation of ALTID}).
2348             * </p>
2349             * <p>
2350             * vCard property name: ORG
2351             * </p>
2352             * <p>
2353             * vCard versions: 2.1, 3.0, 4.0
2354             * </p>
2355             * @param departments the ordered list of department(s), starting with the
2356             * broadest and ending with the most specific (e.g. "Google", "GMail Team",
2357             * "Spam Detection Squad")
2358             */
2359            public OrganizationType setOrganization(String... departments) {
2360                    OrganizationType type = new OrganizationType();
2361                    for (String department : departments) {
2362                            type.addValue(department);
2363                    }
2364                    setOrganization(type);
2365                    return type;
2366            }
2367    
2368            /**
2369             * <p>
2370             * Gets all CATEGORIES properties.
2371             * </p>
2372             * <p>
2373             * This method should only be used on the rare occasion when there are
2374             * alternative representations of this property (see:
2375             * {@link VCardSubTypes#getAltId explanation of ALTID}). Otherwise, use
2376             * {@link #getCategories}.
2377             * </p>
2378             * <p>
2379             * vCard property name: CATEGORIES
2380             * </p>
2381             * <p>
2382             * vCard versions: 2.1, 3.0, 4.0
2383             * </p>
2384             * @return the CATEGORIES properties
2385             * @see CategoriesType#getAltId
2386             */
2387            public List<CategoriesType> getCategoriesList() {
2388                    return categories;
2389            }
2390    
2391            /**
2392             * <p>
2393             * Gets the list of keywords (aka "tags") that can be used to describe the
2394             * person.
2395             * </p>
2396             * <p>
2397             * Use {@link #getCategoriesList} to get the alternative representations of
2398             * this property (see: {@link VCardSubTypes#getAltId explanation of ALTID}).
2399             * </p>
2400             * <p>
2401             * vCard property name: CATEGORIES
2402             * </p>
2403             * <p>
2404             * vCard versions: 2.1, 3.0, 4.0
2405             * </p>
2406             * @return the categories
2407             */
2408            public CategoriesType getCategories() {
2409                    return categories.isEmpty() ? null : categories.get(0);
2410            }
2411    
2412            /**
2413             * <p>
2414             * Adds a CATEGORIES property to the vCard.
2415             * </p>
2416             * <p>
2417             * This method should only be used on the rare occasion when alternative
2418             * representations of this property are needed (see:
2419             * {@link VCardSubTypes#getAltId explanation of ALTID}). Otherwise, use
2420             * {@link #setCategories(CategoriesType)}.
2421             * </p>
2422             * <p>
2423             * vCard property name: CATEGORIES
2424             * </p>
2425             * <p>
2426             * vCard versions: 2.1, 3.0, 4.0
2427             * </p>
2428             * @param categories the CATEGORIES property to add
2429             * @see CategoriesType#setAltId
2430             */
2431            public void addCategories(CategoriesType categories) {
2432                    this.categories.add(categories);
2433            }
2434    
2435            /**
2436             * <p>
2437             * Sets the list of keywords (aka "tags") that can be used to describe the
2438             * person.
2439             * </p>
2440             * <p>
2441             * Use {@link #addCategories} to add alternative representations of this
2442             * property (see: {@link VCardSubTypes#getAltId explanation of ALTID}).
2443             * </p>
2444             * <p>
2445             * vCard property name: CATEGORIES
2446             * </p>
2447             * <p>
2448             * vCard versions: 2.1, 3.0, 4.0
2449             * </p>
2450             * @param categories the categories (multiple categories can be added to
2451             * this object)
2452             */
2453            public void setCategories(CategoriesType categories) {
2454                    this.categories.clear();
2455                    addCategories(categories);
2456            }
2457    
2458            /**
2459             * <p>
2460             * Sets the list of keywords (aka "tags") that can be used to describe the
2461             * person. This is a convenience method for
2462             * {@link #setCategories(CategoriesType)}.
2463             * </p>
2464             * <p>
2465             * Use {@link #addCategories} to add alternative representations of this
2466             * property (see: {@link VCardSubTypes#getAltId explanation of ALTID}).
2467             * </p>
2468             * <p>
2469             * vCard property name: CATEGORIES
2470             * </p>
2471             * <p>
2472             * vCard versions: 2.1, 3.0, 4.0
2473             * </p>
2474             * @param categories the category or categories (e.g. "swimmer", "biker",
2475             * "knitter")
2476             * @return the type object that was created
2477             */
2478            public CategoriesType setCategories(String... categories) {
2479                    CategoriesType type = new CategoriesType();
2480                    for (String category : categories) {
2481                            type.addValue(category);
2482                    }
2483                    setCategories(type);
2484                    return type;
2485            }
2486    
2487            /**
2488             * Gets information about the person's agent.
2489             * <p>
2490             * vCard property name: AGENT
2491             * </p>
2492             * <p>
2493             * vCard versions: 2.1, 3.0
2494             * </p>
2495             * @return the agent information
2496             */
2497            public AgentType getAgent() {
2498                    return agent;
2499            }
2500    
2501            /**
2502             * Sets information about the person's agent.
2503             * <p>
2504             * vCard property name: AGENT
2505             * </p>
2506             * <p>
2507             * vCard versions: 2.1, 3.0
2508             * </p>
2509             * @param agent the agent information
2510             */
2511            public void setAgent(AgentType agent) {
2512                    this.agent = agent;
2513            }
2514    
2515            /**
2516             * Gets the notes. Notes contain free-form, miscellaneous text.
2517             * <p>
2518             * vCard property name: NOTE
2519             * </p>
2520             * <p>
2521             * vCard versions: 2.1, 3.0, 4.0
2522             * </p>
2523             * @return the notes
2524             */
2525            public List<NoteType> getNotes() {
2526                    return notes;
2527            }
2528    
2529            /**
2530             * Adds a note. Notes contain free-form, miscellaneous text.
2531             * <p>
2532             * vCard property name: NOTE
2533             * </p>
2534             * <p>
2535             * vCard versions: 2.1, 3.0, 4.0
2536             * </p>
2537             * @param note the note to add
2538             */
2539            public void addNote(NoteType note) {
2540                    notes.add(note);
2541            }
2542    
2543            /**
2544             * Adds a note. Notes contain free-form, miscellaneous text. This is a
2545             * convenience method for {@link #addNote(NoteType)}.
2546             * <p>
2547             * vCard property name: NOTE
2548             * </p>
2549             * <p>
2550             * vCard versions: 2.1, 3.0, 4.0
2551             * </p>
2552             * @param note the note to add
2553             * @return the type object that was created
2554             */
2555            public NoteType addNote(String note) {
2556                    NoteType type = new NoteType(note);
2557                    addNote(type);
2558                    return type;
2559            }
2560    
2561            /**
2562             * Gets the unique identifier of the vCard.
2563             * <p>
2564             * vCard property name: UID
2565             * </p>
2566             * <p>
2567             * vCard versions: 2.1, 3.0, 4.0
2568             * </p>
2569             * @return the unique identifier
2570             */
2571            public UidType getUid() {
2572                    return uid;
2573            }
2574    
2575            /**
2576             * Sets the unique identifier of the vCard.
2577             * <p>
2578             * vCard property name: UID
2579             * </p>
2580             * <p>
2581             * vCard versions: 2.1, 3.0, 4.0
2582             * </p>
2583             * @param uid the unique identifier
2584             */
2585            public void setUid(UidType uid) {
2586                    this.uid = uid;
2587            }
2588    
2589            /**
2590             * Gets the public encryption keys.
2591             * <p>
2592             * vCard property name: KEY
2593             * </p>
2594             * <p>
2595             * vCard versions: 2.1, 3.0, 4.0
2596             * </p>
2597             * @return the keys
2598             */
2599            public List<KeyType> getKeys() {
2600                    return keys;
2601            }
2602    
2603            /**
2604             * Adds a public encryption key.
2605             * <p>
2606             * vCard property name: KEY
2607             * </p>
2608             * <p>
2609             * vCard versions: 2.1, 3.0, 4.0
2610             * </p>
2611             * @param key the key to add
2612             */
2613            public void addKey(KeyType key) {
2614                    keys.add(key);
2615            }
2616    
2617            /**
2618             * Gets the instant messaging handles.
2619             * <p>
2620             * vCard property name: IMPP
2621             * </p>
2622             * <p>
2623             * vCard versions: 3.0, 4.0
2624             * </p>
2625             * @return the instant messaging handles
2626             */
2627            public List<ImppType> getImpps() {
2628                    return impps;
2629            }
2630    
2631            /**
2632             * Adds an instant messaging handle.
2633             * <p>
2634             * vCard property name: IMPP
2635             * </p>
2636             * <p>
2637             * vCard versions: 3.0, 4.0
2638             * </p>
2639             * @param impp the instant messaging handle to add
2640             */
2641            public void addImpp(ImppType impp) {
2642                    impps.add(impp);
2643            }
2644    
2645            /**
2646             * Gets a list of people that the person is related to.
2647             * <p>
2648             * vCard property name: RELATED
2649             * </p>
2650             * <p>
2651             * vCard versions: 4.0
2652             * </p>
2653             * @return the person's relations
2654             */
2655            public List<RelatedType> getRelations() {
2656                    return relations;
2657            }
2658    
2659            /**
2660             * Adds someone that the person is related to.
2661             * <p>
2662             * vCard property name: RELATED
2663             * </p>
2664             * <p>
2665             * vCard versions: 4.0
2666             * </p>
2667             * @param related the relation to add
2668             */
2669            public void addRelated(RelatedType related) {
2670                    relations.add(related);
2671            }
2672    
2673            /**
2674             * Gets the languages that the person speaks.
2675             * <p>
2676             * vCard property name: LANG
2677             * </p>
2678             * <p>
2679             * vCard versions: 4.0
2680             * </p>
2681             * @return the languages
2682             */
2683            public List<LanguageType> getLanguages() {
2684                    return languages;
2685            }
2686    
2687            /**
2688             * Adds a language that the person speaks.
2689             * <p>
2690             * vCard property name: LANG
2691             * </p>
2692             * <p>
2693             * vCard versions: 4.0
2694             * </p>
2695             * @param language the language to add
2696             */
2697            public void addLanguage(LanguageType language) {
2698                    languages.add(language);
2699            }
2700    
2701            /**
2702             * Adds a language that the person speaks. This is a convenience method for
2703             * {@link #addLanguage(LanguageType)}.
2704             * <p>
2705             * vCard property name: LANG
2706             * </p>
2707             * <p>
2708             * vCard versions: 4.0
2709             * </p>
2710             * @param language the language to add (e.g. "en-us")
2711             * @return the type object that was created
2712             */
2713            public LanguageType addLanguage(String language) {
2714                    LanguageType type = new LanguageType(language);
2715                    addLanguage(type);
2716                    return type;
2717            }
2718    
2719            /**
2720             * Gets the URIs that can be used to schedule a meeting with the person on
2721             * his or her calendar.
2722             * <p>
2723             * vCard property name: CALADRURI
2724             * </p>
2725             * <p>
2726             * vCard versions: 4.0
2727             * </p>
2728             * @return the calendar request URIs
2729             */
2730            public List<CalendarRequestUriType> getCalendarRequestUris() {
2731                    return calendarRequestUris;
2732            }
2733    
2734            /**
2735             * Adds a URI that can be used to schedule a meeting with the person on his
2736             * or her calendar.
2737             * <p>
2738             * vCard property name: CALADRURI
2739             * </p>
2740             * <p>
2741             * vCard versions: 4.0
2742             * </p>
2743             * @param calendarRequestUri the calendar request URI to add
2744             */
2745            public void addCalendarRequestUri(CalendarRequestUriType calendarRequestUri) {
2746                    calendarRequestUris.add(calendarRequestUri);
2747            }
2748    
2749            /**
2750             * Gets the URIs that point to the person's calendar.
2751             * <p>
2752             * vCard property name: CALURI
2753             * </p>
2754             * <p>
2755             * vCard versions: 4.0
2756             * </p>
2757             * @return the calendar URIs
2758             */
2759            public List<CalendarUriType> getCalendarUris() {
2760                    return calendarUris;
2761            }
2762    
2763            /**
2764             * Adds a URI that points to the person's calendar.
2765             * <p>
2766             * vCard property name: CALURI
2767             * </p>
2768             * <p>
2769             * vCard versions: 4.0
2770             * </p>
2771             * @param calendarUri the calendar URI to add
2772             */
2773            public void addCalendarUri(CalendarUriType calendarUri) {
2774                    calendarUris.add(calendarUri);
2775            }
2776    
2777            /**
2778             * Gets the URLs that can be used to determine when the person is free
2779             * and/or busy.
2780             * <p>
2781             * vCard property name: FBURL
2782             * </p>
2783             * <p>
2784             * vCard versions: 4.0
2785             * </p>
2786             * @return the free-busy URLs
2787             */
2788            public List<FbUrlType> getFbUrls() {
2789                    return fbUrls;
2790            }
2791    
2792            /**
2793             * Adds a URL that can be used to determine when the person is free and/or
2794             * busy.
2795             * <p>
2796             * vCard property name: FBURL
2797             * </p>
2798             * <p>
2799             * vCard versions: 4.0
2800             * </p>
2801             * @param fbUrl the free-busy URL to add
2802             */
2803            public void addFbUrl(FbUrlType fbUrl) {
2804                    fbUrls.add(fbUrl);
2805            }
2806    
2807            /**
2808             * Gets the properties that are used to assign globally-unique identifiers
2809             * to individual property instances. CLIENTPIDMAPs are used for merging
2810             * together different versions of the same vCard.
2811             * <p>
2812             * vCard property name: CLIENTPIDMAP
2813             * </p>
2814             * <p>
2815             * vCard versions: 4.0
2816             * </p>
2817             * @return the client PID maps
2818             */
2819            public List<ClientPidMapType> getClientPidMaps() {
2820                    return clientPidMaps;
2821            }
2822    
2823            /**
2824             * Adds a property that is used to assign a globally-unique identifier to an
2825             * individual property instance. CLIENTPIDMAPs are used for merging together
2826             * different versions of the same vCard.
2827             * <p>
2828             * vCard property name: CLIENTPIDMAP
2829             * </p>
2830             * <p>
2831             * vCard versions: 4.0
2832             * </p>
2833             * @param clientPidMap the client PID map to add
2834             */
2835            public void addClientPidMap(ClientPidMapType clientPidMap) {
2836                    clientPidMaps.add(clientPidMap);
2837            }
2838    
2839            /**
2840             * Gets any XML data that is attached to the vCard. XML properties may be
2841             * present if the vCard was encoded in XML and the XML document contained
2842             * non-standard elements. The XML vCard properties in this case would
2843             * contain all of the non-standard XML elements.
2844             * <p>
2845             * vCard property name: XML
2846             * </p>
2847             * <p>
2848             * vCard versions: 4.0
2849             * </p>
2850             * @return the XML data
2851             */
2852            public List<XmlType> getXmls() {
2853                    return xmls;
2854            }
2855    
2856            /**
2857             * Adds XML data to the vCard. XML properties may be present if the vCard
2858             * was encoded in XML and the XML document contained non-standard elements.
2859             * The XML vCard properties in this case would contain all of the
2860             * non-standard XML elements.
2861             * <p>
2862             * vCard property name: XML
2863             * </p>
2864             * <p>
2865             * vCard versions: 4.0
2866             * </p>
2867             * @param xml the XML data to add
2868             */
2869            public void addXml(XmlType xml) {
2870                    xmls.add(xml);
2871            }
2872    
2873            /**
2874             * Gets the professional subject areas of which the the person is
2875             * knowledgeable.
2876             * <p>
2877             * vCard property name: EXPERTISE
2878             * </p>
2879             * <p>
2880             * vCard versions: 4.0
2881             * </p>
2882             * @return the professional skills
2883             * @see <a href="http://tools.ietf.org/html/rfc6715">RFC 6715</a>
2884             */
2885            public List<ExpertiseType> getExpertise() {
2886                    return expertises;
2887            }
2888    
2889            /**
2890             * Adds a professional subject area of which the the person is
2891             * knowledgeable.
2892             * <p>
2893             * vCard property name: EXPERTISE
2894             * </p>
2895             * <p>
2896             * vCard versions: 4.0
2897             * </p>
2898             * @param expertise the professional skill to add
2899             * @see <a href="http://tools.ietf.org/html/rfc6715">RFC 6715</a>
2900             */
2901            public void addExpertise(ExpertiseType expertise) {
2902                    expertises.add(expertise);
2903            }
2904    
2905            /**
2906             * Adds a professional subject area of which the the person is
2907             * knowledgeable. This is a convenience method for
2908             * {@link #addExpertise(ExpertiseType)}.
2909             * <p>
2910             * vCard property name: EXPERTISE
2911             * </p>
2912             * <p>
2913             * vCard versions: 4.0
2914             * </p>
2915             * @param expertise the professional skill to add (e.g. "programming")
2916             * @return the type object that was created
2917             * @see <a href="http://tools.ietf.org/html/rfc6715">RFC 6715</a>
2918             */
2919            public ExpertiseType addExpertise(String expertise) {
2920                    ExpertiseType type = new ExpertiseType(expertise);
2921                    addExpertise(type);
2922                    return type;
2923            }
2924    
2925            /**
2926             * Gets the hobbies that the person actively engages in.
2927             * <p>
2928             * vCard property name: HOBBY
2929             * </p>
2930             * <p>
2931             * vCard versions: 4.0
2932             * </p>
2933             * @return the hobbies
2934             * @see <a href="http://tools.ietf.org/html/rfc6715">RFC 6715</a>
2935             */
2936            public List<HobbyType> getHobbies() {
2937                    return hobbies;
2938            }
2939    
2940            /**
2941             * Adds a hobby that the person actively engages in.
2942             * <p>
2943             * vCard property name: HOBBY
2944             * </p>
2945             * <p>
2946             * vCard versions: 4.0
2947             * </p>
2948             * @param hobby the hobby to add
2949             * @see <a href="http://tools.ietf.org/html/rfc6715">RFC 6715</a>
2950             */
2951            public void addHobby(HobbyType hobby) {
2952                    hobbies.add(hobby);
2953            }
2954    
2955            /**
2956             * Adds a hobby that the person actively engages in. This is a convenience
2957             * method for {@link #addHobby(HobbyType)}.
2958             * <p>
2959             * vCard property name: HOBBY
2960             * </p>
2961             * <p>
2962             * vCard versions: 4.0
2963             * </p>
2964             * @param hobby the hobby to add (e.g. "photography")
2965             * @return the type objec that was created
2966             * @see <a href="http://tools.ietf.org/html/rfc6715">RFC 6715</a>
2967             */
2968            public HobbyType addHobby(String hobby) {
2969                    HobbyType type = new HobbyType(hobby);
2970                    addHobby(type);
2971                    return type;
2972            }
2973    
2974            /**
2975             * Gets the person's interests.
2976             * <p>
2977             * vCard property name: INTEREST
2978             * </p>
2979             * <p>
2980             * vCard versions: 4.0
2981             * </p>
2982             * @return the interests
2983             * @see <a href="http://tools.ietf.org/html/rfc6715">RFC 6715</a>
2984             */
2985            public List<InterestType> getInterests() {
2986                    return interests;
2987            }
2988    
2989            /**
2990             * Adds an interest.
2991             * <p>
2992             * vCard property name: INTEREST
2993             * </p>
2994             * <p>
2995             * vCard versions: 4.0
2996             * </p>
2997             * @param interest the interest to add
2998             * @see <a href="http://tools.ietf.org/html/rfc6715">RFC 6715</a>
2999             */
3000            public void addInterest(InterestType interest) {
3001                    interests.add(interest);
3002            }
3003    
3004            /**
3005             * Adds an interest. This is a convenience method for
3006             * {@link #addInterest(InterestType)}.
3007             * <p>
3008             * vCard property name: INTEREST
3009             * </p>
3010             * <p>
3011             * vCard versions: 4.0
3012             * </p>
3013             * @param interest the interest to add (e.g. "football")
3014             * @return the type object that was created
3015             * @see <a href="http://tools.ietf.org/html/rfc6715">RFC 6715</a>
3016             */
3017            public InterestType addInterest(String interest) {
3018                    InterestType type = new InterestType(interest);
3019                    addInterest(type);
3020                    return type;
3021            }
3022    
3023            /**
3024             * Gets the organization directories.
3025             * <p>
3026             * vCard property name: ORG-DIRECTORY
3027             * </p>
3028             * <p>
3029             * vCard versions: 4.0
3030             * </p>
3031             * @return the organization directories
3032             * @see <a href="http://tools.ietf.org/html/rfc6715">RFC 6715</a>
3033             */
3034            public List<OrgDirectoryType> getOrgDirectories() {
3035                    return orgDirectories;
3036            }
3037    
3038            /**
3039             * Adds an organization directory.
3040             * <p>
3041             * vCard property name: ORG-DIRECTORY
3042             * </p>
3043             * <p>
3044             * vCard versions: 4.0
3045             * </p>
3046             * @param orgDirectory the organization directory to add
3047             * @see <a href="http://tools.ietf.org/html/rfc6715">RFC 6715</a>
3048             */
3049            public void addOrgDirectory(OrgDirectoryType orgDirectory) {
3050                    orgDirectories.add(orgDirectory);
3051            }
3052    
3053            /**
3054             * Adds an organization directory. This is a convenience method for
3055             * {@link #addOrgDirectory(OrgDirectoryType)}.
3056             * <p>
3057             * vCard property name: ORG-DIRECTORY
3058             * </p>
3059             * <p>
3060             * vCard versions: 4.0
3061             * </p>
3062             * @param orgDirectory the organization directory to add (e.g.
3063             * "http://company.com/staff")
3064             * @return the type object that was created
3065             * @see <a href="http://tools.ietf.org/html/rfc6715">RFC 6715</a>
3066             */
3067            public OrgDirectoryType addOrgDirectory(String orgDirectory) {
3068                    OrgDirectoryType type = new OrgDirectoryType(orgDirectory);
3069                    addOrgDirectory(type);
3070                    return type;
3071            }
3072    
3073            /**
3074             * Adds an extended type to the vCard.
3075             * @param type the extended type to add
3076             */
3077            public void addExtendedType(VCardType type) {
3078                    extendedTypes.put(type.getTypeName(), type);
3079            }
3080    
3081            /**
3082             * Adds an extended type to the vCard.
3083             * @param name the name of the extended type. It MUST begin with "X-" (for
3084             * example, "X-GENDER").
3085             * @param value the value of the extended type
3086             * @return the extended type object that was created
3087             */
3088            public RawType addExtendedType(String name, String value) {
3089                    RawType type = new RawType(name, value);
3090                    addExtendedType(type);
3091                    return type;
3092            }
3093    
3094            /**
3095             * Gets all extended types that have a particular name. Use this method to
3096             * retrieve the extended types that have NOT been unmarshalled into a
3097             * custom, extended type class.
3098             * @param typeName the type name
3099             * @return the extended types or empty list if none were found
3100             */
3101            public List<RawType> getExtendedType(String typeName) {
3102                    return getExtendedType(typeName, RawType.class);
3103            }
3104    
3105            /**
3106             * Gets all extended types that have a particular name and that are an
3107             * instance of a particular class.
3108             * @param typeName the type name
3109             * @param clazz the type class
3110             * @return the extended types or empty list if none were found
3111             */
3112            @SuppressWarnings("unchecked")
3113            public <T extends VCardType> List<T> getExtendedType(String typeName, Class<T> clazz) {
3114                    List<VCardType> types = extendedTypes.get(typeName);
3115                    List<T> list = new ArrayList<T>();
3116                    for (VCardType type : types) {
3117                            if (clazz.isInstance(type)) {
3118                                    T rt = (T) type;
3119                                    list.add(rt);
3120                            }
3121                    }
3122                    return list;
3123            }
3124    
3125            /**
3126             * Gets all extended types that are an instance of a particular class.
3127             * @param clazz the type class
3128             * @return the extended types or empty list of none were found
3129             */
3130            @SuppressWarnings("unchecked")
3131            public <T extends VCardType> List<T> getExtendedType(Class<T> clazz) {
3132                    List<T> list = new ArrayList<T>();
3133                    for (VCardType type : extendedTypes.values()) {
3134                            if (clazz.isInstance(type)) {
3135                                    list.add((T) type);
3136                            }
3137                    }
3138                    return list;
3139            }
3140    
3141            /**
3142             * Gets all extended types.
3143             * @return the extended types (key = the type name, value = the list of type
3144             * objects that have that name)
3145             */
3146            public Map<String, List<VCardType>> getExtendedTypes() {
3147                    return extendedTypes.getMap();
3148            }
3149    
3150            /**
3151             * Gets all of the vCard's properties. Does not include the "BEGIN", "END",
3152             * or "VERSION" properties.
3153             * @return the vCard properties
3154             */
3155            public Collection<VCardType> getAllTypes() {
3156                    Collection<VCardType> allTypes = new ArrayList<VCardType>();
3157    
3158                    for (Field field : getClass().getDeclaredFields()) {
3159                            try {
3160                                    field.setAccessible(true);
3161                                    Object value = field.get(this);
3162                                    if (value instanceof VCardType) {
3163                                            VCardType type = (VCardType) value;
3164                                            allTypes.add(type);
3165                                    } else if (value instanceof Collection) {
3166                                            Collection<?> collection = (Collection<?>) value;
3167                                            for (Object obj : collection) {
3168                                                    if (obj instanceof VCardType) {
3169                                                            VCardType type = (VCardType) obj;
3170                                                            allTypes.add(type);
3171                                                    }
3172                                            }
3173                                    }
3174                            } catch (IllegalArgumentException e) {
3175                                    //shouldn't be thrown because we're passing the correct object into Field.get()
3176                            } catch (IllegalAccessException e) {
3177                                    //shouldn't be thrown because we're calling Field.setAccessible(true)
3178                            }
3179                    }
3180    
3181                    for (VCardType extendedType : extendedTypes.values()) {
3182                            allTypes.add(extendedType);
3183                    }
3184    
3185                    return allTypes;
3186            }
3187    
3188            /**
3189             * Iterates through each of the vCard's properties in no particular order.
3190             * Does not include the "BEGIN", "END", or "VERSION" properties.
3191             * @return the iterator
3192             */
3193            public Iterator<VCardType> iterator() {
3194                    return getAllTypes().iterator();
3195            }
3196    }