001package com.nimbusds.jose;
002
003
004import java.text.ParseException;
005
006import net.jcip.annotations.ThreadSafe;
007
008import com.nimbusds.jose.util.Base64URL;
009
010
011/**
012 * Unsecured (plain / {@code alg=none}) JOSE object. This class is thread-safe.
013 *
014 * @author Vladimir Dzhuvinov
015 * @version 2014-04-08
016 */
017@ThreadSafe
018public class PlainObject extends JOSEObject {
019
020
021        private static final long serialVersionUID = 1L;
022
023
024        /**
025         * The header.
026         */
027        private final PlainHeader header;
028
029
030        /**
031         * Creates a new unsecured JOSE object with a default {@link
032         * PlainHeader} and the specified payload.
033         *
034         * @param payload The payload. Must not be {@code null}.
035         */
036        public PlainObject(final Payload payload) {
037
038                if (payload == null) {
039                        throw new IllegalArgumentException("The payload must not be null");
040                }
041
042                setPayload(payload);
043
044                header = new PlainHeader();
045        }
046
047
048        /**
049         * Creates a new unsecured JOSE object with the specified header and
050         * payload.
051         *
052         * @param header  The unsecured header. Must not be {@code null}.
053         * @param payload The payload. Must not be {@code null}.
054         */
055        public PlainObject(final PlainHeader header, final Payload payload) {
056
057                if (header == null) {
058
059                        throw new IllegalArgumentException("The unsecured header must not be null");
060                }
061
062                this.header = header;
063
064                if (payload == null) {
065
066                        throw new IllegalArgumentException("The payload must not be null");
067                }
068
069                setPayload(payload);
070        }
071
072
073        /**
074         * Creates a new unsecured JOSE object with the specified
075         * Base64URL-encoded parts.
076         *
077         * @param firstPart  The first part, corresponding to the unsecured
078         *                   header. Must not be {@code null}.
079         * @param secondPart The second part, corresponding to the payload. 
080         *                   Must not be {@code null}.
081         *
082         * @throws ParseException If parsing of the serialised parts failed.
083         */
084        public PlainObject(final Base64URL firstPart, final Base64URL secondPart)
085                throws ParseException {
086
087                if (firstPart == null) {
088
089                        throw new IllegalArgumentException("The first part must not be null");
090                }
091
092                try {
093                        header = PlainHeader.parse(firstPart);
094
095                } catch (ParseException e) {
096
097                        throw new ParseException("Invalid unsecured header: " + e.getMessage(), 0);
098                }
099
100                if (secondPart == null) {
101
102                        throw new IllegalArgumentException("The second part must not be null");
103                }
104
105                setPayload(new Payload(secondPart));
106
107                setParsedParts(firstPart, secondPart, null);
108        }
109
110
111        @Override
112        public PlainHeader getHeader() {
113
114                return header;
115        }
116
117
118        /**
119         * Serialises this unsecured JOSE object to its compact format
120         * consisting of Base64URL-encoded parts delimited by period ('.') 
121         * characters.
122         *
123         * <pre>
124         * [header-base64url].[payload-base64url].[]
125         * </pre>
126         *
127         * @return The serialised unsecured JOSE object.
128         */
129        @Override
130        public String serialize() {
131
132                return header.toBase64URL().toString() + '.' + getPayload().toBase64URL().toString() + '.';
133        }
134
135
136        /**
137         * Parses an unsecured JOSE object from the specified string in compact
138         * format.
139         *
140         * @param s The string to parse. Must not be {@code null}.
141         *
142         * @return The unsecured JOSE object.
143         *
144         * @throws ParseException If the string couldn't be parsed to a valid 
145         *                        unsecured JOSE object.
146         */
147        public static PlainObject parse(final String s)
148                throws ParseException {
149
150                Base64URL[] parts = JOSEObject.split(s);
151
152                if (! parts[2].toString().isEmpty()) {
153                        
154                        throw new ParseException("Unexpected third Base64URL part", 0);
155                }
156
157                return new PlainObject(parts[0], parts[1]);
158        }
159}