Coverage Report - org.apache.tapestry.script.AbstractTokenRule
 
Classes in this File Line Coverage Branch Coverage Complexity
AbstractTokenRule
0%
0/68
0%
0/28
4.75
 
 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  0
 abstract class AbstractTokenRule extends BaseRule
 32  
 {
 33  
 
 34  
     private static final int STATE_START = 0;
 35  
     private static final int STATE_DOLLAR = 1;
 36  
     private static final int STATE_COLLECT_EXPRESSION = 2;
 37  
     
 38  
     /**
 39  
      * Adds a token to its parent, the top object on the stack.
 40  
      */
 41  
     protected void addToParent(RuleDirectedParser parser, IScriptToken token)
 42  
     {
 43  0
         IScriptToken parent = (IScriptToken) parser.peek();
 44  
 
 45  0
         parent.addToken(token);
 46  0
     }
 47  
 
 48  
     /**
 49  
      * {@inheritDoc}
 50  
      */
 51  
     public void content(RuleDirectedParser parser, String content)
 52  
     {
 53  0
         IScriptToken token = (IScriptToken) parser.peek();
 54  
 
 55  0
         addTextTokens(token, content, parser.getLocation());
 56  0
     }
 57  
 
 58  
     /**
 59  
      * Parses the provided text and converts it into a series of .
 60  
      */
 61  
     protected void addTextTokens(IScriptToken token, String text, Location location)
 62  
     {
 63  0
         char[] buffer = text.toCharArray();
 64  0
         int state = STATE_START;
 65  0
         int blockStart = 0;
 66  0
         int blockLength = 0;
 67  0
         int expressionStart = -1;
 68  0
         int expressionLength = 0;
 69  0
         int i = 0;
 70  0
         int braceDepth = 0;
 71  
 
 72  0
         while (i < buffer.length)
 73  
         {
 74  0
             char ch = buffer[i];
 75  
 
 76  0
             switch (state)
 77  
             {
 78  
                 case STATE_START :
 79  
 
 80  0
                     if (ch == '$')
 81  
                     {
 82  0
                         state = STATE_DOLLAR;
 83  0
                         i++;
 84  0
                         continue;
 85  
                     }
 86  
 
 87  0
                     blockLength++;
 88  0
                     i++;
 89  0
                     continue;
 90  
 
 91  
                 case STATE_DOLLAR :
 92  
 
 93  0
                     if (ch == '{')
 94  
                     {
 95  0
                         state = STATE_COLLECT_EXPRESSION;
 96  0
                         i++;
 97  
 
 98  0
                         expressionStart = i;
 99  0
                         expressionLength = 0;
 100  0
                         braceDepth = 1;
 101  
 
 102  0
                         continue;
 103  
                     }
 104  
 
 105  
                     // The '$' was just what it was, not the start of a ${} expression
 106  
                     // block, so include it as part of the static text block.
 107  
 
 108  0
                     blockLength++;
 109  
 
 110  0
                     state = STATE_START;
 111  0
                     continue;
 112  
 
 113  
                 case STATE_COLLECT_EXPRESSION :
 114  
 
 115  0
                     if (ch != '}')
 116  
                     {
 117  0
                         if (ch == '{')
 118  0
                             braceDepth++;
 119  
 
 120  0
                         i++;
 121  0
                         expressionLength++;
 122  0
                         continue;
 123  
                     }
 124  
 
 125  0
                     braceDepth--;
 126  
 
 127  0
                     if (braceDepth > 0)
 128  
                     {
 129  0
                         i++;
 130  0
                         expressionLength++;
 131  0
                         continue;
 132  
                     }
 133  
 
 134  
                     // Hit the closing brace of an expression.
 135  
 
 136  
                     // Degenerate case:  the string "${}".
 137  
 
 138  0
                     if (expressionLength == 0)
 139  0
                         blockLength += 3;
 140  
 
 141  0
                     if (blockLength > 0)
 142  0
                         token.addToken(constructStatic(text, blockStart, blockLength, location));
 143  
 
 144  0
                     if (expressionLength > 0)
 145  
                     {
 146  0
                         String expression =
 147  
                             text.substring(expressionStart, expressionStart + expressionLength);
 148  
 
 149  0
                         token.addToken(new InsertToken(expression, location));
 150  
                     }
 151  
 
 152  0
                     i++;
 153  0
                     blockStart = i;
 154  0
                     blockLength = 0;
 155  
 
 156  
                     // And drop into state start
 157  
 
 158  0
                     state = STATE_START;
 159  
 
 160  0
                     continue;
 161  
             }
 162  
 
 163  0
         }
 164  
 
 165  
         // OK, to handle the end.  Couple of degenerate cases where
 166  
         // a ${...} was incomplete, so we adust the block length.
 167  
 
 168  0
         if (state == STATE_DOLLAR)
 169  0
             blockLength++;
 170  
 
 171  0
         if (state == STATE_COLLECT_EXPRESSION)
 172  0
             blockLength += expressionLength + 2;
 173  
 
 174  0
         if (blockLength > 0)
 175  0
             token.addToken(constructStatic(text, blockStart, blockLength, location));
 176  0
     }
 177  
 
 178  
     private IScriptToken constructStatic(
 179  
         String text,
 180  
         int blockStart,
 181  
         int blockLength,
 182  
         Location location)
 183  
     {
 184  0
         String literal = text.substring(blockStart, blockStart + blockLength);
 185  
 
 186  0
         return new StaticToken(literal, location);
 187  
     }
 188  
 }