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