001package com.nimbusds.jose;
002
003
004import java.text.ParseException;
005import java.util.Map;
006import java.util.Objects;
007import java.util.Set;
008
009import net.jcip.annotations.Immutable;
010
011import com.nimbusds.jose.util.JSONObjectUtils;
012
013
014/**
015 * JSON Web Signature (JWS) or JSON Web Encryption (JWE) unprotected header
016 * (in a JSON serialisation). This class is immutable.
017 *
018 * @author Alexander Martynov
019 * @author Vladimir Dzhuvinov
020 * @version 2021-10-05
021 */
022@Immutable
023public final class UnprotectedHeader {
024        
025        
026        /**
027         * The header parameters.
028         */
029        private final Map<String, Object> params;
030        
031        
032        /**
033         * Creates a new unprotected header.
034         *
035         * @param params The header parameters. Must not be {@code null}.
036         */
037        private UnprotectedHeader(final Map<String, Object> params) {
038                Objects.requireNonNull(params);
039                this.params = params;
040        }
041        
042        
043        /**
044         * Gets the key ID ({@code kid}) parameter.
045         *
046         * @return The key ID parameter, {@code null} if not specified.
047         */
048        public String getKeyID() {
049                
050                return (String) params.get(HeaderParameterNames.KEY_ID);
051        }
052        
053        
054        /**
055         * Gets a parameter.
056         *
057         * @param name The name of the parameter. Must not be {@code null}.
058         *
059         * @return The parameter, {@code null} if not specified.
060         */
061        public Object getParam(final String name) {
062                
063                return params.get(name);
064        }
065        
066        
067        /**
068         * Gets the names of the included parameters in this unprotected
069         * header.
070         *
071         * @return The included parameters.
072         */
073        public Set<String> getIncludedParams() {
074                
075                return params.keySet();
076        }
077        
078        
079        /**
080         * Returns a JSON object representation of this unprotected header.
081         *
082         * @return The JSON object, empty if no parameters are specified.
083         */
084        public Map<String, Object> toJSONObject() {
085                
086                Map<String, Object> o = JSONObjectUtils.newJSONObject();
087                o.putAll(params);
088                return o;
089        }
090        
091        
092        /**
093         * Parses an unprotected header from the specified JSON object.
094         *
095         * @param jsonObject The JSON object, {@code null} if not specified.
096         *
097         * @return The unprotected header or {@code null}.
098         *
099         * @throws ParseException If the JSON object couldn't be parsed to a
100         *                        valid unprotected header.
101         */
102        public static UnprotectedHeader parse(final Map<String, Object> jsonObject)
103                throws ParseException {
104                
105                if (jsonObject == null) {
106                        return null;
107                }
108                
109                Builder header = new Builder();
110                
111                for (final String name : jsonObject.keySet()) {
112                        header = header.param(name, jsonObject.get(name));
113                }
114                
115                return header.build();
116        }
117        
118        
119        /**
120         * Builder for constructing an unprotected JWS or JWE header.
121         */
122        public static class Builder {
123                
124                
125                private final Map<String, Object> params = JSONObjectUtils.newJSONObject();
126                
127                
128                /**
129                 * Creates a new unprotected header builder.
130                 */
131                public Builder() {
132                
133                }
134                
135                
136                /**
137                 * Sets the key ID ({@code kid}) parameter.
138                 *
139                 * @param kid The key ID parameter, {@code null} if not
140                 *            specified.
141                 *
142                 * @return This builder.
143                 */
144                public Builder keyID(final String kid) {
145                        params.put(HeaderParameterNames.KEY_ID, kid);
146                        return this;
147                }
148                
149                
150                /**
151                 * Sets a parameter.
152                 *
153                 * @param name  The name of the parameter. Must  not be
154                 *              {@code null}.
155                 * @param value The value of the parameter, should map to a
156                 *              valid JSON entity, {@code null} if not
157                 *              specified.
158                 *
159                 * @return This builder.
160                 */
161                public Builder param(final String name, final Object value) {
162                        params.put(name, value);
163                        return this;
164                }
165                
166                
167                /**
168                 * Builds a new unprotected header.
169                 *
170                 * @return The unprotected header.
171                 */
172                public UnprotectedHeader build() {
173                        return new UnprotectedHeader(params);
174                }
175        }
176}