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