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