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-08)
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 instanceof KeyType && this.toString().equals(object.toString());
120            }
121            
122            
123            /**
124             * Returns the string representation of this key type.
125             *
126             * @see #getValue
127             *
128             * @return The string representation.
129             */
130            @Override
131            public String toString() {
132            
133                    return value;
134            }
135            
136            
137            /**
138             * Returns the JSON string representation of this key type.
139             * 
140             * @return The JSON string representation.
141             */
142            @Override
143            public String toJSONString() {
144            
145                    StringBuilder sb = new StringBuilder();
146                    sb.append('"');
147                    sb.append(JSONObject.escape(value));
148                    sb.append('"');
149                    return sb.toString();
150            }
151            
152            
153            /**
154             * Parses a key type from the specified string.
155             *
156             * @param s The string to parse. Must not be {@code null}.
157             *
158             * @return The key type (matching standard key type constant, else a 
159             *         newly created one).
160             *
161             * @throws ParseException If the string couldn't be parsed.
162             */
163            public static KeyType parse(final String s) {
164            
165                    if (s == null)
166                            throw new IllegalArgumentException("The ket type string must not be null");
167                    
168                    if (s.equals(EC.getValue()))
169                            return EC;
170                    
171                    else if (s.equals(RSA.getValue()))
172                            return RSA;
173                    
174                    else
175                            return new KeyType(s, null);
176            }
177    }