001/*
002 * oauth2-oidc-sdk
003 *
004 * Copyright 2012-2016, Connect2id Ltd and contributors.
005 *
006 * Licensed under the Apache License, Version 2.0 (the "License"); you may not use
007 * this file except in compliance with the License. You may obtain a copy of the
008 * License at
009 *
010 *    http://www.apache.org/licenses/LICENSE-2.0
011 *
012 * Unless required by applicable law or agreed to in writing, software distributed
013 * under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
014 * CONDITIONS OF ANY KIND, either express or implied. See the License for the
015 * specific language governing permissions and limitations under the License.
016 */
017
018package com.nimbusds.openid.connect.sdk.claims;
019
020
021import java.net.URI;
022import java.util.*;
023
024import net.minidev.json.JSONObject;
025
026import com.nimbusds.langtag.LangTag;
027import com.nimbusds.oauth2.sdk.ParseException;
028import com.nimbusds.openid.connect.sdk.assurance.claims.Birthplace;
029import com.nimbusds.openid.connect.sdk.assurance.claims.CountryCode;
030
031
032/**
033 * Person-specific claims set, intended to provide common getters and setters
034 * for {@link UserInfo OpenID Connect UserInfo} and
035 * {@link com.nimbusds.openid.connect.sdk.assurance.claims.VerifiedClaimsSet
036 * OpenID Connect Identity Assurance verified claims}.
037 *
038 * <p>Related specifications:
039 *
040 * <ul>
041 *     <li>OpenID Connect Core 1.0, sections 5.1 and 5.6.
042 *     <li>OpenID Connect for Identity Assurance 1.0, section 3.1.
043 * </ul>
044 */
045public class PersonClaims extends ClaimsSet {
046
047
048        /**
049         * The name claim name.
050         */
051        public static final String NAME_CLAIM_NAME = "name";
052
053
054        /**
055         * The given name claim name.
056         */
057        public static final String GIVEN_NAME_CLAIM_NAME = "given_name";
058
059
060        /**
061         * The family name claim name.
062         */
063        public static final String FAMILY_NAME_CLAIM_NAME = "family_name";
064
065
066        /**
067         * The middle name claim name.
068         */
069        public static final String MIDDLE_NAME_CLAIM_NAME = "middle_name";
070
071
072        /**
073         * The nickname claim name.
074         */
075        public static final String NICKNAME_CLAIM_NAME = "nickname";
076
077
078        /**
079         * The preferred username claim name.
080         */
081        public static final String PREFERRED_USERNAME_CLAIM_NAME = "preferred_username";
082
083
084        /**
085         * The profile claim name.
086         */
087        public static final String PROFILE_CLAIM_NAME = "profile";
088
089
090        /**
091         * The picture claim name.
092         */
093        public static final String PICTURE_CLAIM_NAME = "picture";
094
095
096        /**
097         * The website claim name.
098         */
099        public static final String WEBSITE_CLAIM_NAME = "website";
100
101
102        /**
103         * The email claim name.
104         */
105        public static final String EMAIL_CLAIM_NAME = "email";
106
107
108        /**
109         * The email verified claim name.
110         */
111        public static final String EMAIL_VERIFIED_CLAIM_NAME = "email_verified";
112
113
114        /**
115         * The gender claim name.
116         */
117        public static final String GENDER_CLAIM_NAME = "gender";
118
119
120        /**
121         * The birth date claim name.
122         */
123        public static final String BIRTHDATE_CLAIM_NAME = "birthdate";
124
125
126        /**
127         * The zoneinfo claim name.
128         */
129        public static final String ZONEINFO_CLAIM_NAME = "zoneinfo";
130
131
132        /**
133         * The locale claim name.
134         */
135        public static final String LOCALE_CLAIM_NAME = "locale";
136
137
138        /**
139         * The phone number claim name.
140         */
141        public static final String PHONE_NUMBER_CLAIM_NAME = "phone_number";
142
143
144        /**
145         * The phone number verified claim name.
146         */
147        public static final String PHONE_NUMBER_VERIFIED_CLAIM_NAME = "phone_number_verified";
148
149
150        /**
151         * The address claim name.
152         */
153        public static final String ADDRESS_CLAIM_NAME = "address";
154
155
156        /**
157         * The updated at claim name.
158         */
159        public static final String UPDATED_AT_CLAIM_NAME = "updated_at";
160        
161        
162        /**
163         * The birthplace claim name (OpenID Connect for Identity Assurance
164         * 1.0). Alternative for {@link #PLACE_OF_BIRTH_CLAIM_NAME}.
165         */
166        // https://bitbucket.org/openid/connect/issues/1119/place_of_birth-birthplace
167        public static final String BIRTHPLACE_CLAIM_NAME = "birthplace";
168        
169        
170        /**
171         * The place of birth claim name (OpenID Connect for Identity Assurance
172         * 1.0). Alternative for {@link #BIRTHPLACE_CLAIM_NAME}.
173         */
174        public static final String PLACE_OF_BIRTH_CLAIM_NAME = "place_of_birth";
175        
176        
177        /**
178         * The nationalities claim name (OpenID Connect for Identity Assurance
179         * 1.0).
180         */
181        public static final String NATIONALITIES_CLAIM_NAME = "nationalities";
182        
183        
184        /**
185         * The birth family name claim name (OpenID Connect for Identity
186         * Assurance 1.0).
187         */
188        public static final String BIRTH_FAMILY_NAME_CLAIM_NAME = "birth_family_name";
189        
190        
191        /**
192         * The birth given name claim name (OpenID Connect for Identity
193         * Assurance 1.0).
194         */
195        public static final String BIRTH_GIVEN_NAME_CLAIM_NAME = "birth_given_name";
196        
197        
198        /**
199         * The birth middle name claim name (OpenID Connect for Identity
200         * Assurance 1.0).
201         */
202        public static final String BIRTH_MIDDLE_NAME_CLAIM_NAME = "birth_middle_name";
203        
204        
205        /**
206         * The salutation claim name (OpenID Connect for Identity Assurance
207         * 1.0).
208         */
209        public static final String SALUTATION_CLAIM_NAME = "salutation";
210        
211        
212        /**
213         * The title claim name (OpenID Connect for Identity Assurance 1.0).
214         */
215        public static final String TITLE_CLAIM_NAME = "title";
216        
217        
218        /**
219         * Gets the names of the standard top-level UserInfo claims.
220         *
221         * @return The names of the standard top-level UserInfo claims
222         *         (read-only set).
223         */
224        public static Set<String> getStandardClaimNames() {
225        
226                Set<String> names = new HashSet<>(ClaimsSet.getStandardClaimNames());
227                names.addAll(Arrays.asList(
228                        NAME_CLAIM_NAME,
229                        GIVEN_NAME_CLAIM_NAME,
230                        FAMILY_NAME_CLAIM_NAME,
231                        MIDDLE_NAME_CLAIM_NAME,
232                        NICKNAME_CLAIM_NAME,
233                        PREFERRED_USERNAME_CLAIM_NAME,
234                        PROFILE_CLAIM_NAME,
235                        PICTURE_CLAIM_NAME,
236                        WEBSITE_CLAIM_NAME,
237                        EMAIL_CLAIM_NAME,
238                        EMAIL_VERIFIED_CLAIM_NAME,
239                        GENDER_CLAIM_NAME,
240                        BIRTHDATE_CLAIM_NAME,
241                        ZONEINFO_CLAIM_NAME,
242                        LOCALE_CLAIM_NAME,
243                        PHONE_NUMBER_CLAIM_NAME,
244                        PHONE_NUMBER_VERIFIED_CLAIM_NAME,
245                        ADDRESS_CLAIM_NAME,
246                        UPDATED_AT_CLAIM_NAME,
247                        BIRTHPLACE_CLAIM_NAME,
248                        PLACE_OF_BIRTH_CLAIM_NAME,
249                        NATIONALITIES_CLAIM_NAME,
250                        BIRTH_FAMILY_NAME_CLAIM_NAME,
251                        BIRTH_GIVEN_NAME_CLAIM_NAME,
252                        BIRTH_MIDDLE_NAME_CLAIM_NAME,
253                        SALUTATION_CLAIM_NAME,
254                        TITLE_CLAIM_NAME
255                ));
256                return Collections.unmodifiableSet(names);
257        }
258        
259        
260        /**
261         * Creates a new empty person-specific claims set.
262         */
263        public PersonClaims() {
264                this(new JSONObject());
265        }
266
267
268        /**
269         * Creates a new person-specific claims set from the specified JSON
270         * object.
271         *
272         * @param jsonObject The JSON object. Must not be {@code null}.
273         */
274        public PersonClaims(final JSONObject jsonObject) {
275
276                super(jsonObject);
277        }
278        
279        
280        // name
281
282        
283        /**
284         * Gets the full name. Corresponds to the {@code name} claim, with no
285         * language tag.
286         *
287         * @return The full name, {@code null} if not specified.
288         */
289        public String getName() {
290        
291                return getStringClaim(NAME_CLAIM_NAME);
292        }
293        
294        
295        /**
296         * Gets the full name. Corresponds to the {@code name} claim, with an
297         * optional language tag.
298         *
299         * @param langTag The language tag of the entry, {@code null} to get 
300         *                the non-tagged entry.
301         *
302         * @return The full name, {@code null} if not specified.
303         */
304        public String getName(final LangTag langTag) {
305        
306                return getStringClaim(NAME_CLAIM_NAME, langTag);
307        }
308        
309        
310        /**
311         * Gets the full name entries. Correspond to the {@code name} claim.
312         *
313         * @return The full name entries, empty map if none.
314         */
315        public Map<LangTag,String> getNameEntries() {
316        
317                return getLangTaggedClaim(NAME_CLAIM_NAME, String.class);
318        }
319
320
321        /**
322         * Sets the full name. Corresponds to the {@code name} claim, with no
323         * language tag.
324         *
325         * @param name The full name. If {@code null} the claim will be 
326         *             removed.
327         */
328        public void setName(final String name) {
329        
330                setClaim(NAME_CLAIM_NAME, name);
331        }
332        
333        
334        /**
335         * Sets the full name. Corresponds to the {@code name} claim, with an
336         * optional language tag.
337         *
338         * @param name    The full name. If {@code null} the claim will be 
339         *                removed.
340         * @param langTag The language tag, {@code null} if not specified.
341         */
342        public void setName(final String name, final LangTag langTag) {
343        
344                setClaim(NAME_CLAIM_NAME, name, langTag);
345        }
346        
347        
348        // given_name
349        
350        
351        /**
352         * Gets the given or first name. Corresponds to the {@code given_name} 
353         * claim, with no language tag.
354         *
355         * @return The given or first name, {@code null} if not specified.
356         */
357        public String getGivenName() {
358        
359                return getStringClaim(GIVEN_NAME_CLAIM_NAME);
360        }
361        
362        
363        /**
364         * Gets the given or first name. Corresponds to the {@code given_name} 
365         * claim, with an optional language tag.
366         *
367         * @param langTag The language tag of the entry, {@code null} to get 
368         *                the non-tagged entry.
369         *
370         * @return The given or first name, {@code null} if not specified.
371         */
372        public String getGivenName(final LangTag langTag) {
373        
374                return getStringClaim(GIVEN_NAME_CLAIM_NAME, langTag);
375        }
376        
377        
378        /**
379         * Gets the given or first name entries. Correspond to the 
380         * {@code given_name} claim.
381         *
382         * @return The given or first name entries, empty map if none.
383         */
384        public Map<LangTag,String> getGivenNameEntries() {
385        
386                return getLangTaggedClaim(GIVEN_NAME_CLAIM_NAME, String.class);
387        }
388
389
390        /**
391         * Sets the given or first name. Corresponds to the {@code given_name} 
392         * claim, with no language tag.
393         *
394         * @param givenName The given or first name. If {@code null} the claim
395         *                  will be removed.
396         */
397        public void setGivenName(final String givenName) {
398        
399                setClaim(GIVEN_NAME_CLAIM_NAME, givenName);
400        }
401        
402        
403        /**
404         * Sets the given or first name. Corresponds to the {@code given_name}
405         * claim, with an optional language tag.
406         *
407         * @param givenName The given or first full name. If {@code null} the 
408         *                  claim will be removed.
409         * @param langTag   The language tag, {@code null} if not specified.
410         */
411        public void setGivenName(final String givenName, final LangTag langTag) {
412        
413                setClaim(GIVEN_NAME_CLAIM_NAME, givenName, langTag);
414        }
415        
416        
417        // family_name
418
419        
420        /**
421         * Gets the surname or last name. Corresponds to the 
422         * {@code family_name} claim, with no language tag.
423         *
424         * @return The surname or last name, {@code null} if not specified.
425         */
426        public String getFamilyName() {
427        
428                return getStringClaim(FAMILY_NAME_CLAIM_NAME);
429        }
430        
431        
432        /**
433         * Gets the surname or last name. Corresponds to the 
434         * {@code family_name} claim, with an optional language tag.
435         *
436         * @param langTag The language tag of the entry, {@code null} to get 
437         *                the non-tagged entry.
438         *
439         * @return The surname or last name, {@code null} if not specified.
440         */
441        public String getFamilyName(final LangTag langTag) {
442        
443                return getStringClaim(FAMILY_NAME_CLAIM_NAME, langTag);
444        }
445        
446        
447        /**
448         * Gets the surname or last name entries. Correspond to the 
449         * {@code family_name} claim.
450         *
451         * @return The surname or last name entries, empty map if none.
452         */
453        public Map<LangTag,String> getFamilyNameEntries() {
454        
455                return getLangTaggedClaim(FAMILY_NAME_CLAIM_NAME, String.class);
456        }
457
458
459        /**
460         * Sets the surname or last name. Corresponds to the 
461         * {@code family_name} claim, with no language tag.
462         *
463         * @param familyName The surname or last name. If {@code null} the 
464         *                   claim will be removed.
465         */
466        public void setFamilyName(final String familyName) {
467        
468                setClaim(FAMILY_NAME_CLAIM_NAME, familyName);
469        }
470        
471        
472        /**
473         * Sets the surname or last name. Corresponds to the 
474         * {@code family_name} claim, with an optional language tag.
475         *
476         * @param familyName The surname or last name. If {@code null} the 
477         *                   claim will be removed.
478         * @param langTag    The language tag, {@code null} if not specified.
479         */
480        public void setFamilyName(final String familyName, final LangTag langTag) {
481        
482                setClaim(FAMILY_NAME_CLAIM_NAME, familyName, langTag);
483        }
484        
485        
486        // middle_name
487
488        
489        /**
490         * Gets the middle name. Corresponds to the {@code middle_name} claim, 
491         * with no language tag.
492         *
493         * @return The middle name, {@code null} if not specified.
494         */
495        public String getMiddleName() {
496        
497                return getStringClaim(MIDDLE_NAME_CLAIM_NAME);
498        }
499        
500        
501        /**
502         * Gets the middle name. Corresponds to the {@code middle_name} claim,
503         * with an optional language tag.
504         *
505         * @param langTag The language tag of the entry, {@code null} to get 
506         *                the non-tagged entry.
507         *
508         * @return The middle name, {@code null} if not specified.
509         */
510        public String getMiddleName(final LangTag langTag) {
511        
512                return getStringClaim(MIDDLE_NAME_CLAIM_NAME, langTag);
513        }
514        
515        
516        /**
517         * Gets the middle name entries. Correspond to the {@code middle_name}
518         * claim.
519         *
520         * @return The middle name entries, empty map if none.
521         */
522        public Map<LangTag,String> getMiddleNameEntries() {
523        
524                return getLangTaggedClaim(MIDDLE_NAME_CLAIM_NAME, String.class);
525        }
526
527
528        /**
529         * Sets the middle name. Corresponds to the {@code middle_name} claim,
530         * with no language tag.
531         *
532         * @param middleName The middle name. If {@code null} the claim will be
533         *                   removed.
534         */
535        public void setMiddleName(final String middleName) {
536        
537                setClaim(MIDDLE_NAME_CLAIM_NAME, middleName);
538        }
539        
540        
541        /**
542         * Sets the middle name. Corresponds to the {@code middle_name} claim, 
543         * with an optional language tag.
544         *
545         * @param middleName The middle name. If {@code null} the claim will be
546         *                   removed.
547         * @param langTag    The language tag, {@code null} if not specified.
548         */
549        public void setMiddleName(final String middleName, final LangTag langTag) {
550        
551                setClaim(MIDDLE_NAME_CLAIM_NAME, middleName, langTag);
552        }
553        
554        
555        // nickname
556        
557        
558        /**
559         * Gets the casual name. Corresponds to the {@code nickname} claim, 
560         * with no language tag.
561         *
562         * @return The casual name, {@code null} if not specified.
563         */
564        public String getNickname() {
565        
566                return getStringClaim(NICKNAME_CLAIM_NAME);
567        }
568        
569        
570        /**
571         * Gets the casual name. Corresponds to the {@code nickname} claim, 
572         * with an optional language tag.
573         *
574         * @param langTag The language tag of the entry, {@code null} to get 
575         *                the non-tagged entry.
576         *
577         * @return The casual name, {@code null} if not specified.
578         */
579        public String getNickname(final LangTag langTag) {
580        
581                return getStringClaim(NICKNAME_CLAIM_NAME, langTag);
582        }
583        
584        
585        /**
586         * Gets the casual name entries. Correspond to the {@code nickname} 
587         * claim.
588         *
589         * @return The casual name entries, empty map if none.
590         */
591        public Map<LangTag,String> getNicknameEntries() {
592        
593                return getLangTaggedClaim(NICKNAME_CLAIM_NAME, String.class);
594        }
595
596
597        /**
598         * Sets the casual name. Corresponds to the {@code nickname} claim, 
599         * with no language tag.
600         *
601         * @param nickname The casual name. If {@code null} the claim will be
602         *                 removed.
603         */
604        public void setNickname(final String nickname) {
605        
606                setClaim(NICKNAME_CLAIM_NAME, nickname);
607        }
608        
609        
610        /**
611         * Sets the casual name. Corresponds to the {@code nickname} claim, 
612         * with an optional language tag.
613         *
614         * @param nickname The casual name. If {@code null} the claim will be
615         *                 removed.
616         * @param langTag  The language tag, {@code null} if not specified.
617         */
618        public void setNickname(final String nickname, final LangTag langTag) {
619        
620                setClaim(NICKNAME_CLAIM_NAME, nickname, langTag);
621        }
622        
623        
624        // preferred_username
625        
626        
627        /**
628         * Gets the preferred username. Corresponds to the 
629         * {@code preferred_username} claim.
630         *
631         * @return The preferred username, {@code null} if not specified.
632         */
633        public String getPreferredUsername() {
634        
635                return getStringClaim(PREFERRED_USERNAME_CLAIM_NAME);
636        }
637        
638        
639        /**
640         * Sets the preferred username. Corresponds to the 
641         * {@code preferred_username} claim.
642         *
643         * @param preferredUsername The preferred username. If {@code null} the
644         *                          claim will be removed.
645         */
646        public void setPreferredUsername(final String preferredUsername) {
647        
648                setClaim(PREFERRED_USERNAME_CLAIM_NAME, preferredUsername);
649        }
650        
651        
652        // profile
653        
654        
655        /**
656         * Gets the profile page. Corresponds to the {@code profile} claim.
657         *
658         * @return The profile page URI, {@code null} if not specified.
659         */
660        public URI getProfile() {
661        
662                return getURIClaim(PROFILE_CLAIM_NAME);
663        }
664        
665        
666        /**
667         * Sets the profile page. Corresponds to the {@code profile} claim.
668         *
669         * @param profile The profile page URI. If {@code null} the claim will
670         *                be removed.
671         */
672        public void setProfile(final URI profile) {
673        
674                setURIClaim(PROFILE_CLAIM_NAME, profile);
675        }
676        
677        
678        // picture
679        
680        
681        /**
682         * Gets the picture. Corresponds to the {@code picture} claim.
683         *
684         * @return The picture URI, {@code null} if not specified.
685         */
686        public URI getPicture() {
687        
688                return getURIClaim(PICTURE_CLAIM_NAME);
689        }
690        
691        
692        /**
693         * Sets the picture. Corresponds to the {@code picture} claim.
694         *
695         * @param picture The picture URI. If {@code null} the claim will be
696         *                removed.
697         */
698        public void setPicture(final URI picture) {
699        
700                setURIClaim(PICTURE_CLAIM_NAME, picture);
701        }
702        
703        
704        // website
705        
706        
707        /**
708         * Gets the web page or blog. Corresponds to the {@code website} claim.
709         *
710         * @return The web page or blog URI, {@code null} if not specified.
711         */
712        public URI getWebsite() {
713        
714                return getURIClaim(WEBSITE_CLAIM_NAME);
715        }
716        
717        
718        /**
719         * Sets the web page or blog. Corresponds to the {@code website} claim.
720         *
721         * @param website The web page or blog URI. If {@code null} the claim
722         *                will be removed.
723         */
724        public void setWebsite(final URI website) {
725        
726                setURIClaim(WEBSITE_CLAIM_NAME, website);
727        }
728        
729        
730        // email
731        
732        
733        /**
734         * Gets the preferred email address. Corresponds to the {@code email}
735         * claim.
736         *
737         * @return The preferred email address, {@code null} if not specified.
738         */
739        public String getEmailAddress() {
740        
741                return getStringClaim(EMAIL_CLAIM_NAME);
742        }
743        
744        
745        /**
746         * Sets the preferred email address. Corresponds to the {@code email}
747         * claim.
748         *
749         * @param email The preferred email address. If {@code null} the claim
750         *              will be removed.
751         */
752        public void setEmailAddress(final String email) {
753        
754                setClaim(EMAIL_CLAIM_NAME, email);
755        }
756        
757        
758        // email_verified
759        
760        
761        /**
762         * Gets the email verification status. Corresponds to the 
763         * {@code email_verified} claim.
764         *
765         * @return The email verification status, {@code null} if not 
766         *         specified.
767         */
768        public Boolean getEmailVerified() {
769        
770                return getBooleanClaim(EMAIL_VERIFIED_CLAIM_NAME);
771        }
772        
773        
774        /**
775         * Sets the email verification status. Corresponds to the
776         * {@code email_verified} claim.
777         *
778         * @param emailVerified The email verification status. If {@code null} 
779         *                      the claim will be removed.
780         */
781        public void setEmailVerified(final Boolean emailVerified) {
782        
783                setClaim(EMAIL_VERIFIED_CLAIM_NAME, emailVerified);
784        }
785        
786        
787        // gender
788        
789        
790        /**
791         * Gets the gender. Corresponds to the {@code gender} claim.
792         *
793         * @return The gender, {@code null} if not specified.
794         */
795        public Gender getGender() {
796        
797                String value = getStringClaim(GENDER_CLAIM_NAME);
798                
799                if (value == null)
800                        return null;
801
802                return new Gender(value);
803        }
804        
805        
806        /**
807         * Sets the gender. Corresponds to the {@code gender} claim.
808         *
809         * @param gender The gender. If {@code null} the claim will be removed.
810         */
811        public void setGender(final Gender gender) {
812        
813                if (gender != null)
814                        setClaim(GENDER_CLAIM_NAME, gender.getValue());
815                else
816                        setClaim(GENDER_CLAIM_NAME, null);
817        }
818        
819        
820        // birthdate
821        
822        
823        /**
824         * Gets the date of birth. Corresponds to the {@code birthdate} claim.
825         *
826         * @return The date of birth, {@code null} if not specified.
827         */
828        public String getBirthdate() {
829        
830                return getStringClaim(BIRTHDATE_CLAIM_NAME);
831        }
832        
833        
834        /**
835         * Sets the date of birth. Corresponds to the {@code birthdate} claim.
836         *
837         * @param birthdate The date of birth. If {@code null} the claim will
838         *                  be removed.
839         */
840        public void setBirthdate(final String birthdate) {
841        
842                setClaim(BIRTHDATE_CLAIM_NAME, birthdate);
843        }
844        
845        
846        // zoneinfo
847        
848        
849        /**
850         * Gets the zoneinfo. Corresponds to the {@code zoneinfo} claim.
851         *
852         * @return The zoneinfo, {@code null} if not specified.
853         */
854        public String getZoneinfo() {
855        
856                return getStringClaim(ZONEINFO_CLAIM_NAME);
857        }
858        
859        
860        /**
861         * Sets the zoneinfo. Corresponds to the {@code zoneinfo} claim.
862         *
863         * @param zoneinfo The zoneinfo. If {@code null} the claim will be 
864         *                 removed.
865         */
866        public void setZoneinfo(final String zoneinfo) {
867        
868                setClaim(ZONEINFO_CLAIM_NAME, zoneinfo);
869        }
870        
871        
872        // locale
873        
874        
875        /**
876         * Gets the locale. Corresponds to the {@code locale} claim.
877         *
878         * @return The locale, {@code null} if not specified.
879         */
880        public String getLocale() {
881        
882                return getStringClaim(LOCALE_CLAIM_NAME);
883        }
884        
885        
886        /**
887         * Sets the locale. Corresponds to the {@code locale} claim.
888         *
889         * @param locale The locale. If {@code null} the claim will be 
890         *               removed.
891         */
892        public void setLocale(final String locale) {
893        
894                setClaim(LOCALE_CLAIM_NAME, locale);
895        }
896        
897        
898        // phone_number
899        
900        
901        /**
902         * Gets the preferred telephone number. Corresponds to the 
903         * {@code phone_number} claim.
904         *
905         * @return The preferred telephone number, {@code null} if not 
906         *         specified.
907         */
908        public String getPhoneNumber() {
909        
910                return getStringClaim(PHONE_NUMBER_CLAIM_NAME);
911        }
912        
913        
914        /**
915         * Sets the preferred telephone number. Corresponds to the 
916         * {@code phone_number} claim.
917         *
918         * @param phoneNumber The preferred telephone number. If {@code null} 
919         *                    the claim will be removed.
920         */
921        public void setPhoneNumber(final String phoneNumber) {
922        
923                setClaim(PHONE_NUMBER_CLAIM_NAME, phoneNumber);
924        }
925        
926        
927        // phone_number_verified
928        
929        
930        /**
931         * Gets the phone number verification status. Corresponds to the 
932         * {@code phone_number_verified} claim.
933         *
934         * @return The phone number verification status, {@code null} if not 
935         *         specified.
936         */
937        public Boolean getPhoneNumberVerified() {
938        
939                return getBooleanClaim(PHONE_NUMBER_VERIFIED_CLAIM_NAME);
940        }
941        
942        
943        /**
944         * Sets the email verification status. Corresponds to the
945         * {@code phone_number_verified} claim.
946         *
947         * @param phoneNumberVerified The phone number verification status. If 
948         *                            {@code null} the claim will be removed.
949         */
950        public void setPhoneNumberVerified(final Boolean phoneNumberVerified) {
951        
952                setClaim(PHONE_NUMBER_VERIFIED_CLAIM_NAME, phoneNumberVerified);
953        }
954        
955        
956        // address
957
958
959        /**
960         * Gets the preferred address. Corresponds to the {@code address} 
961         * claim, with no language tag.
962         *
963         * @return The preferred address, {@code null} if not specified.
964         */
965        public Address getAddress() {
966        
967                return getAddress(null);
968        }
969        
970        
971        /**
972         * Gets the preferred address. Corresponds to the {@code address} 
973         * claim, with an optional language tag.
974         *
975         * @param langTag The language tag of the entry, {@code null} to get 
976         *                the non-tagged entry.
977         *
978         * @return The preferred address, {@code null} if not specified.
979         */
980        public Address getAddress(final LangTag langTag) {
981        
982                String name;
983
984                if (langTag!= null)
985                        name = ADDRESS_CLAIM_NAME + "#" + langTag;
986                else
987                        name = ADDRESS_CLAIM_NAME;
988
989                JSONObject jsonObject = getClaim(name, JSONObject.class);
990
991                if (jsonObject == null)
992                        return null;
993
994                return new Address(jsonObject);
995        }
996        
997        
998        /**
999         * Gets the preferred address entries. Correspond to the 
1000         * {@code address} claim.
1001         *
1002         * @return The preferred address entries, empty map if none.
1003         */
1004        public Map<LangTag,Address> getAddressEntries() {
1005        
1006                Map<LangTag,JSONObject> entriesIn = getLangTaggedClaim(ADDRESS_CLAIM_NAME, JSONObject.class);
1007
1008                Map<LangTag,Address> entriesOut = new HashMap<>();
1009
1010                for (Map.Entry<LangTag,JSONObject> en: entriesIn.entrySet())
1011                        entriesOut.put(en.getKey(), new Address(en.getValue()));
1012
1013                return entriesOut;
1014        }
1015
1016
1017        /**
1018         * Sets the preferred address. Corresponds to the {@code address} 
1019         * claim, with no language tag.
1020         *
1021         * @param address The preferred address. If {@code null} the claim will
1022         *                be removed.
1023         */
1024        public void setAddress(final Address address) {
1025        
1026                if (address != null)
1027                        setClaim(ADDRESS_CLAIM_NAME, address.toJSONObject());
1028                else
1029                        setClaim(ADDRESS_CLAIM_NAME, null);
1030        }
1031        
1032        
1033        /**
1034         * Sets the preferred address. Corresponds to the {@code address}
1035         * claim, with an optional language tag.
1036         *
1037         * @param address  The preferred address. If {@code null} the claim 
1038         *                 will be removed.
1039         * @param langTag The language tag, {@code null} if not specified.
1040         */
1041        public void setAddress(final Address address, final LangTag langTag) {
1042
1043                String key = langTag == null ? ADDRESS_CLAIM_NAME : ADDRESS_CLAIM_NAME + "#" + langTag;
1044
1045                if (address != null)
1046                        setClaim(key, address.toJSONObject());
1047                else
1048                        setClaim(key, null);
1049        }
1050        
1051        
1052        // updated_at
1053        
1054        
1055        /**
1056         * Gets the time the end-user information was last updated. Corresponds 
1057         * to the {@code updated_at} claim.
1058         *
1059         * @return The time the end-user information was last updated, 
1060         *         {@code null} if not specified.
1061         */
1062        public Date getUpdatedTime() {
1063        
1064                return getDateClaim(UPDATED_AT_CLAIM_NAME);
1065        }
1066        
1067        
1068        /**
1069         * Sets the time the end-user information was last updated. Corresponds
1070         * to the {@code updated_at} claim.
1071         *
1072         * @param updatedTime The time the end-user information was last 
1073         *                    updated. If {@code null} the claim will be 
1074         *                    removed.
1075         */
1076        public void setUpdatedTime(final Date updatedTime) {
1077        
1078                setDateClaim(UPDATED_AT_CLAIM_NAME, updatedTime);
1079        }
1080        
1081        
1082        // birthplace
1083        
1084        
1085        /**
1086         * Gets the birthplace. Corresponds to the {@code birthplace} claim
1087         * from OpenID Connect for Identity Assurance 1.0.
1088         *
1089         * @return The birthplace, {@code null} if not specified.
1090         */
1091        public Birthplace getBirthplace() {
1092                
1093                JSONObject jsonObject = getClaim(BIRTHPLACE_CLAIM_NAME, JSONObject.class);
1094                
1095                if (jsonObject == null) {
1096                        return null;
1097                }
1098                
1099                return new Birthplace(jsonObject);
1100        }
1101        
1102        
1103        /**
1104         * Sets the birthplace. Corresponds to the {@code birthplace} claim
1105         * from OpenID Connect for Identity Assurance 1.0.
1106         *
1107         * @param birthplace The birthplace, {@code null} if not specified.
1108         */
1109        public void setBirthplace(final Birthplace birthplace) {
1110                
1111                if (birthplace != null) {
1112                        setClaim(BIRTHPLACE_CLAIM_NAME, birthplace.toJSONObject());
1113                }
1114        }
1115        
1116        
1117        // place_of_birth
1118        
1119        
1120        /**
1121         * Gets the birthplace. Corresponds to the {@code place_of_birth} claim
1122         * from OpenID Connect for Identity Assurance 1.0. Alternative for
1123         * {@link #getBirthplace()}.
1124         *
1125         * @return The birthplace, {@code null} if not specified.
1126         */
1127        public Birthplace getPlaceOfBirth() {
1128                
1129                JSONObject jsonObject = getClaim(PLACE_OF_BIRTH_CLAIM_NAME, JSONObject.class);
1130                
1131                if (jsonObject == null) {
1132                        return null;
1133                }
1134                
1135                return new Birthplace(jsonObject);
1136        }
1137        
1138        
1139        /**
1140         * Sets the birthplace. Corresponds to the {@code place_of_birth} claim
1141         * from OpenID Connect for Identity Assurance 1.0. Alternative for
1142         * {@link #setBirthplace(Birthplace)}.
1143         *
1144         * @param birthplace The birthplace, {@code null} if not specified.
1145         */
1146        public void setPlaceOfBirth(final Birthplace birthplace) {
1147                
1148                if (birthplace != null) {
1149                        setClaim(PLACE_OF_BIRTH_CLAIM_NAME, birthplace.toJSONObject());
1150                }
1151        }
1152        
1153        
1154        // nationalities
1155        
1156        /**
1157         * Gets the user's nationalities. Corresponds to the
1158         * {@code nationalities} claim from OpenID Connect for Identity
1159         * Assurance 1.0.
1160         *
1161         * @return The nationalities, {@code null} if not specified or parsing
1162         *         failed.
1163         */
1164        public List<CountryCode> getNationalities() {
1165        
1166                List<String> values = getStringListClaim(NATIONALITIES_CLAIM_NAME);
1167                
1168                if (values == null) {
1169                        return null;
1170                }
1171                
1172                List<CountryCode> codes = new LinkedList<>();
1173                for (String v: values) {
1174                        if (v != null) {
1175                                try {
1176                                        codes.add(CountryCode.parse(v));
1177                                } catch (ParseException e) {
1178                                        return null;
1179                                }
1180                        }
1181                }
1182                return codes;
1183        }
1184        
1185        
1186        /**
1187         * Sets the user's nationalities. Corresponds to the
1188         * {@code nationalities} claim from OpenID Connect for Identity
1189         * Assurance 1.0.
1190         *
1191         * @param nationalities The nationalities, {@code null} if not
1192         *                      specified.
1193         */
1194        public void setNationalities(final List<CountryCode> nationalities) {
1195        
1196                List<String> values = null;
1197                
1198                if (nationalities != null) {
1199                        values = new LinkedList<>();
1200                        for (CountryCode code: nationalities) {
1201                                if (code != null) {
1202                                        values.add(code.getValue());
1203                                }
1204                        }
1205                }
1206                
1207                setClaim(NATIONALITIES_CLAIM_NAME, values);
1208        }
1209        
1210        
1211        // birth_family_name
1212        
1213        /**
1214         * Gets the birth family name. Corresponds to the
1215         * {@code birth_family_name} claim from OpenID Connect for Identity
1216         * Assurance 1.0, with no language tag.
1217         *
1218         * @return The birth family name, {@code null} if not specified.
1219         */
1220        public String getBirthFamilyName() {
1221                
1222                return getStringClaim(BIRTH_FAMILY_NAME_CLAIM_NAME);
1223        }
1224        
1225        
1226        /**
1227         * Gets the birth family name. Corresponds to the 
1228         * {@code birth_family_name} claim from OpenID Connect for Identity 
1229         * Assurance 1.0, with an optional language tag.
1230         *
1231         * @param langTag The language tag of the entry, {@code null} to get 
1232         *                the non-tagged entry.
1233         *
1234         * @return The birth family name, {@code null} if not specified.
1235         */
1236        public String getBirthFamilyName(final LangTag langTag) {
1237                
1238                return getStringClaim(BIRTH_FAMILY_NAME_CLAIM_NAME, langTag);
1239        }
1240        
1241        
1242        /**
1243         * Gets the birth family name entries. Correspond to the 
1244         * {@code birth_family_name} claim from OpenID Connect for Identity 
1245         * Assurance 1.0.
1246         *
1247         * @return The birth family name entries, empty map if none.
1248         */
1249        public Map<LangTag,String> getBirthFamilyNameEntries() {
1250                
1251                return getLangTaggedClaim(BIRTH_FAMILY_NAME_CLAIM_NAME, String.class);
1252        }
1253        
1254        
1255        /**
1256         * Sets the birth family name. Corresponds to the
1257         * {@code birth_family_name} claim from OpenID Connect for Identity
1258         * Assurance 1.0, with no language tag.
1259         *
1260         * @param birthFamilyName The birth family name, {@code null} if not
1261         *                        specified.
1262         */
1263        public void setBirthFamilyName(final String birthFamilyName) {
1264                
1265                setClaim(BIRTH_FAMILY_NAME_CLAIM_NAME, birthFamilyName);
1266        }
1267        
1268        
1269        /**
1270         * Sets the birth family name. Corresponds to the 
1271         * {@code birth_family_name} claim from OpenID Connect for Identity
1272         * Assurance 1.0, with an optional language tag.
1273         *
1274         * @param birthFamilyName The birth family name. If {@code null} the 
1275         *                        claim will be removed.
1276         * @param langTag         The language tag, {@code null} if not 
1277         *                        specified.
1278         */
1279        public void setBirthFamilyName(final String birthFamilyName, final LangTag langTag) {
1280                
1281                setClaim(BIRTH_FAMILY_NAME_CLAIM_NAME, birthFamilyName, langTag);
1282        }
1283        
1284        // birth_given_name
1285        
1286        /**
1287         * Gets the birth given name. Corresponds to the
1288         * {@code birth_given_name} claim from OpenID Connect for Identity
1289         * Assurance 1.0, with no language tag.
1290         *
1291         * @return The birth given name, {@code null} if not specified.
1292         */
1293        public String getBirthGivenName() {
1294                
1295                return getStringClaim(BIRTH_GIVEN_NAME_CLAIM_NAME);
1296        }
1297        
1298        
1299        /**
1300         * Gets the birth given name. Corresponds to the 
1301         * {@code birth_given_name} claim from OpenID Connect for Identity 
1302         * Assurance 1.0, with an optional language tag.
1303         *
1304         * @param langTag The language tag of the entry, {@code null} to get 
1305         *                the non-tagged entry.
1306         *
1307         * @return The birth given name, {@code null} if not specified.
1308         */
1309        public String getBirthGivenName(final LangTag langTag) {
1310                
1311                return getStringClaim(BIRTH_GIVEN_NAME_CLAIM_NAME, langTag);
1312        }
1313        
1314        
1315        /**
1316         * Gets the birth given name entries. Correspond to the 
1317         * {@code birth_given_name} claim from OpenID Connect for Identity 
1318         * Assurance 1.0.
1319         *
1320         * @return The birth given name entries, empty map if none.
1321         */
1322        public Map<LangTag,String> getBirthGivenNameEntries() {
1323                
1324                return getLangTaggedClaim(BIRTH_GIVEN_NAME_CLAIM_NAME, String.class);
1325        }
1326        
1327        
1328        /**
1329         * Sets the birth given name. Corresponds to the
1330         * {@code birth_given_name} claim from OpenID Connect for Identity
1331         * Assurance 1.0.
1332         *
1333         * @param birthGivenName The birth given name, {@code null} if not
1334         *                       specified.
1335         */
1336        public void setBirthGivenName(final String birthGivenName) {
1337                
1338                setClaim(BIRTH_GIVEN_NAME_CLAIM_NAME, birthGivenName);
1339        }
1340        
1341        
1342        /**
1343         * Sets the birth given name. Corresponds to the 
1344         * {@code birth_given_name} claim from OpenID Connect for Identity
1345         * Assurance 1.0, with an optional language tag.
1346         *
1347         * @param birthGivenName The birth given name. If {@code null} the 
1348         *                       claim will be removed.
1349         * @param langTag        The language tag, {@code null} if not 
1350         *                       specified.
1351         */
1352        public void setBirthGivenName(final String birthGivenName, final LangTag langTag) {
1353                
1354                setClaim(BIRTH_GIVEN_NAME_CLAIM_NAME, birthGivenName, langTag);
1355        }
1356        
1357        
1358        // birth_middle_name
1359        
1360        
1361        /**
1362         * Gets the birth middle name. Corresponds to the
1363         * {@code birth_middle_name} claim from OpenID Connect for Identity
1364         * Assurance 1.0, with no language tag.
1365         *
1366         * @return The birth middle name, {@code null} if not specified.
1367         */
1368        public String getBirthMiddleName() {
1369                
1370                return getStringClaim(BIRTH_MIDDLE_NAME_CLAIM_NAME);
1371        }
1372        
1373        
1374        /**
1375         * Gets the birth middle name. Corresponds to the 
1376         * {@code birth_middle_name} claim from OpenID Connect for Identity 
1377         * Assurance 1.0, with an optional language tag.
1378         *
1379         * @param langTag The language tag of the entry, {@code null} to get 
1380         *                the non-tagged entry.
1381         *
1382         * @return The birth middle name, {@code null} if not specified.
1383         */
1384        public String getBirthMiddleName(final LangTag langTag) {
1385                
1386                return getStringClaim(BIRTH_MIDDLE_NAME_CLAIM_NAME, langTag);
1387        }
1388        
1389        
1390        /**
1391         * Gets the birth middle name entries. Correspond to the 
1392         * {@code birth_middle_name} claim from OpenID Connect for Identity 
1393         * Assurance 1.0.
1394         *
1395         * @return The birth middle name entries, empty map if none.
1396         */
1397        public Map<LangTag,String> getBirthMiddleNameEntries() {
1398                
1399                return getLangTaggedClaim(BIRTH_MIDDLE_NAME_CLAIM_NAME, String.class);
1400        }
1401        
1402        
1403        /**
1404         * Sets the birth middle name. Corresponds to the
1405         * {@code birth_middle_name} claim from OpenID Connect for Identity
1406         * Assurance 1.0.
1407         *
1408         * @param birthMiddleName The birth middle name, {@code null} if not
1409         *                        specified.
1410         */
1411        public void setBirthMiddleName(final String birthMiddleName) {
1412                
1413                setClaim(BIRTH_MIDDLE_NAME_CLAIM_NAME, birthMiddleName);
1414        }
1415        
1416        
1417        /**
1418         * Sets the birth middle name. Corresponds to the 
1419         * {@code birth_middle_name} claim from OpenID Connect for Identity
1420         * Assurance 1.0, with an optional language tag.
1421         *
1422         * @param birthMiddleName The birth middle name. If {@code null} the 
1423         *                        claim will be removed.
1424         * @param langTag         The language tag, {@code null} if not
1425         *                        specified.
1426         */
1427        public void setBirthMiddleName(final String birthMiddleName, final LangTag langTag) {
1428                
1429                setClaim(BIRTH_MIDDLE_NAME_CLAIM_NAME, birthMiddleName, langTag);
1430        }
1431        
1432        
1433        // salutation
1434        
1435        
1436        /**
1437         * Gets the salutation. Corresponds to the {@code salutation} claim
1438         * from OpenID Connect for Identity Assurance 1.0, with no language 
1439         * tag.
1440         *
1441         * @return The salutation, {@code null} if not specified.
1442         */
1443        public String getSalutation() {
1444                
1445                return getStringClaim(SALUTATION_CLAIM_NAME);
1446        }
1447        
1448        
1449        /**
1450         * Gets the salutation. Corresponds to the {@code salutation} claim
1451         * from OpenID Connect for Identity Assurance 1.0, with an optional
1452         * language tag.
1453         *
1454         * @param langTag The language tag of the entry, {@code null} to get 
1455         *                the non-tagged entry.
1456         *
1457         * @return The salutation, {@code null} if not specified.
1458         */
1459        public String getSalutation(final LangTag langTag) {
1460                
1461                return getStringClaim(SALUTATION_CLAIM_NAME, langTag);
1462        }
1463        
1464        
1465        /**
1466         * Gets the salutation entries. Correspond to the {@code salutation}
1467         * claim from OpenID Connect for Identity Assurance 1.0.
1468         *
1469         * @return The salutation entries, empty map if none.
1470         */
1471        public Map<LangTag,String> getSalutationEntries() {
1472                
1473                return getLangTaggedClaim(SALUTATION_CLAIM_NAME, String.class);
1474        }
1475        
1476        
1477        /**
1478         * Sets the salutation. Corresponds to the {@code salutation} claim
1479         * from OpenID Connect for Identity Assurance 1.0.
1480         *
1481         * @param salutation The salutation, {@code null} if not specified.
1482         */
1483        public void setSalutation(final String salutation) {
1484                
1485                setClaim(SALUTATION_CLAIM_NAME, salutation);
1486        }
1487        
1488        
1489        /**
1490         * Sets the salutation. Corresponds to the {@code salutation} claim
1491         * from OpenID Connect for Identity Assurance 1.0, with an optional
1492         * language tag.
1493         *
1494         * @param salutation The salutation. If {@code null} the claim will be
1495         *                   removed.
1496         * @param langTag    The language tag, {@code null} if not specified.
1497         */
1498        public void setSalutation(final String salutation, final LangTag langTag) {
1499                
1500                setClaim(SALUTATION_CLAIM_NAME, salutation, langTag);
1501        }
1502        
1503        
1504        // title
1505        
1506        
1507        /**
1508         * Gets the title. Corresponds to the {@code title} claim from OpenID
1509         * Connect for Identity Assurance 1.0, with no language tag.
1510         *
1511         * @return The salutation, {@code null} if not specified.
1512         */
1513        public String getTitle() {
1514                
1515                return getStringClaim(TITLE_CLAIM_NAME);
1516        }
1517        
1518        
1519        /**
1520         * Gets the title. Corresponds to the {@code title} claim from OpenID 
1521         * Connect for Identity Assurance 1.0, with an optional language tag.
1522         *
1523         * @param langTag The language tag of the entry, {@code null} to get 
1524         *                the non-tagged entry.
1525         *
1526         * @return The title, {@code null} if not specified.
1527         */
1528        public String getTitle(final LangTag langTag) {
1529                
1530                return getStringClaim(TITLE_CLAIM_NAME, langTag);
1531        }
1532        
1533        
1534        /**
1535         * Gets the title entries. Correspond to the {@code title} claim from 
1536         * OpenID Connect for Identity Assurance 1.0.
1537         *
1538         * @return The title entries, empty map if none.
1539         */
1540        public Map<LangTag,String> getTitleEntries() {
1541                
1542                return getLangTaggedClaim(TITLE_CLAIM_NAME, String.class);
1543        }
1544        
1545        
1546        /**
1547         * Sets the title. Corresponds to the {@code title} claim from OpenID
1548         * Connect for Identity Assurance 1.0.
1549         *
1550         * @param title The title, {@code null} if not specified.
1551         */
1552        public void setTitle(final String title) {
1553                
1554                setClaim(TITLE_CLAIM_NAME, title);
1555        }
1556        
1557        
1558        /**
1559         * Sets the title. Corresponds to the {@code title} claim from OpenID 
1560         * Connect for Identity Assurance 1.0, with an optional language tag.
1561         *
1562         * @param title   The title. If {@code null} the claim will be removed.
1563         * @param langTag The language tag, {@code null} if not specified.
1564         */
1565        public void setTitle(final String title, final LangTag langTag) {
1566                
1567                setClaim(TITLE_CLAIM_NAME, title, langTag);
1568        }
1569}