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]