Clover coverage report - Code Coverage for tapestry release 4.0-beta-8
Coverage timestamp: Sat Sep 24 2005 11:50:34 EDT
file stats: LOC: 191   Methods: 4
NCLOC: 107   Classes: 1
 
 Source file Conditionals Statements Methods TOTAL
AbstractTokenRule.java 95.8% 100% 100% 98.9%
coverage coverage
 1    // Copyright 2004, 2005 The Apache Software Foundation
 2    //
 3    // Licensed under the Apache License, Version 2.0 (the "License");
 4    // you may not use this file except in compliance with the License.
 5    // You may obtain a copy of the License at
 6    //
 7    // http://www.apache.org/licenses/LICENSE-2.0
 8    //
 9    // Unless required by applicable law or agreed to in writing, software
 10    // distributed under the License is distributed on an "AS IS" BASIS,
 11    // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 12    // See the License for the specific language governing permissions and
 13    // limitations under the License.
 14   
 15    package org.apache.tapestry.script;
 16   
 17    import org.apache.hivemind.Location;
 18    import org.apache.tapestry.util.xml.BaseRule;
 19    import org.apache.tapestry.util.xml.RuleDirectedParser;
 20   
 21    /**
 22    * Base class for the rules that build {@link org.apache.tapestry.script.IScriptToken}s.
 23    * Used with classes that can contain a mix of text and elements (those that
 24    * accept "full content").
 25    *
 26    *
 27    * @author Howard Lewis Ship
 28    * @since 3.0
 29    **/
 30   
 31    abstract class AbstractTokenRule extends BaseRule
 32    {
 33   
 34    /**
 35    * Adds a token to its parent, the top object on the stack.
 36    */
 37  19 protected void addToParent(RuleDirectedParser parser, IScriptToken token)
 38    {
 39  19 IScriptToken parent = (IScriptToken) parser.peek();
 40   
 41  19 parent.addToken(token);
 42    }
 43   
 44    /**
 45    * Peeks at the top object on the stack (which must be a {@link IScriptToken}),
 46    * and converts the text into a series of {@link org.apache.tapestry.script.StaticToken} and
 47    * {@link org.apache.tapestry.script.InsertToken}s.
 48    */
 49   
 50  22 public void content(RuleDirectedParser parser, String content)
 51    {
 52  22 IScriptToken token = (IScriptToken) parser.peek();
 53   
 54  22 addTextTokens(token, content, parser.getLocation());
 55    }
 56   
 57    private static final int STATE_START = 0;
 58    private static final int STATE_DOLLAR = 1;
 59    private static final int STATE_COLLECT_EXPRESSION = 2;
 60   
 61    /**
 62    * Parses the provided text and converts it into a series of
 63    */
 64  22 protected void addTextTokens(IScriptToken token, String text, Location location)
 65    {
 66  22 char[] buffer = text.toCharArray();
 67  22 int state = STATE_START;
 68  22 int blockStart = 0;
 69  22 int blockLength = 0;
 70  22 int expressionStart = -1;
 71  22 int expressionLength = 0;
 72  22 int i = 0;
 73  22 int braceDepth = 0;
 74   
 75  22 while (i < buffer.length)
 76    {
 77  290 char ch = buffer[i];
 78   
 79  290 switch (state)
 80    {
 81  215 case STATE_START :
 82   
 83  215 if (ch == '$')
 84    {
 85  8 state = STATE_DOLLAR;
 86  8 i++;
 87  8 continue;
 88    }
 89   
 90  207 blockLength++;
 91  207 i++;
 92  207 continue;
 93   
 94  7 case STATE_DOLLAR :
 95   
 96  7 if (ch == '{')
 97    {
 98  6 state = STATE_COLLECT_EXPRESSION;
 99  6 i++;
 100   
 101  6 expressionStart = i;
 102  6 expressionLength = 0;
 103  6 braceDepth = 1;
 104   
 105  6 continue;
 106    }
 107   
 108    // The '$' was just what it was, not the start of a ${} expression
 109    // block, so include it as part of the static text block.
 110   
 111  1 blockLength++;
 112   
 113  1 state = STATE_START;
 114  1 continue;
 115   
 116  68 case STATE_COLLECT_EXPRESSION :
 117   
 118  68 if (ch != '}')
 119    {
 120  62 if (ch == '{')
 121  1 braceDepth++;
 122   
 123  62 i++;
 124  62 expressionLength++;
 125  62 continue;
 126    }
 127   
 128  6 braceDepth--;
 129   
 130  6 if (braceDepth > 0)
 131    {
 132  1 i++;
 133  1 expressionLength++;
 134  1 continue;
 135    }
 136   
 137    // Hit the closing brace of an expression.
 138   
 139    // Degenerate case: the string "${}".
 140   
 141  5 if (expressionLength == 0)
 142  1 blockLength += 3;
 143   
 144  5 if (blockLength > 0)
 145  5 token.addToken(constructStatic(text, blockStart, blockLength, location));
 146   
 147  5 if (expressionLength > 0)
 148    {
 149  4 String expression =
 150    text.substring(expressionStart, expressionStart + expressionLength);
 151   
 152  4 token.addToken(new InsertToken(expression, location));
 153    }
 154   
 155  5 i++;
 156  5 blockStart = i;
 157  5 blockLength = 0;
 158   
 159    // And drop into state start
 160   
 161  5 state = STATE_START;
 162   
 163  5 continue;
 164    }
 165   
 166    }
 167   
 168    // OK, to handle the end. Couple of degenerate cases where
 169    // a ${...} was incomplete, so we adust the block length.
 170   
 171  22 if (state == STATE_DOLLAR)
 172  1 blockLength++;
 173   
 174  22 if (state == STATE_COLLECT_EXPRESSION)
 175  1 blockLength += expressionLength + 2;
 176   
 177  22 if (blockLength > 0)
 178  21 token.addToken(constructStatic(text, blockStart, blockLength, location));
 179    }
 180   
 181  26 private IScriptToken constructStatic(
 182    String text,
 183    int blockStart,
 184    int blockLength,
 185    Location location)
 186    {
 187  26 String literal = text.substring(blockStart, blockStart + blockLength);
 188   
 189  26 return new StaticToken(literal, location);
 190    }
 191    }