001    package com.nimbusds.jose;
002    
003    
004    import java.text.ParseException;
005    
006    import net.jcip.annotations.ThreadSafe;
007    
008    import 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$ (2012-10-23)
016     */
017    @ThreadSafe
018    public 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 ReadOnlyPlainHeader 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    }