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 }