001 package com.nimbusds.jose; 002 003 004 import java.text.ParseException; 005 006 import javax.mail.internet.ContentType; 007 import javax.mail.internet.ParameterList; 008 009 import net.jcip.annotations.ThreadSafe; 010 011 import com.nimbusds.jose.util.Base64URL; 012 013 014 /** 015 * Plaintext (unsecured) JOSE object. This class is thread-safe. 016 * 017 * @author Vladimir Dzhuvinov 018 * @version $version$ (2013-05-04) 019 */ 020 @ThreadSafe 021 public class PlainObject extends JOSEObject { 022 023 024 /** 025 * The MIME type of plain JOSE objects serialised to a compact form: 026 * {@code application/jws; charset=UTF-8} 027 */ 028 public static final ContentType MIME_TYPE_COMPACT; 029 030 031 /** 032 * The MIME type of plain JOSE objects serialised to a JSON object 033 * form: {@code application/jws-js; charset=UTF-8} 034 */ 035 public static final ContentType MIME_TYPE_JS; 036 037 038 static { 039 040 final ParameterList params = new ParameterList(); 041 params.set("charset", "UTF-8"); 042 043 MIME_TYPE_COMPACT = new ContentType("application", "jws", params); 044 045 MIME_TYPE_JS = new ContentType("application", "jws-js", params); 046 } 047 048 049 /** 050 * The header. 051 */ 052 private final PlainHeader header; 053 054 055 /** 056 * Creates a new plaintext JOSE object with a default 057 * {@link PlainHeader} and the specified payload. 058 * 059 * @param payload The payload. Must not be {@code null}. 060 */ 061 public PlainObject(final Payload payload) { 062 063 if (payload == null) { 064 065 throw new IllegalArgumentException("The payload must not be null"); 066 } 067 068 setPayload(payload); 069 070 header = new PlainHeader(); 071 } 072 073 074 /** 075 * Creates a new plaintext JOSE object with the specified header and 076 * payload. 077 * 078 * @param header The plaintext header. Must not be {@code null}. 079 * @param payload The payload. Must not be {@code null}. 080 */ 081 public PlainObject(final PlainHeader header, final Payload payload) { 082 083 if (header == null) { 084 085 throw new IllegalArgumentException("The plain header must not be null"); 086 } 087 088 this.header = header; 089 090 if (payload == null) { 091 092 throw new IllegalArgumentException("The payload must not be null"); 093 } 094 095 setPayload(payload); 096 } 097 098 099 /** 100 * Creates a new plaintext JOSE object with the specified 101 * Base64URL-encoded parts. 102 * 103 * @param firstPart The first part, corresponding to the plaintext 104 * header. Must not be {@code null}. 105 * @param secondPart The second part, corresponding to the payload. 106 * Must not be {@code null}. 107 * 108 * @throws ParseException If parsing of the serialised parts failed. 109 */ 110 public PlainObject(final Base64URL firstPart, final Base64URL secondPart) 111 throws ParseException { 112 113 if (firstPart == null) { 114 115 throw new IllegalArgumentException("The first part must not be null"); 116 } 117 118 try { 119 header = PlainHeader.parse(firstPart); 120 121 } catch (ParseException e) { 122 123 throw new ParseException("Invalid plain header: " + e.getMessage(), 0); 124 } 125 126 if (secondPart == null) { 127 128 throw new IllegalArgumentException("The second part must not be null"); 129 } 130 131 setPayload(new Payload(secondPart)); 132 133 setParsedParts(firstPart, secondPart, null); 134 } 135 136 137 @Override 138 public ReadOnlyPlainHeader getHeader() { 139 140 return header; 141 } 142 143 144 /** 145 * Serialises this plaintext JOSE object to its compact format 146 * consisting of Base64URL-encoded parts delimited by period ('.') 147 * characters. 148 * 149 * <pre> 150 * [header-base64url].[payload-base64url].[] 151 * </pre> 152 * 153 * @return The serialised plaintext JOSE object. 154 */ 155 @Override 156 public String serialize() { 157 158 StringBuilder sb = new StringBuilder(header.toBase64URL().toString()); 159 sb.append('.'); 160 sb.append(getPayload().toBase64URL().toString()); 161 sb.append('.'); 162 return sb.toString(); 163 } 164 165 166 /** 167 * Parses a plaintext JOSE object from the specified string in compact 168 * format. 169 * 170 * @param s The string to parse. Must not be {@code null}. 171 * 172 * @return The plain JOSE object. 173 * 174 * @throws ParseException If the string couldn't be parsed to a valid 175 * plaintext JOSE object. 176 */ 177 public static PlainObject parse(final String s) 178 throws ParseException { 179 180 Base64URL[] parts = JOSEObject.split(s); 181 182 if (! parts[2].toString().isEmpty()) { 183 184 throw new ParseException("Unexpected third Base64URL part", 0); 185 } 186 187 return new PlainObject(parts[0], parts[1]); 188 } 189 }