From 074e21bf4abf0a2481097e73361dc204dca8d2ab Mon Sep 17 00:00:00 2001 From: Atharva Jadhav Date: Tue, 21 Apr 2026 17:22:04 +0530 Subject: [PATCH 1/2] Update StructuredDataMessage Javadoc for RFC 5424 compliance --- .../log4j/message/StructuredDataMessage.java | 116 ++++++++++++++++++ 1 file changed, 116 insertions(+) diff --git a/log4j-api/src/main/java/org/apache/logging/log4j/message/StructuredDataMessage.java b/log4j-api/src/main/java/org/apache/logging/log4j/message/StructuredDataMessage.java index 46b757d54f2..d2c229990fa 100644 --- a/log4j-api/src/main/java/org/apache/logging/log4j/message/StructuredDataMessage.java +++ b/log4j-api/src/main/java/org/apache/logging/log4j/message/StructuredDataMessage.java @@ -58,6 +58,21 @@ public enum Format { /** * Creates a StructuredDataMessage using an ID (max 32 characters), message, and type (max 32 characters). + *

+ * The {@code id} parameter represents the syslog {@code SD-ID} and is expected to conform to + * RFC 5424 Section 6.3.2. + * It is recommended to use {@link StructuredDataId} instead of a raw {@link String} where possible. + *

+ *

+ * The {@code type} parameter represents the syslog {@code MSGID} and is expected to conform to + * RFC 5424 Section 6.2.7. + *

+ *

+ * Both {@code id} and {@code type} are considered trusted inputs (typically compile-time constants). + * If these values are derived from external or untrusted sources, it is the caller's responsibility + * to validate and sanitize them to ensure RFC-compliant output, especially when used with + * {@code Rfc5424Layout}. + *

* @param id The String id. * @param msg The message. * @param type The message type. @@ -69,6 +84,21 @@ public StructuredDataMessage(final String id, final String msg, final String typ /** * Creates a StructuredDataMessage using an ID (user specified max characters), message, and type (user specified * maximum number of characters). + *

+ * The {@code id} parameter represents the syslog {@code SD-ID} and is expected to conform to + * RFC 5424 Section 6.3.2. + * It is recommended to use {@link StructuredDataId} instead of a raw {@link String} where possible. + *

+ *

+ * The {@code type} parameter represents the syslog {@code MSGID} and is expected to conform to + * RFC 5424 Section 6.2.7. + *

+ *

+ * Both {@code id} and {@code type} are considered trusted inputs (typically compile-time constants). + * If these values are derived from external or untrusted sources, it is the caller's responsibility + * to validate and sanitize them to ensure RFC-compliant output, especially when used with + * {@code Rfc5424Layout}. + *

* @param id The String id. * @param msg The message. * @param type The message type. @@ -85,6 +115,21 @@ public StructuredDataMessage(final String id, final String msg, final String typ /** * Creates a StructuredDataMessage using an ID (max 32 characters), message, type (max 32 characters), and an * initial map of structured data to include. + *

+ * The {@code id} parameter represents the syslog {@code SD-ID} and is expected to conform to + * RFC 5424 Section 6.3.2. + * It is recommended to use {@link StructuredDataId} instead of a raw {@link String} where possible. + *

+ *

+ * The {@code type} parameter represents the syslog {@code MSGID} and is expected to conform to + * RFC 5424 Section 6.2.7. + *

+ *

+ * Both {@code id} and {@code type} are considered trusted inputs (typically compile-time constants). + * If these values are derived from external or untrusted sources, it is the caller's responsibility + * to validate and sanitize them to ensure RFC-compliant output, especially when used with + * {@code Rfc5424Layout}. + *

* @param id The String id. * @param msg The message. * @param type The message type. @@ -97,6 +142,21 @@ public StructuredDataMessage(final String id, final String msg, final String typ /** * Creates a StructuredDataMessage using an (user specified max characters), message, and type (user specified * maximum number of characters, and an initial map of structured data to include. + *

+ * The {@code id} parameter represents the syslog {@code SD-ID} and is expected to conform to + * RFC 5424 Section 6.3.2. + * It is recommended to use {@link StructuredDataId} instead of a raw {@link String} where possible. + *

+ *

+ * The {@code type} parameter represents the syslog {@code MSGID} and is expected to conform to + * RFC 5424 Section 6.2.7. + *

+ *

+ * Both {@code id} and {@code type} are considered trusted inputs (typically compile-time constants). + * If these values are derived from external or untrusted sources, it is the caller's responsibility + * to validate and sanitize them to ensure RFC-compliant output, especially when used with + * {@code Rfc5424Layout}. + *

* @param id The String id. * @param msg The message. * @param type The message type. @@ -115,6 +175,20 @@ public StructuredDataMessage( /** * Creates a StructuredDataMessage using a StructuredDataId, message, and type (max 32 characters). + *

+ * The {@link StructuredDataId} parameter represents the syslog {@code SD-ID} and is expected to conform to + * RFC 5424 Section 6.3.2. + *

+ *

+ * The {@code type} parameter represents the syslog {@code MSGID} and is expected to conform to + * RFC 5424 Section 6.2.7. + *

+ *

+ * Both {@code id} and {@code type} are considered trusted inputs (typically compile-time constants). + * If these values are derived from external or untrusted sources, it is the caller's responsibility + * to validate and sanitize them to ensure RFC-compliant output, especially when used with + * {@code Rfc5424Layout}. + *

* @param id The StructuredDataId. * @param msg The message. * @param type The message type. @@ -125,6 +199,20 @@ public StructuredDataMessage(final StructuredDataId id, final String msg, final /** * Creates a StructuredDataMessage using a StructuredDataId, message, and type (max 32 characters). + *

+ * The {@link StructuredDataId} parameter represents the syslog {@code SD-ID} and is expected to conform to + * RFC 5424 Section 6.3.2. + *

+ *

+ * The {@code type} parameter represents the syslog {@code MSGID} and is expected to conform to + * RFC 5424 Section 6.2.7. + *

+ *

+ * Both {@code id} and {@code type} are considered trusted inputs (typically compile-time constants). + * If these values are derived from external or untrusted sources, it is the caller's responsibility + * to validate and sanitize them to ensure RFC-compliant output, especially when used with + * {@code Rfc5424Layout}. + *

* @param id The StructuredDataId. * @param msg The message. * @param type The message type. @@ -141,6 +229,20 @@ public StructuredDataMessage(final StructuredDataId id, final String msg, final /** * Creates a StructuredDataMessage using a StructuredDataId, message, type (max 32 characters), and an initial map * of structured data to include. + *

+ * The {@link StructuredDataId} parameter represents the syslog {@code SD-ID} and is expected to conform to + * RFC 5424 Section 6.3.2. + *

+ *

+ * The {@code type} parameter represents the syslog {@code MSGID} and is expected to conform to + * RFC 5424 Section 6.2.7. + *

+ *

+ * Both {@code id} and {@code type} are considered trusted inputs (typically compile-time constants). + * If these values are derived from external or untrusted sources, it is the caller's responsibility + * to validate and sanitize them to ensure RFC-compliant output, especially when used with + * {@code Rfc5424Layout}. + *

* @param id The StructuredDataId. * @param msg The message. * @param type The message type. @@ -154,6 +256,20 @@ public StructuredDataMessage( /** * Creates a StructuredDataMessage using a StructuredDataId, message, type (max 32 characters), and an initial map * of structured data to include. + *

+ * The {@link StructuredDataId} parameter represents the syslog {@code SD-ID} and is expected to conform to + * RFC 5424 Section 6.3.2. + *

+ *

+ * The {@code type} parameter represents the syslog {@code MSGID} and is expected to conform to + * RFC 5424 Section 6.2.7. + *

+ *

+ * Both {@code id} and {@code type} are considered trusted inputs (typically compile-time constants). + * If these values are derived from external or untrusted sources, it is the caller's responsibility + * to validate and sanitize them to ensure RFC-compliant output, especially when used with + * {@code Rfc5424Layout}. + *

* @param id The StructuredDataId. * @param msg The message. * @param type The message type. From 5c45e5ac74a92eb01f63c787d8692fd7a849a5f4 Mon Sep 17 00:00:00 2001 From: Atharva Jadhav Date: Tue, 12 May 2026 12:29:43 +0530 Subject: [PATCH 2/2] Update JavaDoc to explain StructuredDataId recommendation; rename id to sdId and type to msgId; validate SD-ID and MSGID inputs in StructuredDataMessage --- .../log4j/message/StructuredDataMessage.java | 473 ++++++++++++------ 1 file changed, 315 insertions(+), 158 deletions(-) diff --git a/log4j-api/src/main/java/org/apache/logging/log4j/message/StructuredDataMessage.java b/log4j-api/src/main/java/org/apache/logging/log4j/message/StructuredDataMessage.java index d2c229990fa..617c29ad5d6 100644 --- a/log4j-api/src/main/java/org/apache/logging/log4j/message/StructuredDataMessage.java +++ b/log4j-api/src/main/java/org/apache/logging/log4j/message/StructuredDataMessage.java @@ -21,11 +21,15 @@ import org.apache.logging.log4j.util.StringBuilders; /** - * Represents a Message that conforms to an RFC 5424 StructuredData element along with the syslog message. + * Represents a Message that conforms to an RFC 5424 StructuredData element + * along with the syslog message. *

- * Thread-safety note: the contents of this message can be modified after construction. - * When using asynchronous loggers and appenders it is not recommended to modify this message after the message is - * logged, because it is undefined whether the logged message string will contain the old values or the modified + * Thread-safety note: the contents of this message can be modified after + * construction. + * When using asynchronous loggers and appenders it is not recommended to modify + * this message after the message is + * logged, because it is undefined whether the logged message string will + * contain the old values or the modified * values. *

* @@ -38,11 +42,11 @@ public class StructuredDataMessage extends MapMessage - * The {@code id} parameter represents the syslog {@code SD-ID} and is expected to conform to - * RFC 5424 Section 6.3.2. - * It is recommended to use {@link StructuredDataId} instead of a raw {@link String} where possible. + * The {@code sdId} parameter represents the syslog {@code SD-ID} and is + * expected + * to conform to + * RFC + * 5424 Section 6.3.2. + * It is recommended to use {@link StructuredDataId} instead of a raw + * {@link String} where possible, + * as it allows specifying a set of allowed keys for structured data elements. *

*

- * The {@code type} parameter represents the syslog {@code MSGID} and is expected to conform to - * RFC 5424 Section 6.2.7. + * The {@code msgId} parameter represents the syslog {@code MSGID} and is + * expected to conform to + * RFC + * 5424 Section 6.2.7. *

*

- * Both {@code id} and {@code type} are considered trusted inputs (typically compile-time constants). - * If these values are derived from external or untrusted sources, it is the caller's responsibility - * to validate and sanitize them to ensure RFC-compliant output, especially when used with + * Both {@code sdId} and {@code msgId} are considered trusted inputs (typically + * compile-time constants). + * If these values are derived from external or untrusted sources, it is the + * caller's responsibility + * to validate and sanitize them to ensure RFC-compliant output, especially when + * used with * {@code Rfc5424Layout}. *

- * @param id The String id. - * @param msg The message. - * @param type The message type. + * + * @param sdId The String SD-ID. + * @param msg The message. + * @param msgId The identifier MSGID. */ - public StructuredDataMessage(final String id, final String msg, final String type) { - this(id, msg, type, MAX_LENGTH); + public StructuredDataMessage(final String sdId, final String msg, final String msgId) { + this(sdId, msg, msgId, MAX_LENGTH); } /** - * Creates a StructuredDataMessage using an ID (user specified max characters), message, and type (user specified + * Creates a StructuredDataMessage using an SD-ID (user specified max + * characters), + * message, and MSGID (user specified * maximum number of characters). *

- * The {@code id} parameter represents the syslog {@code SD-ID} and is expected to conform to - * RFC 5424 Section 6.3.2. - * It is recommended to use {@link StructuredDataId} instead of a raw {@link String} where possible. + * The {@code sdId} parameter represents the syslog {@code SD-ID} and is + * expected + * to conform to + * RFC + * 5424 Section 6.3.2. + * It is recommended to use {@link StructuredDataId} instead of a raw + * {@link String} where possible, + * as it allows specifying a set of allowed keys for structured data elements. *

*

- * The {@code type} parameter represents the syslog {@code MSGID} and is expected to conform to - * RFC 5424 Section 6.2.7. + * The {@code msgId} parameter represents the syslog {@code MSGID} and is + * expected to conform to + * RFC + * 5424 Section 6.2.7. *

*

- * Both {@code id} and {@code type} are considered trusted inputs (typically compile-time constants). - * If these values are derived from external or untrusted sources, it is the caller's responsibility - * to validate and sanitize them to ensure RFC-compliant output, especially when used with + * Both {@code sdId} and {@code msgId} are considered trusted inputs (typically + * compile-time constants). + * If these values are derived from external or untrusted sources, it is the + * caller's responsibility + * to validate and sanitize them to ensure RFC-compliant output, especially when + * used with * {@code Rfc5424Layout}. *

- * @param id The String id. - * @param msg The message. - * @param type The message type. + * + * @param sdId The String SD-ID. + * @param msg The message. + * @param msgId The message identifier MSGID. * @param maxLength The maximum length of keys; * @since 2.9.0 */ - public StructuredDataMessage(final String id, final String msg, final String type, final int maxLength) { - this.id = new StructuredDataId(id, null, null, maxLength); + public StructuredDataMessage(final String sdId, final String msg, final String msgId, final int maxLength) { + validateSdId(sdId); + validateMsgId(msgId); + + this.sdId = new StructuredDataId(sdId, null, null, maxLength); this.message = msg; - this.type = type; + this.msgId = msgId; this.maxLength = maxLength; } /** - * Creates a StructuredDataMessage using an ID (max 32 characters), message, type (max 32 characters), and an + * Creates a StructuredDataMessage using an SD-ID (max 32 characters), message, + * MSGID (max 32 characters), and an * initial map of structured data to include. *

- * The {@code id} parameter represents the syslog {@code SD-ID} and is expected to conform to - * RFC 5424 Section 6.3.2. - * It is recommended to use {@link StructuredDataId} instead of a raw {@link String} where possible. + * The {@code sdId} parameter represents the syslog {@code SD-ID} and is + * expected + * to conform to + * RFC + * 5424 Section 6.3.2. + * It is recommended to use {@link StructuredDataId} instead of a raw + * {@link String} where possible, + * as it allows specifying a set of allowed keys for structured data elements. *

*

- * The {@code type} parameter represents the syslog {@code MSGID} and is expected to conform to - * RFC 5424 Section 6.2.7. + * The {@code msgId} parameter represents the syslog {@code MSGID} and is + * expected to conform to + * RFC + * 5424 Section 6.2.7. *

*

- * Both {@code id} and {@code type} are considered trusted inputs (typically compile-time constants). - * If these values are derived from external or untrusted sources, it is the caller's responsibility - * to validate and sanitize them to ensure RFC-compliant output, especially when used with + * Both {@code sdId} and {@code msgId} are considered trusted inputs (typically + * compile-time constants). + * If these values are derived from external or untrusted sources, it is the + * caller's responsibility + * to validate and sanitize them to ensure RFC-compliant output, especially when + * used with * {@code Rfc5424Layout}. *

- * @param id The String id. - * @param msg The message. - * @param type The message type. - * @param data The StructuredData map. + * + * @param sdId The String SD-ID. + * @param msg The message. + * @param msgId The message identifier MSGID. + * @param data The StructuredData map. */ - public StructuredDataMessage(final String id, final String msg, final String type, final Map data) { - this(id, msg, type, data, MAX_LENGTH); + public StructuredDataMessage( + final String sdId, final String msg, final String msgId, final Map data) { + this(sdId, msg, msgId, data, MAX_LENGTH); } /** - * Creates a StructuredDataMessage using an (user specified max characters), message, and type (user specified - * maximum number of characters, and an initial map of structured data to include. + * Creates a StructuredDataMessage using an (user specified max characters), + * message, and MSGID (user specified + * maximum number of characters, and an initial map of structured data to + * include. *

- * The {@code id} parameter represents the syslog {@code SD-ID} and is expected to conform to - * RFC 5424 Section 6.3.2. - * It is recommended to use {@link StructuredDataId} instead of a raw {@link String} where possible. + * The {@code sdId} parameter represents the syslog {@code SD-ID} and is + * expected + * to conform to + * RFC + * 5424 Section 6.3.2. + * It is recommended to use {@link StructuredDataId} instead of a raw + * {@link String} where possible, + * as it allows specifying a set of allowed keys for structured data elements. *

*

- * The {@code type} parameter represents the syslog {@code MSGID} and is expected to conform to - * RFC 5424 Section 6.2.7. + * The {@code msgId} parameter represents the syslog {@code MSGID} and is + * expected to conform to + * RFC + * 5424 Section 6.2.7. *

*

- * Both {@code id} and {@code type} are considered trusted inputs (typically compile-time constants). - * If these values are derived from external or untrusted sources, it is the caller's responsibility - * to validate and sanitize them to ensure RFC-compliant output, especially when used with + * Both {@code sdId} and {@code msgId} are considered trusted inputs (typically + * compile-time constants). + * If these values are derived from external or untrusted sources, it is the + * caller's responsibility + * to validate and sanitize them to ensure RFC-compliant output, especially when + * used with * {@code Rfc5424Layout}. *

- * @param id The String id. - * @param msg The message. - * @param type The message type. - * @param data The StructuredData map. + * + * @param sdId The String SD-ID. + * @param msg The message. + * @param msgId The message identifier. + * @param data The StructuredData map. * @param maxLength The maximum length of keys; * @since 2.9.0 */ public StructuredDataMessage( - final String id, final String msg, final String type, final Map data, final int maxLength) { + final String sdId, + final String msg, + final String msgId, + final Map data, + final int maxLength) { super(data); - this.id = new StructuredDataId(id, null, null, maxLength); + + validateSdId(sdId); + validateMsgId(msgId); + + this.sdId = new StructuredDataId(sdId, null, null, maxLength); this.message = msg; - this.type = type; + this.msgId = msgId; this.maxLength = maxLength; } /** - * Creates a StructuredDataMessage using a StructuredDataId, message, and type (max 32 characters). + * Creates a StructuredDataMessage using a StructuredDataId, message, and MSGID + * (max 32 characters). *

- * The {@link StructuredDataId} parameter represents the syslog {@code SD-ID} and is expected to conform to - * RFC 5424 Section 6.3.2. + * The {@link StructuredDataId} parameter represents the syslog {@code SD-ID} + * and is expected to conform to + * RFC + * 5424 Section 6.3.2. *

*

- * The {@code type} parameter represents the syslog {@code MSGID} and is expected to conform to - * RFC 5424 Section 6.2.7. + * The {@code msgId} parameter represents the syslog {@code MSGID} and is + * expected to conform to + * RFC + * 5424 Section 6.2.7. *

*

- * Both {@code id} and {@code type} are considered trusted inputs (typically compile-time constants). - * If these values are derived from external or untrusted sources, it is the caller's responsibility - * to validate and sanitize them to ensure RFC-compliant output, especially when used with + * Both {@code sdId} and {@code msgId} are considered trusted inputs (typically + * compile-time constants). + * If these values are derived from external or untrusted sources, it is the + * caller's responsibility + * to validate and sanitize them to ensure RFC-compliant output, especially when + * used with * {@code Rfc5424Layout}. *

- * @param id The StructuredDataId. - * @param msg The message. - * @param type The message type. + * + * @param sdId The StructuredDataId. + * @param msg The message. + * @param msgId The message identifier MSGID. */ - public StructuredDataMessage(final StructuredDataId id, final String msg, final String type) { - this(id, msg, type, MAX_LENGTH); + public StructuredDataMessage(final StructuredDataId sdId, final String msg, final String msgId) { + this(sdId, msg, msgId, MAX_LENGTH); } /** - * Creates a StructuredDataMessage using a StructuredDataId, message, and type (max 32 characters). + * Creates a StructuredDataMessage using a StructuredDataId, message, and MSGID + * (max 32 characters). *

- * The {@link StructuredDataId} parameter represents the syslog {@code SD-ID} and is expected to conform to - * RFC 5424 Section 6.3.2. + * The {@link StructuredDataId} parameter represents the syslog {@code SD-ID} + * and is expected to conform to + * RFC + * 5424 Section 6.3.2. *

*

- * The {@code type} parameter represents the syslog {@code MSGID} and is expected to conform to - * RFC 5424 Section 6.2.7. + * The {@code msgId} parameter represents the syslog {@code MSGID} and is + * expected to conform to + * RFC + * 5424 Section 6.2.7. *

*

- * Both {@code id} and {@code type} are considered trusted inputs (typically compile-time constants). - * If these values are derived from external or untrusted sources, it is the caller's responsibility - * to validate and sanitize them to ensure RFC-compliant output, especially when used with + * Both {@code sdId} and {@code msgId} are considered trusted inputs (typically + * compile-time constants). + * If these values are derived from external or untrusted sources, it is the + * caller's responsibility + * to validate and sanitize them to ensure RFC-compliant output, especially when + * used with * {@code Rfc5424Layout}. *

- * @param id The StructuredDataId. - * @param msg The message. - * @param type The message type. + * + * @param sdId The StructuredDataId. + * @param msg The message. + * @param msgId The message identifier MSGID. * @param maxLength The maximum length of keys; * @since 2.9.0 */ - public StructuredDataMessage(final StructuredDataId id, final String msg, final String type, final int maxLength) { - this.id = id; + public StructuredDataMessage( + final StructuredDataId sdId, final String msg, final String msgId, final int maxLength) { + + if (sdId == null) { + throw new IllegalArgumentException("SD-ID cannot be null"); + } + validateMsgId(msgId); + + this.sdId = sdId; this.message = msg; - this.type = type; + this.msgId = msgId; this.maxLength = maxLength; } /** - * Creates a StructuredDataMessage using a StructuredDataId, message, type (max 32 characters), and an initial map + * Creates a StructuredDataMessage using a StructuredDataId, message, MSGID (max + * 32 characters), and an initial map * of structured data to include. *

- * The {@link StructuredDataId} parameter represents the syslog {@code SD-ID} and is expected to conform to - * RFC 5424 Section 6.3.2. + * The {@link StructuredDataId} parameter represents the syslog {@code SD-ID} + * and is expected to conform to + * RFC + * 5424 Section 6.3.2. *

*

- * The {@code type} parameter represents the syslog {@code MSGID} and is expected to conform to - * RFC 5424 Section 6.2.7. + * The {@code msgId} parameter represents the syslog {@code MSGID} and is + * expected to conform to + * RFC + * 5424 Section 6.2.7. *

*

- * Both {@code id} and {@code type} are considered trusted inputs (typically compile-time constants). - * If these values are derived from external or untrusted sources, it is the caller's responsibility - * to validate and sanitize them to ensure RFC-compliant output, especially when used with + * Both {@code sdId} and {@code msgId} are considered trusted inputs (typically + * compile-time constants). + * If these values are derived from external or untrusted sources, it is the + * caller's responsibility + * to validate and sanitize them to ensure RFC-compliant output, especially when + * used with * {@code Rfc5424Layout}. *

- * @param id The StructuredDataId. - * @param msg The message. - * @param type The message type. - * @param data The StructuredData map. + * + * @param sdId The StructuredDataId. + * @param msg The message. + * @param msgId The message identifier MSGID. + * @param data The StructuredData map. */ public StructuredDataMessage( - final StructuredDataId id, final String msg, final String type, final Map data) { - this(id, msg, type, data, MAX_LENGTH); + final StructuredDataId sdId, final String msg, final String msgId, final Map data) { + this(sdId, msg, msgId, data, MAX_LENGTH); } /** - * Creates a StructuredDataMessage using a StructuredDataId, message, type (max 32 characters), and an initial map + * Creates a StructuredDataMessage using a StructuredDataId, message, MSGID (max + * 32 characters), and an initial map * of structured data to include. *

- * The {@link StructuredDataId} parameter represents the syslog {@code SD-ID} and is expected to conform to - * RFC 5424 Section 6.3.2. + * The {@link StructuredDataId} parameter represents the syslog {@code SD-ID} + * and is expected to conform to + * RFC + * 5424 Section 6.3.2. *

*

- * The {@code type} parameter represents the syslog {@code MSGID} and is expected to conform to - * RFC 5424 Section 6.2.7. + * The {@code msgId} parameter represents the syslog {@code MSGID} and is + * expected to conform to + * RFC + * 5424 Section 6.2.7. *

*

- * Both {@code id} and {@code type} are considered trusted inputs (typically compile-time constants). - * If these values are derived from external or untrusted sources, it is the caller's responsibility - * to validate and sanitize them to ensure RFC-compliant output, especially when used with + * Both {@code sdId} and {@code msgId} are considered trusted inputs (typically + * compile-time constants). + * If these values are derived from external or untrusted sources, it is the + * caller's responsibility + * to validate and sanitize them to ensure RFC-compliant output, especially when + * used with * {@code Rfc5424Layout}. *

- * @param id The StructuredDataId. - * @param msg The message. - * @param type The message type. - * @param data The StructuredData map. + * + * @param sdId The StructuredDataId. + * @param msg The message. + * @param msgId The message identifier MSGID. + * @param data The StructuredData map. * @param maxLength The maximum length of keys; * @since 2.9.0 */ public StructuredDataMessage( - final StructuredDataId id, + final StructuredDataId sdId, final String msg, - final String type, + final String msgId, final Map data, final int maxLength) { super(data); - this.id = id; + + if (sdId == null) { + throw new IllegalArgumentException("SD-ID cannot be null"); + } + + validateMsgId(msgId); + + this.sdId = sdId; this.message = msg; - this.type = type; + this.msgId = msgId; this.maxLength = maxLength; } /** * Constructor based on a StructuredDataMessage. + * * @param msg The StructuredDataMessage. * @param map The StructuredData map. */ private StructuredDataMessage(final StructuredDataMessage msg, final Map map) { super(map); - this.id = msg.id; + this.sdId = msg.sdId; this.message = msg.message; - this.type = msg.type; + this.msgId = msg.msgId; this.maxLength = MAX_LENGTH; } @@ -312,6 +430,7 @@ protected StructuredDataMessage() { /** * Returns the supported formats. + * * @return An array of the supported format names. */ @Override @@ -325,42 +444,48 @@ public String[] getFormats() { } /** - * Returns this message id. + * Returns the Structured Data ID (SD-ID) of this message. + * * @return the StructuredDataId. */ public StructuredDataId getId() { - return id; + return sdId; } /** - * Sets the id from a String. This ID can be at most 32 characters long. - * @param id The String id. + * Sets the sdId from a String. This sdId can be at most 32 characters long. + * + * @param sdId The String sdId. */ - protected void setId(final String id) { - this.id = new StructuredDataId(id, null, null); + protected void setId(final String sdId) { + validateSdId(sdId); + this.sdId = new StructuredDataId(sdId, null, null); } /** - * Sets the id. - * @param id The StructuredDataId. + * Sets the sdId. + * + * @param sdId The StructuredDataId. */ - protected void setId(final StructuredDataId id) { - this.id = id; + protected void setId(final StructuredDataId sdId) { + if (sdId == null) { + throw new IllegalArgumentException("SD-ID cannot be null"); + } + this.sdId = sdId; } /** - * Returns this message type. - * @return the type. + * Returns the message identifier (MSGID). + * + * @return the msgId. */ public String getType() { - return type; + return msgId; } - protected void setType(final String type) { - if (type.length() > MAX_LENGTH) { - throw new IllegalArgumentException("structured data type exceeds maximum length of 32 characters: " + type); - } - this.type = type; + protected void setType(final String msgId) { + validateMsgId(msgId); + this.msgId = msgId; } @Override @@ -375,6 +500,7 @@ public void formatTo(final String[] formats, final StringBuilder buffer) { /** * Returns the message. + * * @return the message. */ @Override @@ -414,9 +540,11 @@ public String asString(final String format) { /** * Formats the structured data as described in RFC 5424. * - * @param format "full" will include the type and message. null will return only the STRUCTURED-DATA as + * @param format "full" will include the type and message. null will + * return only the STRUCTURED-DATA as * described in RFC 5424 - * @param structuredDataId The SD-ID as described in RFC 5424. If null the value in the StructuredData + * @param structuredDataId The SD-ID as described in RFC 5424. If null the value + * in the StructuredData * will be used. * @return The formatted String. */ @@ -429,11 +557,13 @@ public final String asString(final Format format, final StructuredDataId structu /** * Formats the structured data as described in RFC 5424. * - * @param format "full" will include the type and message. null will return only the STRUCTURED-DATA as + * @param format "full" will include the type and message. null will + * return only the STRUCTURED-DATA as * described in RFC 5424 - * @param structuredDataId The SD-ID as described in RFC 5424. If null the value in the StructuredData + * @param structuredDataId The SD-ID as described in RFC 5424. If null the value + * in the StructuredData * will be used. - * @param sb The StringBuilder to append the formatted message to. + * @param sb The StringBuilder to append the formatted message to. * @since 2.8 */ public final void asString(final Format format, final StructuredDataId structuredDataId, final StringBuilder sb) { @@ -473,7 +603,7 @@ public final void asString(final Format format, final StructuredDataId structure private void asXml(final StructuredDataId structuredDataId, final StringBuilder sb) { sb.append("\n"); - sb.append("").append(type).append("\n"); + sb.append("").append(msgId).append("\n"); sb.append("").append(structuredDataId).append("\n"); super.asXml(sb); sb.append("\n\n"); @@ -481,6 +611,7 @@ private void asXml(final StructuredDataId structuredDataId, final StringBuilder /** * Formats the message and return it. + * * @return the formatted message. */ @Override @@ -490,10 +621,14 @@ public String getFormattedMessage() { /** * Formats the message according to the specified format. - * @param formats An array of Strings that provide extra information about how to format the message. - * StructuredDataMessage accepts only a format of "FULL" which will cause the event type to be - * prepended and the event message to be appended. Specifying any other value will cause only the - * StructuredData to be included. The default is "FULL". + * + * @param formats An array of Strings that provide extra information about how + * to format the message. + * StructuredDataMessage accepts only a format of "FULL" which + * will cause the event type to be + * prepended and the event message to be appended. Specifying any + * other value will cause only the + * StructuredData to be included. The default is "FULL". * * @return the formatted message. */ @@ -541,10 +676,10 @@ public boolean equals(final Object o) { if (!super.equals(o)) { return false; } - if (type != null ? !type.equals(that.type) : that.type != null) { + if (msgId != null ? !msgId.equals(that.msgId) : that.msgId != null) { return false; } - if (id != null ? !id.equals(that.id) : that.id != null) { + if (sdId != null ? !sdId.equals(that.sdId) : that.sdId != null) { return false; } if (message != null ? !message.equals(that.message) : that.message != null) { @@ -557,8 +692,8 @@ public boolean equals(final Object o) { @Override public int hashCode() { int result = super.hashCode(); - result = HASHVAL * result + (type != null ? type.hashCode() : 0); - result = HASHVAL * result + (id != null ? id.hashCode() : 0); + result = HASHVAL * result + (msgId != null ? msgId.hashCode() : 0); + result = HASHVAL * result + (sdId != null ? sdId.hashCode() : 0); result = HASHVAL * result + (message != null ? message.hashCode() : 0); return result; } @@ -653,4 +788,26 @@ protected void validateKey(final String key) { } } } + + private void validateSdId(final String sdId) { + if (sdId == null) { + throw new IllegalArgumentException("SD-ID cannot be null"); + } + validateKey(sdId); + } + + private void validateMsgId(final String msgId) { + if (msgId == null) { + throw new IllegalArgumentException("MSGID cannot be null"); + } + if (msgId.length() > MAX_LENGTH) { + throw new IllegalArgumentException("MSGID exceeds maximum length of 32 characters: " + msgId); + } + for (int i = 0; i < msgId.length(); i++) { + final char c = msgId.charAt(i); + if (c < '!' || c > '~') { + throw new IllegalArgumentException("MSGID must contain printable US ASCII characters: " + msgId); + } + } + } }