001/*
002 * oauth2-oidc-sdk
003 *
004 * Copyright 2012-2021, 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.assurance.evidences;
019
020
021import java.util.Objects;
022
023import net.jcip.annotations.Immutable;
024import net.minidev.json.JSONObject;
025
026import com.nimbusds.oauth2.sdk.ParseException;
027import com.nimbusds.oauth2.sdk.util.CollectionUtils;
028import com.nimbusds.oauth2.sdk.util.JSONObjectUtils;
029import com.nimbusds.openid.connect.sdk.claims.Address;
030
031
032/**
033 * Voucher.
034 *
035 * <p>Related specifications:
036 *
037 * <ul>
038 *     <li>OpenID Connect for Identity Assurance 1.0, section 5.1.1.3.
039 * </ul>
040 */
041public class Voucher {
042        
043        
044        /**
045         * The name.
046         */
047        private final Name name;
048        
049        
050        /**
051         * The birthdate.
052         */
053        private final String birthdateString;
054        
055        
056        /**
057         * The address.
058         */
059        private final Address address;
060        
061        
062        /**
063         * The occupation.
064         */
065        private final Occupation occupation;
066        
067        
068        /**
069         * The organisation.
070         */
071        private final Organization organization;
072        
073        
074        /**
075         * Creates a new voucher.
076         *
077         * @param name            The name, {@code null} if not specified.
078         * @param birthdateString The birthday string, {@code null} if not
079         *                        specified.
080         * @param address         The address elements, {@code null} if not
081         *                        specified.
082         * @param occupation      The occupation, {@code null} if not
083         *                        specified.
084         * @param organization    The organisation, {@code null} if not
085         *                        specified.
086         */
087        public Voucher(final Name name,
088                       final String birthdateString,
089                       final Address address,
090                       final Occupation occupation,
091                       final Organization organization) {
092                
093                this.name = name;
094                this.birthdateString = birthdateString;
095                this.address = address;
096                this.occupation = occupation;
097                this.organization = organization;
098        }
099        
100        
101        /**
102         * Returns the name.
103         *
104         * @return The name, {@code null} if not specified.
105         */
106        public Name getName() {
107                return name;
108        }
109        
110        
111        /**
112         * Returns the birthdate string.
113         *
114         * @return The birthdate string, {@code null} if not specified.
115         */
116        public String getBirthdateString() {
117                return birthdateString;
118        }
119        
120        
121        /**
122         * Returns the address elements.
123         *
124         * @return The address elements, {@code null} if not specified.
125         */
126        public Address getAddress() {
127                return address;
128        }
129        
130        
131        /**
132         * Returns the occupation.
133         *
134         * @return The occupation, {@code null} if not specified.
135         */
136        public Occupation getOccupation() {
137                return occupation;
138        }
139        
140        
141        /**
142         * Returns the organisation.
143         *
144         * @return The organisation, {@code null} if not specified.
145         */
146        public Organization getOrganization() {
147                return organization;
148        }
149        
150        
151        /**
152         * Returns a JSON object representation of this voucher.
153         *
154         * @return The JSON object.
155         */
156        public JSONObject toJSONObject() {
157                
158                JSONObject o = new JSONObject();
159                if (getName() != null) {
160                        o.put("name", getName().getValue());
161                }
162                if (getBirthdateString() != null) {
163                        o.put("birthdate", getBirthdateString());
164                }
165                if (getAddress() != null) {
166                        o.putAll(getAddress().toJSONObject());
167                }
168                if (getOccupation() != null) {
169                        o.put("occupation", getOccupation().getValue());
170                }
171                if (getOrganization() != null) {
172                        o.put("organization", getOrganization().getValue());
173                }
174                return o;
175        }
176        
177        
178        @Override
179        public boolean equals(Object o) {
180                if (this == o) return true;
181                if (!(o instanceof Voucher)) return false;
182                Voucher voucher = (Voucher) o;
183                return Objects.equals(getName(), voucher.getName()) &&
184                        Objects.equals(getBirthdateString(), voucher.getBirthdateString()) &&
185                        Objects.equals(getAddress(), voucher.getAddress()) &&
186                        Objects.equals(getOccupation(), voucher.getOccupation()) &&
187                        Objects.equals(getOrganization(), voucher.getOrganization());
188        }
189        
190        
191        @Override
192        public int hashCode() {
193                return Objects.hash(
194                        getName(),
195                        getBirthdateString(),
196                        getAddress(),
197                        getOccupation(),
198                        getOrganization()
199                );
200        }
201        
202        
203        /**
204         * Parses a voucher from the specified JSON objecassertEquals("Equality", voucher, Voucher.parse(jsonObject));
205                assertEquals("Hash code", voucher.hashCode(), Voucher.parse(jsonObject).hashCode());t.
206         *
207         * @param jsonObject The JSON object. Must not be {@code null}.
208         *
209         * @return The voucher.
210         *
211         * @throws ParseException If parsing failed.
212         */
213        public static Voucher parse(final JSONObject jsonObject)
214                throws ParseException {
215                
216                try {
217                        Name name = null;
218                        if (jsonObject.get("name") != null) {
219                                name = new Name(JSONObjectUtils.getString(jsonObject, "name"));
220                        }
221                        
222                        String birthdateString = JSONObjectUtils.getString(jsonObject, "birthdate", null);
223                        
224                        Occupation occupation = null;
225                        if (jsonObject.get("occupation") != null) {
226                                occupation = new Occupation(JSONObjectUtils.getString(jsonObject, "occupation"));
227                        }
228                        
229                        Organization organization = null;
230                        if (jsonObject.get("organization") != null) {
231                                organization = new Organization(JSONObjectUtils.getString(jsonObject, "organization"));
232                        }
233                        
234                        Address address = null;
235                        if (CollectionUtils.intersect(Address.getStandardClaimNames(), jsonObject.keySet())) {
236                                
237                                JSONObject addressSpecific = new JSONObject(jsonObject);
238                                addressSpecific.remove("name");
239                                addressSpecific.remove("birthdate");
240                                addressSpecific.remove("occupation");
241                                addressSpecific.remove("organization");
242                                address = new Address(addressSpecific);
243                        }
244                        
245                        return new Voucher(name, birthdateString, address, occupation, organization);
246                        
247                } catch (Exception e) {
248                        throw new ParseException(e.getMessage(), e);
249                }
250        }
251}