001    package com.nimbusds.jose;
002    
003    
004    import net.minidev.json.JSONAware;
005    import net.minidev.json.JSONObject;
006    
007    import net.jcip.annotations.Immutable;
008    
009    
010    /**
011     * Key type. Used to represent the {@code kty} parameter in JSON Web Keys 
012     * (JWKs). This class is immutable.
013     *
014     * <p>Includes constants for the following standard key types:
015     *
016     * <ul>
017     *     <li>{@link #EC}
018     *     <li>{@link #RSA}
019     * </ul>
020     *
021     * <p>Additional key types can be defined using the constructor.
022     *
023     * @author Vladimir Dzhuvinov
024     * @version $version$ (2013-01-15)
025     */
026    @Immutable
027    public final class KeyType implements JSONAware {
028    
029    
030            /**
031             * The key type value.
032             */
033            private final String value;
034            
035            
036            /**
037             * The implementation requirement, {@code null} if not known.
038             */
039            private final Requirement requirement;
040            
041            
042            /**
043             * Elliptic Curve (DSS) key type (recommended).
044             */
045            public static final KeyType EC = new KeyType("EC", Requirement.RECOMMENDED);
046            
047            
048            /**
049             * RSA (RFC 3447) key type (required).
050             */
051            public static final KeyType RSA = new KeyType("RSA", Requirement.REQUIRED);
052            
053            
054            /**
055             * Creates a new key type with the specified value and implementation 
056             * requirement.
057             *
058             * @param value The key type value. Values are case sensitive. Must not
059             *              be {@code null}.
060             * @param req   The implementation requirement, {@code null} if not 
061             *              known.
062             */
063            public KeyType(final String value, final Requirement req) {
064            
065                    if (value == null)
066                            throw new IllegalArgumentException("The key type value must not be null");
067                    
068                    this.value = value;
069                    
070                    requirement = req;
071            }
072            
073            
074            /**
075             * Gets the value of this key type. Values are case sensitive.
076             *
077             * @return The key type.
078             */
079            public String getValue() {
080            
081                    return value;
082            }
083            
084            
085            /**
086             * Gets the implementation requirement of this key type.
087             *
088             * @return The implementation requirement, {@code null} if not known.
089             */
090            public Requirement getRequirement() {
091            
092                    return requirement;
093            }
094            
095            
096            /**
097             * Overrides {@code Object.hashCode()}.
098             *
099             * @return The object hash code.
100             */
101            @Override
102            public int hashCode() {
103            
104                    return value.hashCode();
105            }
106            
107            
108            /**
109             * Overrides {@code Object.equals()}.
110             *
111             * @param object The object to compare to.
112             *
113             * @return {@code true} if the objects have the same value, otherwise
114             *         {@code false}.
115             */
116            @Override
117            public boolean equals(final Object object) {
118            
119                    return object != null && 
120                           object instanceof KeyType && 
121                           this.toString().equals(object.toString());
122            }
123            
124            
125            /**
126             * Returns the string representation of this key type.
127             *
128             * @see #getValue
129             *
130             * @return The string representation.
131             */
132            @Override
133            public String toString() {
134            
135                    return value;
136            }
137            
138            
139            /**
140             * Returns the JSON string representation of this key type.
141             * 
142             * @return The JSON string representation.
143             */
144            @Override
145            public String toJSONString() {
146            
147                    StringBuilder sb = new StringBuilder();
148                    sb.append('"');
149                    sb.append(JSONObject.escape(value));
150                    sb.append('"');
151                    return sb.toString();
152            }
153            
154            
155            /**
156             * Parses a key type from the specified string.
157             *
158             * @param s The string to parse. Must not be {@code null}.
159             *
160             * @return The key type (matching standard key type constant, else a 
161             *         newly created one).
162             *
163             * @throws ParseException If the string couldn't be parsed.
164             */
165            public static KeyType parse(final String s) {
166            
167                    if (s == null)
168                            throw new IllegalArgumentException("The ket type string must not be null");
169                    
170                    if (s.equals(EC.getValue()))
171                            return EC;
172                    
173                    else if (s.equals(RSA.getValue()))
174                            return RSA;
175                    
176                    else
177                            return new KeyType(s, null);
178            }
179    }