Coverage Report - org.apache.myfaces.view.facelets.compiler.TextUnit
 
Classes in this File Line Coverage Branch Coverage Complexity
TextUnit
0%
0/284
0%
0/182
5.857
 
 1  
 /*
 2  
  * Licensed to the Apache Software Foundation (ASF) under one
 3  
  * or more contributor license agreements.  See the NOTICE file
 4  
  * distributed with this work for additional information
 5  
  * regarding copyright ownership.  The ASF licenses this file
 6  
  * to you under the Apache License, Version 2.0 (the
 7  
  * "License"); you may not use this file except in compliance
 8  
  * with the License.  You may obtain a copy of the License at
 9  
  *
 10  
  *   http://www.apache.org/licenses/LICENSE-2.0
 11  
  *
 12  
  * Unless required by applicable law or agreed to in writing,
 13  
  * software distributed under the License is distributed on an
 14  
  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 15  
  * KIND, either express or implied.  See the License for the
 16  
  * specific language governing permissions and limitations
 17  
  * under the License.
 18  
  */
 19  
 package org.apache.myfaces.view.facelets.compiler;
 20  
 
 21  
 import java.util.ArrayList;
 22  
 import java.util.Iterator;
 23  
 import java.util.List;
 24  
 import java.util.Stack;
 25  
 
 26  
 import javax.el.ELException;
 27  
 import javax.faces.application.FacesMessage;
 28  
 import javax.faces.view.facelets.CompositeFaceletHandler;
 29  
 import javax.faces.view.facelets.FaceletHandler;
 30  
 import javax.faces.view.facelets.Tag;
 31  
 import javax.faces.view.facelets.TagAttribute;
 32  
 import javax.faces.view.facelets.TagException;
 33  
 
 34  
 import org.apache.myfaces.shared.renderkit.html.HTML;
 35  
 import org.apache.myfaces.view.facelets.el.ELText;
 36  
 
 37  
 /**
 38  
  * 
 39  
  * @author Jacob Hookom
 40  
  * @version $Id$
 41  
  */
 42  
 final class TextUnit extends CompilationUnit
 43  
 {
 44  
 
 45  
     private final StringBuffer buffer;
 46  
 
 47  
     private final StringBuffer textBuffer;
 48  
 
 49  
     private final List<Instruction> instructionBuffer;
 50  
 
 51  
     private final Stack<Tag> tags;
 52  
 
 53  
     private final List<Object> children;
 54  
 
 55  
     private boolean startTagOpen;
 56  
 
 57  
     private final String alias;
 58  
 
 59  
     private final String id;
 60  
     
 61  
     private final List<Object> messages;
 62  
 
 63  
     private final boolean escapeInlineText;
 64  
 
 65  
     private final boolean compressSpaces;
 66  
 
 67  
     public TextUnit(String alias, String id)
 68  
     {
 69  0
         this(alias,id,true);
 70  0
     }
 71  
     
 72  
     public TextUnit(String alias, String id, boolean escapeInlineText)
 73  
     {
 74  0
         this(alias,id,escapeInlineText,false);
 75  0
     }
 76  
     
 77  
     public TextUnit(String alias, String id, boolean escapeInlineText, boolean compressSpaces)
 78  0
     {
 79  0
         this.alias = alias;
 80  0
         this.id = id;
 81  0
         this.buffer = new StringBuffer();
 82  0
         this.textBuffer = new StringBuffer();
 83  0
         this.instructionBuffer = new ArrayList<Instruction>();
 84  0
         this.tags = new Stack<Tag>();
 85  0
         this.children = new ArrayList<Object>();
 86  0
         this.startTagOpen = false;
 87  0
         this.messages = new ArrayList<Object>(4);
 88  0
         this.escapeInlineText = escapeInlineText;
 89  0
         this.compressSpaces = compressSpaces;
 90  0
     }
 91  
 
 92  
     public FaceletHandler createFaceletHandler()
 93  
     {
 94  0
         this.flushBufferToConfig(true);
 95  
 
 96  0
         if (this.children.size() == 0)
 97  
         {
 98  0
             return LEAF;
 99  
         }
 100  
 
 101  0
         FaceletHandler[] h = new FaceletHandler[this.children.size()];
 102  
         Object obj;
 103  0
         for (int i = 0; i < h.length; i++)
 104  
         {
 105  0
             obj = this.children.get(i);
 106  0
             if (obj instanceof FaceletHandler)
 107  
             {
 108  0
                 h[i] = (FaceletHandler) obj;
 109  
             }
 110  
             else
 111  
             {
 112  0
                 h[i] = ((CompilationUnit) obj).createFaceletHandler();
 113  
             }
 114  
         }
 115  0
         if (h.length == 1)
 116  
         {
 117  0
             return h[0];
 118  
         }
 119  0
         return new CompositeFaceletHandler(h);
 120  
     }
 121  
 
 122  
     private void addInstruction(Instruction instruction)
 123  
     {
 124  0
         this.flushTextBuffer(false);
 125  0
         this.instructionBuffer.add(instruction);
 126  0
     }
 127  
 
 128  
     private void flushTextBuffer(boolean child)
 129  
     {
 130  0
         if (this.textBuffer.length() > 0)
 131  
         {
 132  0
             String s = this.textBuffer.toString();
 133  
 
 134  0
             if (child)
 135  
             {
 136  0
                 s = trimRight(s);
 137  
             }
 138  0
             if (s.length() > 0)
 139  
             {
 140  0
                 if (!compressSpaces)
 141  
                 {
 142  
                     //Do it as usual.
 143  0
                     ELText txt = ELText.parse(s);
 144  0
                     if (txt != null)
 145  
                     {
 146  0
                         if (txt.isLiteral())
 147  
                         {
 148  0
                             if (escapeInlineText)
 149  
                             {
 150  0
                                 this.instructionBuffer.add(new LiteralTextInstruction(txt.toString()));
 151  
                             }
 152  
                             else
 153  
                             {
 154  0
                                 this.instructionBuffer.add(new LiteralNonExcapedTextInstruction(txt.toString()));
 155  
                             }
 156  
                         }
 157  
                         else
 158  
                         {
 159  0
                             if (escapeInlineText)
 160  
                             {
 161  0
                                 this.instructionBuffer.add(new TextInstruction(this.alias, txt ));
 162  
                             }
 163  
                             else
 164  
                             {
 165  
                                 // When escape inline text is disabled (jspx case) we have to split the EL and add
 166  
                                 // separate instructions, so it can be properly escaped.
 167  0
                                 ELText[] splitText = ELText.parseAsArray(s);
 168  0
                                 if (splitText.length > 1)
 169  
                                 {
 170  0
                                     Instruction[] array = new Instruction[splitText.length];
 171  0
                                     for (int i = 0; i < splitText.length; i++)
 172  
                                     {
 173  0
                                         ELText selText = splitText[i];
 174  0
                                         if (selText.isLiteral())
 175  
                                         {
 176  0
                                             array[i] = new LiteralNonExcapedTextInstruction(selText.toString());
 177  
                                         }
 178  
                                         else
 179  
                                         {
 180  0
                                             array[i] = new TextInstruction(this.alias, selText );
 181  
                                         }
 182  
                                     }
 183  0
                                     this.instructionBuffer.add(new CompositeTextInstruction(array));
 184  0
                                 }
 185  
                                 else
 186  
                                 {
 187  0
                                     this.instructionBuffer.add(new TextInstruction(this.alias, txt ));
 188  
                                 }
 189  
                             }
 190  
                         }
 191  
                     }
 192  0
                 }
 193  
                 else
 194  
                 {
 195  
                     // First check if the text contains EL before build something, and if contains 
 196  
                     // an EL expression, compress it before build the ELText.
 197  0
                     if (s != null && s.length() > 0)
 198  
                     {
 199  0
                         if (ELText.isLiteral(s))
 200  
                         {
 201  0
                             if (escapeInlineText)
 202  
                             {
 203  0
                                 this.instructionBuffer.add(new LiteralTextInstruction(s));
 204  
                             }
 205  
                             else
 206  
                             {
 207  0
                                 this.instructionBuffer.add(new LiteralNonExcapedTextInstruction(s));
 208  
                             }
 209  
                         }
 210  
                         else
 211  
                         {
 212  0
                             if (instructionBuffer.size() > 0 && 
 213  
                                 !(instructionBuffer.get(instructionBuffer.size()-1) instanceof LiteralXMLInstruction))
 214  
                             {
 215  0
                                 s = compressELText(s);
 216  
                             }
 217  
                             // When escape inline text is disabled (jspx case) we have to split the EL and add
 218  
                             // separate instructions, so it can be properly escaped.
 219  0
                             ELText[] splitText = ELText.parseAsArray(s);
 220  0
                             if (splitText.length > 1)
 221  
                             {
 222  0
                                 Instruction[] array = new Instruction[splitText.length];
 223  0
                                 for (int i = 0; i < splitText.length; i++)
 224  
                                 {
 225  0
                                     ELText selText = splitText[i];
 226  0
                                     if (selText.isLiteral())
 227  
                                     {
 228  0
                                         array[i] = new LiteralNonExcapedTextInstruction(selText.toString());
 229  
                                     }
 230  
                                     else
 231  
                                     {
 232  0
                                         array[i] = new TextInstruction(this.alias, selText );
 233  
                                     }
 234  
                                 }
 235  0
                                 this.instructionBuffer.add(new CompositeTextInstruction(array));
 236  0
                             }
 237  
                             else
 238  
                             {
 239  0
                                 this.instructionBuffer.add(new TextInstruction(this.alias, ELText.parse(s)));
 240  
                             }
 241  
                         }
 242  
                     }
 243  
                 }
 244  
             }
 245  
 
 246  
         }
 247  0
         this.textBuffer.setLength(0);
 248  0
     }
 249  
 
 250  
     public void write(String text)
 251  
     {
 252  0
         this.finishStartTag();
 253  0
         this.textBuffer.append(text);
 254  0
         this.buffer.append(text);
 255  0
     }
 256  
 
 257  
     public void writeInstruction(String text)
 258  
     {
 259  0
         this.finishStartTag();
 260  0
         ELText el = ELText.parse(text);
 261  0
         if (el.isLiteral())
 262  
         {
 263  0
             this.addInstruction(new LiteralXMLInstruction(text));
 264  
         }
 265  
         else
 266  
         {
 267  0
             this.addInstruction(new XMLInstruction(el));
 268  
         }
 269  0
         this.buffer.append(text);
 270  0
     }
 271  
 
 272  
     public void writeComment(String text)
 273  
     {
 274  0
         this.finishStartTag();
 275  
 
 276  0
         ELText el = ELText.parse(text);
 277  0
         if (el.isLiteral())
 278  
         {
 279  0
             this.addInstruction(new LiteralCommentInstruction(text));
 280  
         }
 281  
         else
 282  
         {
 283  0
             this.addInstruction(new CommentInstruction(el));
 284  
         }
 285  
 
 286  0
         this.buffer.append("<!--" + text + "-->");
 287  0
     }
 288  
 
 289  
     public void startTag(Tag tag)
 290  
     {
 291  
 
 292  
         // finish any previously written tags
 293  0
         this.finishStartTag();
 294  
 
 295  
         // push this tag onto the stack
 296  0
         this.tags.push(tag);
 297  
 
 298  
         // write it out
 299  0
         this.buffer.append('<');
 300  0
         this.buffer.append(tag.getQName());
 301  
 
 302  0
         this.addInstruction(new StartElementInstruction(tag.getQName()));
 303  
 
 304  0
         TagAttribute[] attrs = tag.getAttributes().getAll();
 305  0
         if (attrs.length > 0)
 306  
         {
 307  0
             for (int i = 0; i < attrs.length; i++)
 308  
             {
 309  0
                 String qname = attrs[i].getQName();
 310  0
                 String value = attrs[i].getValue();
 311  0
                 this.buffer.append(' ').append(qname).append("=\"").append(value).append("\"");
 312  
 
 313  0
                 ELText txt = ELText.parseAllowEmptyString(value);
 314  0
                 if (txt != null)
 315  
                 {
 316  0
                     if (txt.isLiteral())
 317  
                     {
 318  0
                         this.addInstruction(new LiteralAttributeInstruction(qname, txt.toString()));
 319  
                     }
 320  
                     else
 321  
                     {
 322  0
                         this.addInstruction(new AttributeInstruction(this.alias, qname, txt));
 323  
                     }
 324  
                 }
 325  
             }
 326  
         }
 327  
         
 328  0
         if (!messages.isEmpty())
 329  
         {
 330  0
             for (Iterator<Object> it = messages.iterator(); it.hasNext();)
 331  
             {
 332  0
                 Object[] message = (Object[])it.next();
 333  0
                 this.addInstruction(new AddFacesMessageInstruction((FacesMessage.Severity) message[0],
 334  
                                                                    (String)message[1], (String)message[2]));
 335  0
                 it.remove();
 336  0
             }
 337  
         }
 338  
 
 339  
         // notify that we have an open tag
 340  0
         this.startTagOpen = true;
 341  0
     }
 342  
 
 343  
     private void finishStartTag()
 344  
     {
 345  0
         if (this.tags.size() > 0 && this.startTagOpen)
 346  
         {
 347  0
             this.buffer.append(">");
 348  0
             this.startTagOpen = false;
 349  
         }
 350  0
     }
 351  
 
 352  
     public void endTag()
 353  
     {
 354  0
         Tag tag = (Tag) this.tags.pop();
 355  
 
 356  0
         if (HTML.BODY_ELEM.equalsIgnoreCase(tag.getQName()))
 357  
         {
 358  0
             this.addInstruction(new BodyEndElementInstruction(tag.getQName()));
 359  
         }
 360  
         else
 361  
         {
 362  0
             this.addInstruction(new EndElementInstruction(tag.getQName()));            
 363  
         }
 364  
 
 365  0
         if (this.startTagOpen)
 366  
         {
 367  0
             this.buffer.append("/>");
 368  0
             this.startTagOpen = false;
 369  
         }
 370  
         else
 371  
         {
 372  0
             this.buffer.append("</").append(tag.getQName()).append('>');
 373  
         }
 374  0
     }
 375  
 
 376  
     public void addChild(CompilationUnit unit)
 377  
     {
 378  
         // if we are adding some other kind of unit
 379  
         // then we need to capture our buffer into a UITextHandler
 380  0
         this.finishStartTag();
 381  0
         this.flushBufferToConfig(true);
 382  0
         this.children.add(unit);
 383  0
     }
 384  
 
 385  
     protected void flushBufferToConfig(boolean child)
 386  
     {
 387  0
         this.flushTextBuffer(child);
 388  
 
 389  0
         int size = this.instructionBuffer.size();
 390  0
         if (size > 0)
 391  
         {
 392  
             try
 393  
             {
 394  0
                 String s = this.buffer.toString();
 395  0
                 if (child)
 396  
                 {
 397  0
                     s = trimRight(s);
 398  
                 }
 399  0
                 ELText txt = ELText.parse(s);
 400  0
                 if (txt != null)
 401  
                 {
 402  0
                     if (compressSpaces)
 403  
                     {
 404  
                         // Use the logic behind the instructions to remove unnecessary instructions
 405  
                         // containing only spaces, or recreating new ones containing only the necessary
 406  
                         // spaces.
 407  0
                         size = compressSpaces(instructionBuffer, size);
 408  
                     }
 409  0
                     Instruction[] instructions = (Instruction[]) this.instructionBuffer
 410  
                             .toArray(new Instruction[size]);
 411  0
                     this.children.add(new UIInstructionHandler(this.alias, this.id, instructions, txt));
 412  0
                     this.instructionBuffer.clear();
 413  
                 }
 414  
 
 415  
             }
 416  0
             catch (ELException e)
 417  
             {
 418  0
                 if (this.tags.size() > 0)
 419  
                 {
 420  0
                     throw new TagException((Tag) this.tags.peek(), e.getMessage());
 421  
                 }
 422  
                 else
 423  
                 {
 424  0
                     throw new ELException(this.alias + ": " + e.getMessage(), e.getCause());
 425  
                 }
 426  0
             }
 427  
         }
 428  
 
 429  
         // ALWAYS CLEAR FOR BOTH IMPL
 430  0
         this.buffer.setLength(0);
 431  0
     }
 432  
 
 433  
     public boolean isClosed()
 434  
     {
 435  0
         return this.tags.empty();
 436  
     }
 437  
 
 438  
     private final static String trimRight(String s)
 439  
     {
 440  0
         int i = s.length() - 1;
 441  0
         while (i >= 0 && Character.isWhitespace(s.charAt(i)))
 442  
         {
 443  0
             i--;
 444  
         }
 445  0
         if (i >= 0)
 446  
         {
 447  0
             return s;
 448  
         }
 449  
         else
 450  
         {
 451  0
             return "";
 452  
         }
 453  
         /*
 454  
         if (i == s.length() - 1)
 455  
         {
 456  
             return s;
 457  
         }
 458  
         else
 459  
         {
 460  
             return s.substring(0, i + 1);
 461  
         }*/
 462  
     }
 463  
     
 464  
     final static String compressELText(String text)
 465  
     {
 466  
         //int firstCharLocation = getFirstTextCharLocationIgnoringSpacesTabsAndCarriageReturn(text);
 467  0
         int firstCharLocation = -1;
 468  0
         int leftChar = 0; // 0=first char on left 1=\n 2=\r 3=\r\n
 469  0
         int lenght = text.length();
 470  0
         String leftText = null;
 471  0
         for (int j = 0; j < lenght; j++)
 472  
         {
 473  0
             char c = text.charAt(j);
 474  0
             if (leftChar == 0)
 475  
             {
 476  0
                 if (c == '\r')
 477  
                 {
 478  0
                     leftChar = 2;
 479  0
                     if (j+1 < lenght)
 480  
                     {
 481  0
                         if (text.charAt(j+1) == '\n')
 482  
                         {
 483  0
                             leftChar = 3;
 484  
                         }
 485  
                     }
 486  
                 }
 487  0
                 if (c == '\n')
 488  
                 {
 489  0
                     leftChar = 1;
 490  
                 }
 491  
             }
 492  0
             if (Character.isWhitespace(c))
 493  
             {
 494  0
                 continue;
 495  
             }
 496  
             else
 497  
             {
 498  0
                 firstCharLocation = j;
 499  0
                 break;
 500  
             }
 501  
         }
 502  0
         if (firstCharLocation == -1)
 503  
         {
 504  0
             firstCharLocation = lenght;
 505  
         }
 506  
         // Define the character on the left
 507  0
         if (firstCharLocation > 0)
 508  
         {
 509  0
             switch (leftChar)
 510  
             {
 511  
                 case 1:
 512  0
                     leftText = "\n";
 513  0
                     break;
 514  
                 case 2:
 515  0
                     leftText = "\r";
 516  0
                     break;
 517  
                 case 3:
 518  0
                     leftText = "\r\n";
 519  0
                     break;
 520  
                 default:
 521  0
                     leftText = (lenght > 1) ? text.substring(0,1) : text;
 522  0
                     break;
 523  
             }                
 524  
         }
 525  
         else
 526  
         {
 527  0
             leftText = "";
 528  
         }
 529  
                 
 530  0
         int lastCharLocation = getLastTextCharLocationIgnoringSpacesTabsAndCarriageReturn(text);
 531  0
         if (firstCharLocation == 0 && lastCharLocation == text.length()-1)
 532  
         {
 533  0
             return text;
 534  
         }
 535  
         else
 536  
         {
 537  0
             if (lastCharLocation+1 < text.length())
 538  
             {
 539  0
                 lastCharLocation = lastCharLocation+1;
 540  
             }
 541  0
             if (firstCharLocation == 0)
 542  
             {
 543  0
                 return text.substring(firstCharLocation, lastCharLocation+1);
 544  
             }
 545  
             else
 546  
             {
 547  0
                 return leftText+text.substring(firstCharLocation, lastCharLocation+1);
 548  
             }
 549  
         }
 550  
     }
 551  
     
 552  
     /**
 553  
      * Compress spaces around a list of instructions, following these rules:
 554  
      * 
 555  
      * - The first instruction that is on the left usually make contact with a component.
 556  
      * 
 557  
      * @param instructionBuffer
 558  
      * @param size
 559  
      * @return 
 560  
      */
 561  
     final static int compressSpaces(List<Instruction> instructionBuffer, int size)
 562  
     {
 563  0
         boolean addleftspace = true;
 564  0
         boolean addrightspace = false;
 565  0
         boolean skipnext = false;
 566  0
         for (int i = 0; i < size; i++)
 567  
         {
 568  0
             String text = null;
 569  0
             String newText = null;
 570  0
             int instructionType = 0;
 571  0
             if (skipnext)
 572  
             {
 573  0
                 skipnext = false;
 574  0
                 continue;
 575  
             }
 576  0
             Instruction ins = instructionBuffer.get(i);
 577  0
             if (i+1 == size)
 578  
             {
 579  0
                 addrightspace = true;
 580  
             }
 581  
             
 582  0
             if (ins instanceof LiteralTextInstruction)
 583  
             {
 584  0
                 text = ((LiteralTextInstruction)ins).getText();
 585  0
                 instructionType = 1;
 586  
             }
 587  0
             else if (ins instanceof LiteralNonExcapedTextInstruction)
 588  
             {
 589  0
                 text = ((LiteralTextInstruction)ins).getText();
 590  0
                 instructionType = 2;
 591  
             }
 592  0
             else if (ins instanceof LiteralXMLInstruction)
 593  
             {
 594  0
                 skipnext = true;
 595  0
                 continue;
 596  
             }
 597  
             
 598  0
             if (text != null && text.length() > 0)
 599  
             {
 600  0
                 int firstCharLocation = -1;
 601  0
                 int leftChar = 0; // 0=first char on left 1=\n 2=\r 3=\r\n
 602  0
                 int lenght = text.length();
 603  0
                 String leftText = null;
 604  0
                 for (int j = 0; j < lenght; j++)
 605  
                 {
 606  0
                     char c = text.charAt(j);
 607  0
                     if (leftChar == 0)
 608  
                     {
 609  0
                         if (c == '\r')
 610  
                         {
 611  0
                             leftChar = 2;
 612  0
                             if (j+1 < lenght)
 613  
                             {
 614  0
                                 if (text.charAt(j+1) == '\n')
 615  
                                 {
 616  0
                                     leftChar = 3;
 617  
                                 }
 618  
                             }
 619  
                         }
 620  0
                         if (c == '\n')
 621  
                         {
 622  0
                             leftChar = 1;
 623  
                         }
 624  
                     }
 625  0
                     if (Character.isWhitespace(c))
 626  
                     {
 627  0
                         continue;
 628  
                     }
 629  
                     else
 630  
                     {
 631  0
                         firstCharLocation = j;
 632  0
                         break;
 633  
                     }
 634  
                 }
 635  0
                 if (firstCharLocation == -1)
 636  
                 {
 637  0
                     firstCharLocation = lenght;
 638  
                 }
 639  
                 // Define the character on the left
 640  0
                 if (firstCharLocation > 0)
 641  
                 {
 642  0
                     switch (leftChar)
 643  
                     {
 644  
                         case 1:
 645  0
                             leftText = "\n";
 646  0
                             break;
 647  
                         case 2:
 648  0
                             leftText = "\r";
 649  0
                             break;
 650  
                         case 3:
 651  0
                             leftText = "\r\n";
 652  0
                             break;
 653  
                         default:
 654  0
                             leftText = (lenght > 1) ? text.substring(0,1) : text;
 655  0
                             break;
 656  
                     }                
 657  
                 }
 658  
                 else
 659  
                 {
 660  0
                     leftText = "";
 661  
                 }
 662  
                 
 663  0
                 if (firstCharLocation == lenght && lenght > 1)
 664  
                 {
 665  
                     // All the instruction is space, replace with an instruction 
 666  
                     // with only one space
 667  0
                     if (addleftspace || addrightspace)
 668  
                     {
 669  0
                         newText = leftText;
 670  
                     }
 671  
                     else
 672  
                     {
 673  0
                         instructionBuffer.remove(i);
 674  0
                         i--;
 675  0
                         size--;
 676  
                     }
 677  
                 }
 678  
                 else
 679  
                 {
 680  0
                     int lastCharLocation = getLastTextCharLocationIgnoringSpacesTabsAndCarriageReturn(text);
 681  
                     // If right space, increment in 1
 682  0
                     if (lastCharLocation+1 < text.length())
 683  
                     {
 684  0
                         lastCharLocation = lastCharLocation+1;
 685  
                     }
 686  0
                     if (firstCharLocation > 0)
 687  
                     {
 688  0
                         newText = leftText+
 689  
                             text.substring(firstCharLocation, lastCharLocation+1);
 690  
                     }
 691  
                     else
 692  
                     {
 693  0
                         newText = text.substring(firstCharLocation, lastCharLocation+1);
 694  
                     }
 695  
                 }
 696  
                 
 697  0
                 if (newText != null)
 698  
                 {
 699  0
                     if (instructionType == 1)
 700  
                     {
 701  0
                         instructionBuffer.set(i, new LiteralTextInstruction(newText));
 702  
                     }
 703  0
                     else if (instructionType == 2)
 704  
                     {
 705  0
                         instructionBuffer.set(i, new LiteralNonExcapedTextInstruction(newText));
 706  
                     }
 707  
                 }
 708  
             }
 709  0
             addleftspace = false;
 710  
         }
 711  0
         return size;
 712  
     }
 713  
     
 714  
     private static int getLastTextCharLocationIgnoringSpacesTabsAndCarriageReturn(String text)
 715  
     {
 716  0
         for (int i = text.length()-1; i >= 0; i--)
 717  
         {
 718  0
             if (Character.isWhitespace(text.charAt(i)))
 719  
             {
 720  0
                 continue;
 721  
             }
 722  
             else
 723  
             {
 724  0
                 return i;
 725  
             }
 726  
         }
 727  0
         return 0;
 728  
     }
 729  
 
 730  
     public String toString()
 731  
     {
 732  0
         return "TextUnit[" + this.children.size() + "]";
 733  
     }
 734  
     
 735  
     public void addMessage(FacesMessage.Severity severity, String summary, String detail)
 736  
     {
 737  0
         this.messages.add(new Object[]{severity, summary, detail});
 738  0
     }
 739  
 }