@@ -14,6 +14,8 @@ package xml
1414 *
1515 * @author Burak Emir
1616 * @param commentText the text contained in this node, may not contain "--"
17+ * and the final character may not be `-` to prevent a closing span of `-->`
18+ * which is invalid. [[https://www.w3.org/TR/xml11//#IDA5CES ]]
1719 */
1820case class Comment (commentText : String ) extends SpecialNode {
1921
@@ -22,12 +24,81 @@ case class Comment(commentText: String) extends SpecialNode {
2224 final override def doCollectNamespaces = false
2325 final override def doTransform = false
2426
25- if (commentText contains " --" )
26- throw new IllegalArgumentException (" text contains \" --\" " )
27+ // Validate the commentText. We call the `Comment.validate` method because
28+ // that shares code with the more safe constructs, e.g. `Comment.validated`
29+ // and `Comment.validatedOpt`.
30+ Comment .validate(commentText).fold(
31+ ()
32+ )(e =>
33+ throw e
34+ )
2735
2836 /**
2937 * Appends "<!-- text -->" to this string buffer.
3038 */
3139 override def buildString (sb : StringBuilder ) =
3240 sb append " <!--" append commentText append " -->"
3341}
42+
43+ // We have to extends `scala.runtime.AbstractFunction1[String, Comment]` and
44+ // override `apply` if we don't want to break binary compatibility.
45+ object Comment extends scala.runtime.AbstractFunction1 [String , Comment ]{
46+
47+ override final def apply (commentText : String ): Comment =
48+ new Comment (commentText)
49+
50+ /** Validates if a given `String` can be a valid XML comment.
51+ *
52+ * There are two related cases where a `String` is invalid. The first is
53+ * when the `String` `"--"` occurs in the body of the text. The second is
54+ * when the final character in the comment is `'-'`. In the second case
55+ * this is invalid because it would yield a XML encoding of `-->` for the
56+ * final three characters of the rendered comment which invalidates the
57+ * first rule of not having `"--"` in the comment.
58+ *
59+ * @see [[https://www.w3.org/TR/xml11//#IDA5CES ]]
60+ */
61+ private def validate (commentText : String ): Option [Throwable ] =
62+ if (commentText.isEmpty) {
63+ None
64+ } else if (commentText.contains(" --" )) {
65+ Some (new IllegalArgumentException (" text contains \" --\" " ))
66+ } else if (commentText.charAt(commentText.length - 1 ) == '-' ) {
67+ Some (new IllegalArgumentException (" The final character of a XML comment may not be '-'. See https://www.w3.org/TR/xml11//#IDA5CES" ))
68+ } else {
69+ None
70+ }
71+
72+ /** Validates if a given `String` can be a valid XML comment, yielding a
73+ * `Left` `Throwable` if it is invalid.
74+ *
75+ * There are two related cases where a `String` is invalid. The first is
76+ * when the `String` `"--"` occurs in the body of the text. The second is
77+ * when the final character in the comment is `'-'`. In the second case
78+ * this is invalid because it would yield a XML encoding of `-->` for the
79+ * final three characters of the rendered comment which invalidates the
80+ * first rule of not having `"--"` in the comment.
81+ *
82+ * @see [[https://www.w3.org/TR/xml11//#IDA5CES ]]
83+ */
84+ def validated (commentText : String ): Either [Throwable , Comment ] =
85+ validate(commentText).fold(
86+ Right (Comment (commentText)): Either [Throwable , Comment ]
87+ )(t => Left (t))
88+
89+
90+ /** Validates if a given `String` can be a valid XML comment, `None` if it is
91+ * invalid.
92+ *
93+ * There are two related cases where a `String` is invalid. The first is
94+ * when the `String` `"--"` occurs in the body of the text. The second is
95+ * when the final character in the comment is `'-'`. In the second case
96+ * this is invalid because it would yield a XML encoding of `-->` for the
97+ * final three characters of the rendered comment which invalidates the
98+ * first rule of not having `"--"` in the comment.
99+ *
100+ * @see [[https://www.w3.org/TR/xml11//#IDA5CES ]]
101+ */
102+ def validatedOpt (commentText : String ): Option [Comment ] =
103+ validated(commentText).toOption
104+ }
0 commit comments