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: 371   Methods: 31
NCLOC: 240   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
MarkupWriterImpl.java 97.5% 98.3% 96.8% 97.9%
coverage coverage
 1   
 // Copyright 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.markup;
 16   
 
 17   
 import java.io.PrintWriter;
 18   
 import java.util.ArrayList;
 19   
 import java.util.List;
 20   
 
 21   
 import org.apache.hivemind.ApplicationRuntimeException;
 22   
 import org.apache.hivemind.util.Defense;
 23   
 import org.apache.tapestry.IMarkupWriter;
 24   
 import org.apache.tapestry.NestedMarkupWriter;
 25   
 
 26   
 /**
 27   
  * Completely revised (for 4.0) implementation of {@link org.apache.tapestry.IMarkupWriter}. No
 28   
  * longer does internal buffering (since the servlet/portlet APIs support that natively) and wraps
 29   
  * around a {@link java.io.PrintWriter} (rather than an {@link java.io.OutputStream}).
 30   
  * 
 31   
  * @author Howard M. Lewis Ship
 32   
  * @since 4.0
 33   
  */
 34   
 public class MarkupWriterImpl implements IMarkupWriter
 35   
 {
 36   
     /**
 37   
      * The underlying {@link PrintWriter}that output is sent to.
 38   
      */
 39   
 
 40   
     private PrintWriter _writer;
 41   
 
 42   
     /**
 43   
      * Filter used to "escape" characters that need any kind of special encoding for the output
 44   
      * content type.
 45   
      */
 46   
 
 47   
     private MarkupFilter _filter;
 48   
 
 49   
     /**
 50   
      * Indicates whether a tag is open or not. A tag is opened by {@link #begin(String)}or
 51   
      * {@link #beginEmpty(String)}. It stays open while calls to the <code>attribute()</code>
 52   
      * methods are made. It is closed (the '&gt;' is written) when any other method is invoked.
 53   
      */
 54   
 
 55   
     private boolean _openTag = false;
 56   
 
 57   
     /**
 58   
      * Indicates that the tag was opened with {@link #beginEmpty(String)}, which affects how the
 59   
      * tag is closed (a slash is added to indicate the lack of a body). This is compatible with
 60   
      * HTML, but reflects an XML/XHTML leaning.
 61   
      */
 62   
 
 63   
     private boolean _emptyTag = false;
 64   
 
 65   
     private String _contentType;
 66   
 
 67   
     /**
 68   
      * A Stack of Strings used to track the active tag elements. Elements are active until the
 69   
      * corresponding close tag is written. The {@link #push(String)}method adds elements to the
 70   
      * stack, {@link #pop()}removes them.
 71   
      */
 72   
 
 73   
     private List _activeElementStack;
 74   
 
 75  462
     public MarkupWriterImpl(String contentType, PrintWriter writer, MarkupFilter filter)
 76   
     {
 77  462
         Defense.notNull(contentType, "contentType");
 78  462
         Defense.notNull(writer, "writer");
 79  462
         Defense.notNull(filter, "filter");
 80   
 
 81  462
         _contentType = contentType;
 82  462
         _writer = writer;
 83  462
         _filter = filter;
 84   
     }
 85   
 
 86  142
     public void attribute(String name, int value)
 87   
     {
 88  142
         checkTagOpen();
 89   
 
 90  141
         _writer.print(' ');
 91  141
         _writer.print(name);
 92  141
         _writer.print("=\"");
 93  141
         _writer.print(value);
 94  141
         _writer.print('"');
 95   
     }
 96   
 
 97  5
     public void attribute(String name, boolean value)
 98   
     {
 99  5
         checkTagOpen();
 100   
 
 101  4
         _writer.print(' ');
 102  4
         _writer.print(name);
 103  4
         _writer.print("=\"");
 104  4
         _writer.print(value);
 105  4
         _writer.print('"');
 106   
     }
 107   
 
 108  2846
     public void attribute(String name, String value)
 109   
     {
 110  2846
         attribute(name, value, false);
 111   
     }
 112   
 
 113  2853
     public void attribute(String name, String value, boolean raw)
 114   
     {
 115  2853
         checkTagOpen();
 116   
 
 117  2852
         _writer.print(' ');
 118   
 
 119   
         // Could use a check here that name contains only valid characters
 120   
 
 121  2852
         _writer.print(name);
 122  2852
         _writer.print("=\"");
 123   
 
 124  2852
         if (value != null)
 125   
         {
 126  2850
             char[] data = value.toCharArray();
 127  2850
             maybePrintFiltered(data, 0, data.length, raw, true);
 128   
         }
 129   
 
 130  2852
         _writer.print('"');
 131   
     }
 132   
 
 133   
     /**
 134   
      * Prints the value, if non-null. May pass it through the filter, unless raw is true.
 135   
      */
 136   
 
 137  13269
     private void maybePrintFiltered(char[] data, int offset, int length, boolean raw,
 138   
             boolean isAttribute)
 139   
     {
 140  13269
         if (data == null || length <= 0)
 141  139
             return;
 142   
 
 143  13130
         if (raw)
 144   
         {
 145  3640
             _writer.write(data, offset, length);
 146  3640
             return;
 147   
         }
 148   
 
 149  9490
         _filter.print(_writer, data, offset, length, isAttribute);
 150   
     }
 151   
 
 152  7
     public void attributeRaw(String name, String value)
 153   
     {
 154  7
         attribute(name, value, true);
 155   
     }
 156   
 
 157  11631
     public void begin(String name)
 158   
     {
 159  11631
         if (_openTag)
 160  3192
             closeTag();
 161   
 
 162  11631
         push(name);
 163   
 
 164  11631
         _writer.print('<');
 165  11631
         _writer.print(name);
 166   
 
 167  11631
         _openTag = true;
 168  11631
         _emptyTag = false;
 169   
     }
 170   
 
 171  848
     public void beginEmpty(String name)
 172   
     {
 173  848
         if (_openTag)
 174  2
             closeTag();
 175   
 
 176  848
         _writer.print('<');
 177  848
         _writer.print(name);
 178   
 
 179  848
         _openTag = true;
 180  848
         _emptyTag = true;
 181   
     }
 182   
 
 183  0
     public boolean checkError()
 184   
     {
 185  0
         return _writer.checkError();
 186   
     }
 187   
 
 188  391
     public void close()
 189   
     {
 190  391
         if (_openTag)
 191  0
             closeTag();
 192   
 
 193   
         // Close any active elements.
 194   
 
 195  391
         while (!stackEmpty())
 196   
         {
 197  3
             _writer.print("</");
 198  3
             _writer.print(pop());
 199  3
             _writer.print('>');
 200   
         }
 201   
 
 202  391
         _writer.close();
 203   
 
 204  391
         _writer = null;
 205  391
         _filter = null;
 206  391
         _activeElementStack = null;
 207   
     }
 208   
 
 209  12471
     public void closeTag()
 210   
     {
 211  12471
         if (_emptyTag)
 212  847
             _writer.print('/');
 213   
 
 214  12471
         _writer.print('>');
 215   
 
 216  12471
         _openTag = false;
 217  12471
         _emptyTag = false;
 218   
     }
 219   
 
 220  534
     public void comment(String value)
 221   
     {
 222  534
         if (_openTag)
 223  1
             closeTag();
 224   
 
 225  534
         _writer.print("<!-- ");
 226  534
         _writer.print(value);
 227  534
         _writer.println(" -->");
 228   
     }
 229   
 
 230  5251
     public void end()
 231   
     {
 232  5251
         if (_openTag)
 233  1089
             closeTag();
 234   
 
 235  5251
         if (stackEmpty())
 236  1
             throw new ApplicationRuntimeException(MarkupMessages.endWithEmptyStack());
 237   
 
 238  5250
         _writer.print("</");
 239  5250
         _writer.print(pop());
 240  5250
         _writer.print('>');
 241   
     }
 242   
 
 243  3228
     public void end(String name)
 244   
     {
 245  3228
         if (_openTag)
 246  8
             closeTag();
 247   
 
 248  3228
         if (_activeElementStack == null || !_activeElementStack.contains(name))
 249  1
             throw new ApplicationRuntimeException(MarkupMessages.elementNotOnStack(
 250   
                     name,
 251   
                     _activeElementStack));
 252   
 
 253  3227
         while (true)
 254   
         {
 255  6352
             String tagName = pop();
 256   
 
 257  6352
             _writer.print("</");
 258  6352
             _writer.print(tagName);
 259  6352
             _writer.print('>');
 260   
 
 261  6352
             if (tagName.equals(name))
 262  3227
                 break;
 263   
         }
 264   
     }
 265   
 
 266  1
     public void flush()
 267   
     {
 268  1
         _writer.flush();
 269   
     }
 270   
 
 271  264
     public NestedMarkupWriter getNestedWriter()
 272   
     {
 273  264
         return new NestedMarkupWriterImpl(this, _filter);
 274   
     }
 275   
 
 276  2
     public void print(char[] data, int offset, int length)
 277   
     {
 278  2
         print(data, offset, length, false);
 279   
     }
 280   
 
 281  3221
     public void printRaw(char[] buffer, int offset, int length)
 282   
     {
 283  3221
         print(buffer, offset, length, true);
 284   
     }
 285   
 
 286  10419
     public void print(char[] buffer, int offset, int length, boolean raw)
 287   
     {
 288  10419
         if (_openTag)
 289  6724
             closeTag();
 290   
 
 291  10419
         maybePrintFiltered(buffer, offset, length, raw, false);
 292   
     }
 293   
 
 294  5233
     public void print(String value)
 295   
     {
 296  5233
         print(value, false);
 297   
     }
 298   
 
 299  425
     public void printRaw(String value)
 300   
     {
 301  425
         print(value, true);
 302   
     }
 303   
 
 304  7196
     public void print(String value, boolean raw)
 305   
     {
 306  7196
         if (value == null || value.length() == 0)
 307   
         {
 308  123
             print(null, 0, 0, raw);
 309  123
             return;
 310   
         }
 311   
 
 312  7073
         char[] buffer = value.toCharArray();
 313   
 
 314  7073
         print(buffer, 0, buffer.length, raw);
 315   
     }
 316   
 
 317  1
     public void print(char value)
 318   
     {
 319  1
         char[] data = new char[]
 320   
         { value };
 321   
 
 322  1
         print(data, 0, 1);
 323   
     }
 324   
 
 325  195
     public void print(int value)
 326   
     {
 327  195
         if (_openTag)
 328  194
             closeTag();
 329   
 
 330  195
         _writer.print(value);
 331   
     }
 332   
 
 333  5422
     public void println()
 334   
     {
 335  5422
         if (_openTag)
 336  1214
             closeTag();
 337   
 
 338  5422
         _writer.println();
 339   
     }
 340   
 
 341  400
     public String getContentType()
 342   
     {
 343  400
         return _contentType;
 344   
     }
 345   
 
 346  3000
     private void checkTagOpen()
 347   
     {
 348  3000
         if (!_openTag)
 349  3
             throw new IllegalStateException(MarkupMessages.tagNotOpen());
 350   
     }
 351   
 
 352  11631
     private void push(String name)
 353   
     {
 354  11631
         if (_activeElementStack == null)
 355  264
             _activeElementStack = new ArrayList();
 356   
 
 357  11631
         _activeElementStack.add(name);
 358   
     }
 359   
 
 360  11605
     private String pop()
 361   
     {
 362  11605
         int lastIndex = _activeElementStack.size() - 1;
 363   
 
 364  11605
         return (String) _activeElementStack.remove(lastIndex);
 365   
     }
 366   
 
 367  5645
     private boolean stackEmpty()
 368   
     {
 369  5645
         return _activeElementStack == null || _activeElementStack.isEmpty();
 370   
     }
 371   
 }