6060 * @author Marek Potociar (marek.potociar at oracle.com)
6161 */
6262public class InboundEvent {
63- private static final GenericType <String > STRING_AS_GENERIC_TYPE = new GenericType <String >(String .class );
63+
64+ private static final GenericType <String > STRING_AS_GENERIC_TYPE = new GenericType <>(String .class );
6465
6566 private final String name ;
6667 private final String id ;
68+ private final String comment ;
6769 private final byte [] data ;
6870 private final long reconnectDelay ;
6971
@@ -76,6 +78,7 @@ public class InboundEvent {
7678 * Inbound event builder. This implementation is not thread-safe.
7779 */
7880 static class Builder {
81+
7982 private String name ;
8083 private String id ;
8184 private long reconnectDelay = SseFeature .RECONNECT_NOT_SET ;
@@ -85,6 +88,7 @@ static class Builder {
8588 private final Annotation [] annotations ;
8689 private final MediaType mediaType ;
8790 private final MultivaluedMap <String , String > headers ;
91+ private final StringBuilder commentBuilder ;
8892
8993 /**
9094 * Create new inbound event builder.
@@ -106,12 +110,13 @@ public Builder(MessageBodyWorkers workers,
106110 this .mediaType = mediaType ;
107111 this .headers = headers ;
108112
113+ this .commentBuilder = new StringBuilder ();
109114 this .dataStream = new ByteArrayOutputStream ();
110115 }
111116
112117 /**
113118 * Set inbound event name.
114- *
119+ * <p/>
115120 * Value of the received SSE {@code "event"} field.
116121 *
117122 * @param name {@code "event"} field value.
@@ -124,7 +129,7 @@ public Builder name(String name) {
124129
125130 /**
126131 * Set inbound event identifier.
127- *
132+ * <p/>
128133 * Value of the received SSE {@code "id"} field.
129134 *
130135 * @param id {@code "id"} field value.
@@ -135,12 +140,32 @@ public Builder id(String id) {
135140 return this ;
136141 }
137142
143+ /**
144+ * Add a comment line to the event.
145+ * <p>
146+ * The comment line will be added to the received SSE event comment as a new line in the comment field.
147+ * If the comment line parameter is {@code null}, the call will be ignored.
148+ * </p>
149+ *
150+ * @param commentLine comment line to be added to the event comment.
151+ * @return updated builder instance.
152+ * @since 2.21
153+ */
154+ public Builder commentLine (final CharSequence commentLine ) {
155+ if (commentLine != null ) {
156+ commentBuilder .append (commentLine ).append ('\n' );
157+ }
158+
159+ return this ;
160+ }
161+
138162 /**
139163 * Set reconnection delay (in milliseconds) that indicates how long the event receiver should wait
140164 * before attempting to reconnect in case a connection to SSE event source is lost.
141165 * <p>
142166 * Value of the received SSE {@code "retry"} field.
143167 * </p>
168+ *
144169 * @param milliseconds reconnection delay in milliseconds. Negative values un-set the reconnection delay.
145170 * @return updated builder instance.
146171 * @since 2.3
@@ -181,6 +206,7 @@ public InboundEvent build() {
181206 return new InboundEvent (
182207 name ,
183208 id ,
209+ commentBuilder .length () > 0 ? commentBuilder .substring (0 , commentBuilder .length () - 1 ) : null ,
184210 reconnectDelay ,
185211 dataStream .toByteArray (),
186212 workers ,
@@ -190,16 +216,18 @@ public InboundEvent build() {
190216 }
191217 }
192218
193- private InboundEvent (String name ,
194- String id ,
195- long reconnectDelay ,
196- byte [] data ,
197- MessageBodyWorkers messageBodyWorkers ,
198- Annotation [] annotations ,
199- MediaType mediaType ,
200- MultivaluedMap <String , String > headers ) {
219+ private InboundEvent (final String name ,
220+ final String id ,
221+ final String comment ,
222+ final long reconnectDelay ,
223+ final byte [] data ,
224+ final MessageBodyWorkers messageBodyWorkers ,
225+ final Annotation [] annotations ,
226+ final MediaType mediaType ,
227+ final MultivaluedMap <String , String > headers ) {
201228 this .name = name ;
202229 this .id = id ;
230+ this .comment = comment ;
203231 this .reconnectDelay = reconnectDelay ;
204232 this .data = data ;
205233 this .messageBodyWorkers = messageBodyWorkers ;
@@ -235,6 +263,20 @@ public String getId() {
235263 return id ;
236264 }
237265
266+ /**
267+ * Get a comment string that accompanies the event.
268+ * <p>
269+ * Contains value of the comment associated with SSE event. This field is optional. Method may return {@code null},
270+ * if the event comment is not specified.
271+ * </p>
272+ *
273+ * @return comment associated with the event.
274+ * @since 2.21
275+ */
276+ public String getComment () {
277+ return comment ;
278+ }
279+
238280 /**
239281 * Get new connection retry time in milliseconds the event receiver should wait before attempting to
240282 * reconnect after a connection to the SSE event source is lost.
@@ -273,8 +315,7 @@ public boolean isEmpty() {
273315 * Get the original event data string {@link String}.
274316 *
275317 * @return event data de-serialized into a string.
276- * @throws javax.ws.rs.ProcessingException
277- * when provided type can't be read. The thrown exception wraps the original cause.
318+ * @throws javax.ws.rs.ProcessingException when provided type can't be read. The thrown exception wraps the original cause.
278319 * @since 2.3
279320 */
280321 public String readData () {
@@ -286,8 +327,7 @@ public String readData() {
286327 *
287328 * @param type Java type to be used for event data de-serialization.
288329 * @return event data de-serialized as an instance of a given type.
289- * @throws javax.ws.rs.ProcessingException
290- * when provided type can't be read. The thrown exception wraps the original cause.
330+ * @throws javax.ws.rs.ProcessingException when provided type can't be read. The thrown exception wraps the original cause.
291331 * @since 2.3
292332 */
293333 public <T > T readData (Class <T > type ) {
@@ -299,10 +339,10 @@ public <T> T readData(Class<T> type) {
299339 *
300340 * @param type generic type to be used for event data de-serialization.
301341 * @return event data de-serialized as an instance of a given type.
302- * @throws javax.ws.rs.ProcessingException
303- * when provided type can't be read. The thrown exception wraps the original cause.
342+ * @throws javax.ws.rs.ProcessingException when provided type can't be read. The thrown exception wraps the original cause.
304343 * @since 2.3
305344 */
345+ @ SuppressWarnings ("unused" )
306346 public <T > T readData (GenericType <T > type ) {
307347 return readData (type , null );
308348 }
@@ -313,22 +353,21 @@ public <T> T readData(GenericType<T> type) {
313353 * @param messageType Java type to be used for event data de-serialization.
314354 * @param mediaType {@link MediaType media type} to be used for event data de-serialization.
315355 * @return event data de-serialized as an instance of a given type.
316- * @throws javax.ws.rs.ProcessingException
317- * when provided type can't be read. The thrown exception wraps the original cause.
356+ * @throws javax.ws.rs.ProcessingException when provided type can't be read. The thrown exception wraps the original cause.
318357 * @since 2.3
319358 */
359+ @ SuppressWarnings ("unused" )
320360 public <T > T readData (Class <T > messageType , MediaType mediaType ) {
321361 return readData (new GenericType <T >(messageType ), mediaType );
322362 }
323363
324364 /**
325365 * Read event data as a given generic type.
326366 *
327- * @param type generic type to be used for event data de-serialization.
328- * @param mediaType {@link MediaType media type} to be used for event data de-serialization.
367+ * @param type generic type to be used for event data de-serialization.
368+ * @param mediaType {@link MediaType media type} to be used for event data de-serialization.
329369 * @return event data de-serialized as an instance of a given type.
330- * @throws javax.ws.rs.ProcessingException
331- * when provided type can't be read. The thrown exception wraps the original cause.
370+ * @throws javax.ws.rs.ProcessingException when provided type can't be read. The thrown exception wraps the original cause.
332371 * @since 2.3
333372 */
334373 public <T > T readData (GenericType <T > type , MediaType mediaType ) {
@@ -360,8 +399,9 @@ private <T> T readAndCast(GenericType<T> type, MediaType effectiveMediaType, Mes
360399 * Get the raw event data bytes.
361400 *
362401 * @return raw event data bytes. The returned byte array may be empty if the event does not
363- * contain any data.
402+ * contain any data.
364403 */
404+ @ SuppressWarnings ("unused" )
365405 public byte [] getRawData () {
366406 if (isEmpty ()) {
367407 return data ;
@@ -383,6 +423,7 @@ public String toString() {
383423 return "InboundEvent{"
384424 + "name='" + name + '\''
385425 + ", id='" + id + '\''
426+ + ", comment=" + (comment == null ? "[no comments]" : '\'' + comment + '\'' )
386427 + ", data=" + s
387428 + '}' ;
388429 }
0 commit comments