Clover coverage report - Code Coverage for tapestry release 4.0.1
Coverage timestamp: Fri Mar 31 2006 09:12:14 EST
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  38 protected void addToParent(RuleDirectedParser parser, IScriptToken token)
 38    {
 39  38 IScriptToken parent = (IScriptToken) parser.peek();
 40   
 41  38 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  44 public void content(RuleDirectedParser parser, String content)
 51    {
 52  44 IScriptToken token = (IScriptToken) parser.peek();
 53   
 54  44 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  44 protected void addTextTokens(IScriptToken token, String text, Location location)
 65    {
 66  44 char[] buffer = text.toCharArray();
 67  44 int state = STATE_START;
 68  44 int blockStart = 0;
 69  44 int blockLength = 0;
 70  44 int expressionStart = -1;
 71  44 int expressionLength = 0;
 72  44 int i = 0;
 73  44 int braceDepth = 0;
 74   
 75  44 while (i < buffer.length)
 76    {
 77  580 char ch = buffer[i];
 78   
 79  580 switch (state)
 80    {
 81  430 case STATE_START :
 82   
 83  430 if (ch == '$')
 84    {
 85  16 state = STATE_DOLLAR;
 86  16 i++;
 87  16 continue;
 88    }
 89   
 90  414 blockLength++;
 91  414 i++;
 92  414 continue;
 93   
 94  14 case STATE_DOLLAR :
 95   
 96  14 if (ch == '{')
 97    {
 98  12 state = STATE_COLLECT_EXPRESSION;
 99  12 i++;
 100   
 101  12 expressionStart = i;
 102  12 expressionLength = 0;
 103  12 braceDepth = 1;
 104   
 105  12 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  2 blockLength++;
 112   
 113  2 state = STATE_START;
 114  2 continue;
 115   
 116  136 case STATE_COLLECT_EXPRESSION :
 117   
 118  136 if (ch != '}')
 119    {
 120  124 if (ch == '{')
 121  2 braceDepth++;
 122   
 123  124 i++;
 124  124 expressionLength++;
 125  124 continue;
 126    }
 127   
 128  12 braceDepth--;
 129   
 130  12 if (braceDepth > 0)
 131    {
 132  2 i++;
 133  2 expressionLength++;
 134  2 continue;
 135    }
 136   
 137    // Hit the closing brace of an expression.
 138   
 139    // Degenerate case: the string "${}".
 140   
 141  10 if (expressionLength == 0)
 142  2 blockLength += 3;
 143   
 144  10 if (blockLength > 0)
 145  10 token.addToken(constructStatic(text, blockStart, blockLength, location));
 146   
 147  10 if (expressionLength > 0)
 148    {
 149  8 String expression =
 150    text.substring(expressionStart, expressionStart + expressionLength);
 151   
 152  8 token.addToken(new InsertToken(expression, location));
 153    }
 154   
 155  10 i++;
 156  10 blockStart = i;
 157  10 blockLength = 0;
 158   
 159    // And drop into state start
 160   
 161  10 state = STATE_START;
 162   
 163  10 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  44 if (state == STATE_DOLLAR)
 172  2 blockLength++;
 173   
 174  44 if (state == STATE_COLLECT_EXPRESSION)
 175  2 blockLength += expressionLength + 2;
 176   
 177  44 if (blockLength > 0)
 178  42 token.addToken(constructStatic(text, blockStart, blockLength, location));
 179    }
 180   
 181  52 private IScriptToken constructStatic(
 182    String text,
 183    int blockStart,
 184    int blockLength,
 185    Location location)
 186    {
 187  52 String literal = text.substring(blockStart, blockStart + blockLength);
 188   
 189  52 return new StaticToken(literal, location);
 190    }
 191    }