Clover coverage report - Code Coverage for tapestry release 4.0-alpha-3
Coverage timestamp: Mon May 16 2005 09:05:49 EDT
file stats: LOC: 192   Methods: 4
NCLOC: 107   Classes: 1
30 day Evaluation Version distributed via the Maven Jar Repository. Clover is not free. You have 30 days to evaluate it. Please visit http://www.thecortex.net/clover to obtain a licensed version of Clover
 
 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  31
     protected void addToParent(RuleDirectedParser parser, IScriptToken token)
 38   
     {
 39  31
         IScriptToken parent = (IScriptToken) parser.peek();
 40   
 
 41  31
         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  42
     public void content(RuleDirectedParser parser, String content)
 51   
     {
 52  42
         IScriptToken token = (IScriptToken) parser.peek();
 53   
 
 54  42
         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  42
     protected void addTextTokens(IScriptToken token, String text, Location location)
 65   
     {
 66  42
         char[] buffer = text.toCharArray();
 67  42
         int state = STATE_START;
 68  42
         int blockStart = 0;
 69  42
         int blockLength = 0;
 70  42
         int expressionStart = -1;
 71  42
         int expressionLength = 0;
 72  42
         int i = 0;
 73  42
         int braceDepth = 0;
 74   
 
 75  42
         while (i < buffer.length)
 76   
         {
 77  1436
             char ch = buffer[i];
 78   
 
 79  1436
             switch (state)
 80   
             {
 81   
                 case STATE_START :
 82   
 
 83  1094
                     if (ch == '$')
 84   
                     {
 85  26
                         state = STATE_DOLLAR;
 86  26
                         i++;
 87  26
                         continue;
 88   
                     }
 89   
 
 90  1068
                     blockLength++;
 91  1068
                     i++;
 92  1068
                     continue;
 93   
 
 94   
                 case STATE_DOLLAR :
 95   
 
 96  25
                     if (ch == '{')
 97   
                     {
 98  24
                         state = STATE_COLLECT_EXPRESSION;
 99  24
                         i++;
 100   
 
 101  24
                         expressionStart = i;
 102  24
                         expressionLength = 0;
 103  24
                         braceDepth = 1;
 104   
 
 105  24
                         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   
                 case STATE_COLLECT_EXPRESSION :
 117   
 
 118  317
                     if (ch != '}')
 119   
                     {
 120  293
                         if (ch == '{')
 121  1
                             braceDepth++;
 122   
 
 123  293
                         i++;
 124  293
                         expressionLength++;
 125  293
                         continue;
 126   
                     }
 127   
 
 128  24
                     braceDepth--;
 129   
 
 130  24
                     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  23
                     if (expressionLength == 0)
 142  1
                         blockLength += 3;
 143   
 
 144  23
                     if (blockLength > 0)
 145  23
                         token.addToken(constructStatic(text, blockStart, blockLength, location));
 146   
 
 147  23
                     if (expressionLength > 0)
 148   
                     {
 149  22
                         String expression =
 150   
                             text.substring(expressionStart, expressionStart + expressionLength);
 151   
 
 152  22
                         token.addToken(new InsertToken(expression, location));
 153   
                     }
 154   
 
 155  23
                     i++;
 156  23
                     blockStart = i;
 157  23
                     blockLength = 0;
 158   
 
 159   
                     // And drop into state start
 160   
 
 161  23
                     state = STATE_START;
 162   
 
 163  23
                     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  42
         if (state == STATE_DOLLAR)
 172  1
             blockLength++;
 173   
 
 174  42
         if (state == STATE_COLLECT_EXPRESSION)
 175  1
             blockLength += expressionLength + 2;
 176   
 
 177  42
         if (blockLength > 0)
 178  41
             token.addToken(constructStatic(text, blockStart, blockLength, location));
 179   
     }
 180   
 
 181  64
     private IScriptToken constructStatic(
 182   
         String text,
 183   
         int blockStart,
 184   
         int blockLength,
 185   
         Location location)
 186   
     {
 187  64
         String literal = text.substring(blockStart, blockStart + blockLength);
 188   
 
 189  64
         return new StaticToken(literal, location);
 190   
     }
 191   
 }
 192