001package com.nimbusds.jose;
002
003
004import java.io.Serializable;
005
006import net.jcip.annotations.Immutable;
007
008import net.minidev.json.JSONAware;
009import net.minidev.json.JSONObject;
010
011
012/**
013 * The base class for algorithm names, with optional implementation 
014 * requirement. This class is immutable.
015 *
016 * <p>Includes constants for the following standard algorithm names:
017 *
018 * <ul>
019 *     <li>{@link #NONE none}
020 * </ul>
021 *
022 * @author Vladimir Dzhuvinov 
023 * @version 2013-03-27
024 */
025@Immutable
026public class Algorithm implements JSONAware, Serializable {
027
028
029        private static final long serialVersionUID = 1L;
030
031
032        /**
033         * No algorithm (unsecured JOSE object without signature / encryption).
034         */
035        public static final Algorithm NONE = new Algorithm("none", Requirement.REQUIRED);
036
037
038        /**
039         * The algorithm name.
040         */
041        private final String name;
042
043
044        /**
045         * The implementation requirement, {@code null} if not known.
046         */
047        private final Requirement requirement;
048
049
050        /**
051         * Creates a new JOSE algorithm name.
052         *
053         * @param name The algorithm name. Must not be {@code null}.
054         * @param req  The implementation requirement, {@code null} if not 
055         *             known.
056         */
057        public Algorithm(final String name, final Requirement req) {
058
059                if (name == null) {
060
061                        throw new IllegalArgumentException("The algorithm name must not be null");
062                }
063
064                this.name = name;
065
066                requirement = req;
067        }
068
069
070        /**
071         * Creates a new JOSE algorithm name.
072         *
073         * @param name The algorithm name. Must not be {@code null}.
074         */
075        public Algorithm(final String name) {
076
077                this(name, null);
078        }
079
080
081        /**
082         * Gets the name of this algorithm.
083         *
084         * @return The algorithm name.
085         */
086        public final String getName() {
087
088                return name;
089        }
090
091
092        /**
093         * Gets the implementation requirement of this algorithm.
094         *
095         * @return The implementation requirement, {@code null} if not known.
096         */
097        public final Requirement getRequirement() {
098
099                return requirement;
100        }
101
102
103        /**
104         * Overrides {@code Object.hashCode()}.
105         *
106         * @return The object hash code.
107         */
108        @Override
109        public final int hashCode() {
110
111                return name.hashCode();
112        }
113
114
115        /**
116         * Overrides {@code Object.equals()}.
117         *
118         * @param object The object to compare to.
119         *
120         * @return {@code true} if the objects have the same value, otherwise
121         *         {@code false}.
122         */
123        @Override
124        public boolean equals(final Object object) {
125
126                return object != null && 
127                       object instanceof Algorithm && 
128                       this.toString().equals(object.toString());
129        }
130
131
132        /**
133         * Returns the string representation of this algorithm.
134         *
135         * @see #getName
136         *
137         * @return The string representation.
138         */
139        @Override
140        public final String toString() {
141
142                return name;
143        }
144
145
146        /**
147         * Returns the JSON string representation of this algorithm.
148         * 
149         * @return The JSON string representation.
150         */
151        @Override
152        public final String toJSONString() {
153
154                return "\"" + JSONObject.escape(name) + '"';
155        }
156}