Author: gvanmatre
Date: Fri Sep 2 21:36:40 2005
New Revision: 267417
URL: http://svn.apache.org/viewcvs?rev=267417&view=rev
Log:
Bug#: 35839 [shale] Clay processes components inside HTML comments
Modified:
struts/shale/trunk/clay-plugin/src/java/org/apache/shale/clay/parser/Parser.java
struts/shale/trunk/clay-plugin/src/test/org/apache/shale/clay/parser/ParserTestCase.java
Modified:
struts/shale/trunk/clay-plugin/src/java/org/apache/shale/clay/parser/Parser.java
URL:
http://svn.apache.org/viewcvs/struts/shale/trunk/clay-plugin/src/java/org/apache/shale/clay/parser/Parser.java?rev=267417&r1=267416&r2=267417&view=diff
==============================================================================
---
struts/shale/trunk/clay-plugin/src/java/org/apache/shale/clay/parser/Parser.java
(original)
+++
struts/shale/trunk/clay-plugin/src/java/org/apache/shale/clay/parser/Parser.java
Fri Sep 2 21:36:40 2005
@@ -436,60 +436,115 @@
}
/**
+ * <p>Declare an array of [EMAIL PROTECTED] Rule}s that validate an ending
[EMAIL PROTECTED] Token}.</p>
+ */
+ private static Rule[] END_TAG_RULES = {new Rule('<', true, 0, true),
+ new Rule('/', true, 1, true),
+ new Rule('>', false, -1, true)};
+
+ /**
+ * <p>Declare an array of [EMAIL PROTECTED] Rule}s that validate self
terminating [EMAIL PROTECTED] Token}.</p>
+ */
+ private static Rule[] SELF_TERM_TAG_RULES = {new Rule('<', true, 0, true),
+ new Rule('/', false, -2, true),
+ new Rule('>', false, -1, true)};
+ /**
+ * <p>Declare an array of [EMAIL PROTECTED] Rule}s that validate self
contained comment [EMAIL PROTECTED] Token}.</p>
+ */
+ private static Rule[] SELF_CONTAINED_COMMENT_RULES = {new Rule('<', true,
0, true),
+ new Rule('!', true, 1, true),
+ new Rule('-', true, 2, true),
+ new Rule('-', true, 3, true),
+ new Rule('>', false, -1, true),
+ new Rule('-', false, -2, true),
+ new Rule('-', false, -3, true),
+ new Rule(' ', false, -4, true)};
+
+ /**
+ * <p>Declare an array of [EMAIL PROTECTED] Rule}s that validate a begin
comment [EMAIL PROTECTED] Token}.</p>
+ */
+ public static Rule[] BEGIN_COMMENT_TAG_RULES = {new Rule('<', true, 0,
true),
+ new Rule('!', true, 1, true),
+ new Rule('-', true, 2, true),
+ new Rule('-', true, 3, true)};
+
+ /**
+ * <p>Declare an array of [EMAIL PROTECTED] Rule}s that validate an end
comment [EMAIL PROTECTED] Token}.</p>
+ */
+ public static Rule[] END_COMMENT_TAG_RULES = {new Rule('>', false, -1,
true),
+ new Rule('-', false, -2, true),
+ new Rule('-', false, -3, true),
+ new Rule(' ', false, -4, true)};
+
+ /**
+ * <p>Declare an array of [EMAIL PROTECTED] Rule}s that validate document
type [EMAIL PROTECTED] Token}.</p>
+ */
+ public static Rule[] DOCTYPE_TAG_RULES = {new Rule('<', true, 0, true),
+ new Rule('!', true, 1, true),
+ new Rule('>', false, -1, true)};
+
+ /**
+ * <p>Declare an array of [EMAIL PROTECTED] Rule}s that validate a
begining [EMAIL PROTECTED] Token}.</p>
+ */
+ public static Rule[] BEGIN_TAG_RULES = {new Rule('<', true, 0, true),
+ new Rule('-', true, 1, false),
+ new Rule('/', true, 1, false),
+ new Rule('?', true, 1, false),
+ new Rule('%', true, 1, false),
+ new Rule('>', false, -1, true)};
+
+ /**
+ * <p>Declare an array of [EMAIL PROTECTED] Shape}s further defined by
[EMAIL PROTECTED] Rule}s that
+ * are used to determine the type of [EMAIL PROTECTED] Node} the [EMAIL
PROTECTED] Token} defines.</p>
+ */
+ private static Shape[] NODE_SHAPES = {
+ new Shape(false, true, false, END_TAG_RULES),
+ new Shape(true, true, false, SELF_TERM_TAG_RULES),
+ new Shape(true, true, true, SELF_CONTAINED_COMMENT_RULES),
+ new Shape(true, false, true, BEGIN_COMMENT_TAG_RULES),
+ new Shape(false, true, true, END_COMMENT_TAG_RULES),
+ new Shape(true, true, true, DOCTYPE_TAG_RULES),
+ new Shape(true, false, false, BEGIN_TAG_RULES)};
+
+
+ /**
* <p>Determine if the [EMAIL PROTECTED] Node} is a starting, ending, or
body text
- * tag.</p>
+ * tag. The array of [EMAIL PROTECTED] Shape}s are used to determine the
type of
+ * [EMAIL PROTECTED] Node} the [EMAIL PROTECTED] Token} representes.</p>
*/
protected void discoverNodeShape(Node node) {
Token token = node.getToken();
- if (token.getDocument().charAt(token.getBeginOffset()) == '<'
- && token.getDocument().charAt(token.getBeginOffset() + 1) == '/'
- && token.getDocument().charAt(token.getEndOffset() - 1) ==
'>') {
- // ending tag found
- node.setEnd(true);
- node.setStart(false);
- } else if (token.getDocument().charAt(token.getBeginOffset()) == '<'
- && token.getDocument().charAt(token.getEndOffset() - 2) == '/'
- && token.getDocument().charAt(token.getEndOffset() - 1) ==
'>') {
- // self ending tag found
- node.setEnd(true);
- node.setStart(true);
- } else if (token.getDocument().charAt(token.getBeginOffset()) == '<'
- && token.getDocument().charAt(token.getBeginOffset() + 1) == '!'
- && token.getDocument().charAt(token.getEndOffset() - 2) == '-'
- && token.getDocument().charAt(token.getEndOffset() - 1) ==
'>') {
- // self contained comment tag found
- node.setEnd(true);
- node.setStart(true);
- node.setComment(true);
- } else if (token.getDocument().charAt(token.getBeginOffset()) == '<'
- && token.getDocument().charAt(token.getBeginOffset() + 1) == '!'
- && token.getDocument().charAt(token.getBeginOffset() + 2) ==
'-') {
- // begin comment tag found
- node.setEnd(false);
- node.setStart(true);
- node.setComment(true);
- } else if (token.getDocument().charAt(token.getEndOffset() - 2) == '-'
- && token.getDocument().charAt(token.getEndOffset() - 1) == '>') {
- // ending comment tag found
- node.setEnd(true);
- node.setStart(false);
- node.setComment(true);
- } else if (token.getDocument().charAt(token.getBeginOffset()) == '<'
- && token.getDocument().charAt(token.getBeginOffset() + 1) == '!'
- && token.getDocument().charAt(token.getEndOffset() - 1) ==
'>') {
- // DOCTYPE is treated like a self contained comment
- node.setEnd(true);
- node.setStart(true);
- node.setComment(true);
- } else if (token.getDocument().charAt(token.getBeginOffset()) == '<'
- && (token.getDocument().charAt(token.getBeginOffset() + 1) != '/'
- && token.getDocument().charAt(token.getBeginOffset() + 1) !=
'?'
- && token.getDocument().charAt(token.getBeginOffset() + 1)
!= '%')
- && token.getDocument().charAt(token.getEndOffset() - 1) ==
'>') {
- // beginning tag found
- node.setEnd(false);
- node.setStart(true);
+ nextShape: for (int i = 0; i < NODE_SHAPES.length; i++) {
+
+ Shape shape = NODE_SHAPES[i];
+
+ Rule[] rules = shape.getRules();
+ for (int j = 0; j < rules.length; j++ ) {
+
+ // use the begin or end token offset
+ int n = (rules[j].isBegin ? token.getBeginOffset() :
token.getEndOffset()) + rules[j].getOffset();
+
+ // if out of document range, look for the next shape
+ if (n > token.getDocument().length() || n < 0)
+ continue nextShape;
+
+ // check the operator
+ boolean match = false;
+ if (rules[j].isEqual)
+ match = (token.getDocument().charAt(n) ==
rules[j].getMnemonic());
+ else
+ match = (token.getDocument().charAt(n) !=
rules[j].getMnemonic());
+
+ if (!match)
+ continue nextShape;
+ }
+
+ node.setStart(shape.isStart());
+ node.setEnd(shape.isEnd());
+ node.setComment(shape.isComment());
+
+ break nextShape;
}
}
@@ -581,4 +636,145 @@
}
+ /**
+ * <p>Defines a parsing [EMAIL PROTECTED] Rule} used to determine
+ * the [EMAIL PROTECTED] Shape} of a [EMAIL PROTECTED] Node}.</p>
+ */
+ static class Rule {
+ /**
+ * <p>The target char to check for in the [EMAIL PROTECTED] Token}
document.</p>
+ */
+ private char mnemonic = ' ';
+
+ /**
+ * <p>A boolen flag that indicates if the <code>offset</code> is from
+ * the begining of the [EMAIL PROTECTED] Token} offset or the ending
offset.</p>
+ */
+ private boolean isBegin = false;
+
+ /**
+ * <p>The offset from the start or end of the [EMAIL PROTECTED] Token}
that the
+ * <code>mnemonic</code> should be found.</p>
+ */
+ private int offset = 0;
+ /**
+ * <p>A boolean value that determines the relational operator used
+ * to compare the <code>mnemonic</code> to the [EMAIL PROTECTED]
Token} begin
+ * or ending offset plus the [EMAIL PROTECTED] Rule} offset. If the
value
+ * is <code>true</code> the equals operator is used; otherwise,
+ * the not equals operator is used in the comparison.</p>
+ */
+ private boolean isEqual = false;
+
+ /**
+ * <p>Overloaded constructor for the immutable object.</p>
+ * @param mnemonic character looked for in the token
+ * @param isBegin boolean that determines if the begining or ending of
the Token is used
+ * @param offset the offset from the begin or ending Token
+ * @param isEqual boolean that determines if the = or != operator is
used to check the mnemonic
+ */
+ public Rule(char mnemonic, boolean isBegin, int offset, boolean
isEqual) {
+ this.mnemonic = mnemonic;
+ this.isBegin = isBegin;
+ this.offset = offset;
+ this.isEqual = isEqual;
+ }
+ /**
+ * <p>Returns the character looked for in the [EMAIL PROTECTED]
Token}.</p>
+ */
+ public char getMnemonic() {
+ return mnemonic;
+ }
+ /**
+ * <p>Returns <code>true</code> if the <code>mnemonic</code> is at the
+ * begin or end of the token plus the <code>offset</code>.</p>
+ */
+ public boolean isBegin() {
+ return isBegin;
+ }
+ /**
+ * <p>Returns a positive or negative offset from the begin or ending
+ * [EMAIL PROTECTED] Token} offset withing the document.</p>
+ */
+ public int getOffset() {
+ return offset;
+ }
+
+ /**
+ * <p>Returns <code>true</code> if the equal relational operator is
+ * used for the <code>mnemonic</code> comparison; otherwise the not
+ * equal operator is used.</p>
+ */
+ public boolean IsEqual() {
+ return isEqual;
+ }
+ }
+
+ /**
+ * <p>This class defines the shape of the [EMAIL PROTECTED] Node} by
characterizing
+ * if the [EMAIL PROTECTED] Token} is a begin, end or comment tag.</p>
+ */
+ static class Shape {
+
+ /**
+ * <p>If <code>true</code> it indicates a starting node.</p>
+ */
+ private boolean isStart = false;
+
+ /**
+ * <p>If <code>true</code> it indicates an ending node.</p>
+ */
+ private boolean isEnd = false;
+
+ /**
+ * <p>If <code>true</code> it indicates a comment node.</p>
+ */
+ private boolean isComment = false;
+
+ /**
+ * <p>An array of [EMAIL PROTECTED] Rule}s used to determine if the
[EMAIL PROTECTED] Node}
+ * matches the [EMAIL PROTECTED] Shape}.</p>
+ */
+ private Rule[] rules = null;
+
+ /**
+ * <p>Overloaded constructor used to instantiate the immutable
object.</p>
+ */
+ public Shape(boolean isStart, boolean isEnd, boolean isComment, Rule[]
rules) {
+ this.isStart = isStart;
+ this.isEnd = isEnd;
+ this.isComment = isComment;
+ this.rules = rules;
+ }
+
+ /**
+ * <p>Returns <code>true</code> if the [EMAIL PROTECTED] Token} is a
starting tag.</p>
+ */
+ public boolean isStart() {
+ return isStart;
+ }
+ /**
+ * <p>Returns <code>true</code> if the [EMAIL PROTECTED] Token} is an
ending tag.</p>
+ */
+ public boolean isEnd() {
+ return isEnd;
+ }
+ /**
+ * <p>Returns <code>true</code> if the [EMAIL PROTECTED] Token} is a
comment tag.</p>
+ */
+ public boolean isComment() {
+ return isComment;
+ }
+ /**
+ * <p>Returns the [EMAIL PROTECTED] Rule}s that define the
<code>isStart</code>,
+ * <code>isEnd</code> and <code>isComment</code> characteristics.</p>
+ */
+ public Rule[] getRules() {
+ return rules;
+ }
+ }
+
+
+
+
}
Modified:
struts/shale/trunk/clay-plugin/src/test/org/apache/shale/clay/parser/ParserTestCase.java
URL:
http://svn.apache.org/viewcvs/struts/shale/trunk/clay-plugin/src/test/org/apache/shale/clay/parser/ParserTestCase.java?rev=267417&r1=267416&r2=267417&view=diff
==============================================================================
---
struts/shale/trunk/clay-plugin/src/test/org/apache/shale/clay/parser/ParserTestCase.java
(original)
+++
struts/shale/trunk/clay-plugin/src/test/org/apache/shale/clay/parser/ParserTestCase.java
Fri Sep 2 21:36:40 2005
@@ -55,12 +55,13 @@
doc1.append("<p><!-- self contained comment -->").append(
"<!--<input type=text size=10 maxsize=10 id=username>").append(
- "<input type=text size=10 maxsize=10 id=password>-->").append(
- "</p>").append("<!--This is a test. Just a test-->").append(
- "<!--<p>Testing <b>123</b></p>-->");
+ "<input type=text size=10 maxsize=10 id=password> -->").append(
+ "</p>").append("<!--This is a test. Just a test -->").append(
+ "<!--<p>Testing <b>123</b></p> -->" +
+ "<!---> -->");
List nodes1 = p.parse(doc1);
- assertTrue("Has 3 root nodes", nodes1.size() == 3);
+ assertTrue("Has 4 root nodes", nodes1.size() == 4);
Node node = (Node) nodes1.get(0);
assertTrue("first paragraph has 2 node", node.getChildren().size() ==
2);
@@ -73,6 +74,11 @@
assertTrue("third comment has 7 child nodes", node.getChildren()
.size() == 7);
+ node = (Node) nodes1.get(3);
+ assertTrue("forth comment has 1 child node", node.getChildren()
+ .size() == 1);
+
+
// truncate the buffer
doc1.setLength(0);
doc1
---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]