Coverage Report - org.apache.myfaces.view.facelets.el.ELText
 
Classes in this File Line Coverage Branch Coverage Complexity
ELText
0%
0/146
0%
0/128
3.341
ELText$ELCacheableTextVariable
0%
0/53
0%
0/40
3.341
ELText$ELTextComposite
0%
0/23
0%
0/10
3.341
ELText$ELTextVariable
0%
0/18
0%
0/6
3.341
ELText$LiteralValueExpression
0%
0/12
N/A
3.341
 
 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.el;
 20  
 
 21  
 import java.io.IOException;
 22  
 import java.io.Writer;
 23  
 import java.util.ArrayList;
 24  
 import java.util.List;
 25  
 
 26  
 import javax.el.ELContext;
 27  
 import javax.el.ELException;
 28  
 import javax.el.ExpressionFactory;
 29  
 import javax.el.ValueExpression;
 30  
 import javax.faces.component.UIComponent;
 31  
 import javax.faces.context.ResponseWriter;
 32  
 import javax.faces.view.Location;
 33  
 
 34  
 import org.apache.myfaces.util.ExternalSpecifications;
 35  
 import org.apache.myfaces.view.facelets.AbstractFaceletContext;
 36  
 
 37  
 /**
 38  
  * Handles parsing EL Strings in accordance with the EL-API Specification.
 39  
  * The parser accepts either <code>${..}</code>
 40  
  * or <code>#{..}</code>.
 41  
  * 
 42  
  * @author Jacob Hookom
 43  
  * @version $Id$
 44  
  */
 45  
 public class ELText
 46  
 {
 47  
 
 48  
     private static final class LiteralValueExpression extends ValueExpression
 49  
     {
 50  
 
 51  
         /**
 52  
          * 
 53  
          */
 54  
         private static final long serialVersionUID = 1L;
 55  
 
 56  
         private final String text;
 57  
 
 58  
         public LiteralValueExpression(String text)
 59  0
         {
 60  0
             this.text = text;
 61  0
         }
 62  
 
 63  
         public boolean isLiteralText()
 64  
         {
 65  0
             return false;
 66  
         }
 67  
 
 68  
         public int hashCode()
 69  
         {
 70  0
             return 0;
 71  
         }
 72  
 
 73  
         public String getExpressionString()
 74  
         {
 75  0
             return this.text;
 76  
         }
 77  
 
 78  
         public boolean equals(Object obj)
 79  
         {
 80  0
             return false;
 81  
         }
 82  
 
 83  
         public void setValue(ELContext context, Object value)
 84  
         {
 85  0
         }
 86  
 
 87  
         public boolean isReadOnly(ELContext context)
 88  
         {
 89  0
             return false;
 90  
         }
 91  
 
 92  
         public Object getValue(ELContext context)
 93  
         {
 94  0
             return null;
 95  
         }
 96  
 
 97  
         public Class<?> getType(ELContext context)
 98  
         {
 99  0
             return null;
 100  
         }
 101  
 
 102  
         public Class<?> getExpectedType()
 103  
         {
 104  0
             return null;
 105  
         }
 106  
 
 107  
     }
 108  
 
 109  
     private static final class ELTextComposite extends ELText
 110  
     {
 111  
         private final ELText[] txt;
 112  
 
 113  
         public ELTextComposite(ELText[] txt)
 114  
         {
 115  0
             super(null);
 116  0
             this.txt = txt;
 117  0
         }
 118  
 
 119  
         public void write(Writer out, ELContext ctx) throws ELException, IOException
 120  
         {
 121  0
             for (int i = 0; i < this.txt.length; i++)
 122  
             {
 123  0
                 this.txt[i].write(out, ctx);
 124  
             }
 125  0
         }
 126  
 
 127  
         public void writeText(ResponseWriter out, ELContext ctx) throws ELException, IOException
 128  
         {
 129  0
             for (int i = 0; i < this.txt.length; i++)
 130  
             {
 131  0
                 this.txt[i].writeText(out, ctx);
 132  
             }
 133  0
         }
 134  
 
 135  
         public String toString(ELContext ctx)
 136  
         {
 137  0
             StringBuffer sb = new StringBuffer();
 138  0
             for (int i = 0; i < this.txt.length; i++)
 139  
             {
 140  0
                 sb.append(this.txt[i].toString(ctx));
 141  
             }
 142  0
             return sb.toString();
 143  
         }
 144  
 
 145  
         /*
 146  
          * public String toString(ELContext ctx) { StringBuffer sb = new StringBuffer(); for (int i = 0; i <
 147  
          * this.txt.length; i++) { sb.append(this.txt[i].toString(ctx)); } return sb.toString(); }
 148  
          */
 149  
 
 150  
         public String toString()
 151  
         {
 152  0
             StringBuffer sb = new StringBuffer();
 153  0
             for (int i = 0; i < this.txt.length; i++)
 154  
             {
 155  0
                 sb.append(this.txt[i].toString());
 156  
             }
 157  0
             return sb.toString();
 158  
         }
 159  
 
 160  
         public boolean isLiteral()
 161  
         {
 162  0
             return false;
 163  
         }
 164  
 
 165  
         public ELText apply(ExpressionFactory factory, ELContext ctx)
 166  
         {
 167  0
             int len = this.txt.length;
 168  0
             ELText[] nt = new ELText[len];
 169  0
             for (int i = 0; i < len; i++)
 170  
             {
 171  0
                 nt[i] = this.txt[i].apply(factory, ctx);
 172  
             }
 173  0
             return new ELTextComposite(nt);
 174  
         }
 175  
     }
 176  
 
 177  0
     private static final class ELTextVariable extends ELText
 178  
     {
 179  
         private final ValueExpression ve;
 180  
 
 181  
         public ELTextVariable(ValueExpression ve)
 182  
         {
 183  0
             super(ve.getExpressionString());
 184  0
             this.ve = ve;
 185  0
         }
 186  
 
 187  
         public boolean isLiteral()
 188  
         {
 189  0
             return false;
 190  
         }
 191  
 
 192  
         public ELText apply(ExpressionFactory factory, ELContext ctx)
 193  
         {
 194  0
             return new ELTextVariable(factory.createValueExpression(ctx, this.ve.getExpressionString(), String.class));
 195  
         }
 196  
 
 197  
         public void write(Writer out, ELContext ctx) throws ELException, IOException
 198  
         {
 199  0
             Object v = this.ve.getValue(ctx);
 200  0
             if (v != null)
 201  
             {
 202  0
                 out.write((String) v);
 203  
             }
 204  0
         }
 205  
 
 206  
         public String toString(ELContext ctx) throws ELException
 207  
         {
 208  0
             Object v = this.ve.getValue(ctx);
 209  0
             if (v != null)
 210  
             {
 211  0
                 return v.toString();
 212  
             }
 213  
 
 214  0
             return null;
 215  
         }
 216  
 
 217  
         public void writeText(ResponseWriter out, ELContext ctx) throws ELException, IOException
 218  
         {
 219  0
             Object v = this.ve.getValue(ctx);
 220  0
             if (v != null)
 221  
             {
 222  0
                 out.writeText((String) v, null);
 223  
             }
 224  0
         }
 225  
     }
 226  
     
 227  
     private static final class ELCacheableTextVariable extends ELText
 228  
     {
 229  
         private final ValueExpression ve;
 230  
         
 231  
         //Just like TagAttributeImpl
 232  
         private final static int EL_CC = 2;
 233  
         
 234  
         private final static int EL_RESOURCE = 8;
 235  
         
 236  
         private final int capabilities;
 237  
         
 238  
         private volatile ELTextVariable cached;
 239  
         
 240  
         public ELCacheableTextVariable(ValueExpression ve)
 241  
         {
 242  0
             super(ve.getExpressionString());
 243  0
             this.ve = ve;
 244  0
             boolean compositeComponentExpression
 245  
                     = CompositeComponentELUtils.isCompositeComponentExpression(ve.getExpressionString());
 246  0
             boolean resourceExpression = ResourceELUtils.isResourceExpression(ve.getExpressionString());
 247  0
             this.capabilities = (compositeComponentExpression ? EL_CC : 0) | ( resourceExpression ? EL_RESOURCE : 0);
 248  0
         }
 249  
 
 250  
         public boolean isLiteral()
 251  
         {
 252  0
             return false;
 253  
         }
 254  
 
 255  
         public ELText apply(ExpressionFactory factory, ELContext ctx)
 256  
         {
 257  0
             AbstractFaceletContext actx = (AbstractFaceletContext) ctx;
 258  
             
 259  0
             if (actx.isAllowCacheELExpressions() && cached != null)
 260  
             {
 261  
                 // In TagAttributeImpl.getValueExpression(), it is necessary to do an
 262  
                 // special logic to detect the cases where #{cc} is included into the
 263  
                 // EL expression and set the proper ccLevel. In this case, it is usual
 264  
                 // the parent composite component is always on top, but it is possible to
 265  
                 // write a nesting case with <composite:insertChildren>, and
 266  
                 // pass a flat EL expression over itself. So, it is necessary to update
 267  
                 // the ccLevel to make possible to find the right parent where this 
 268  
                 // expression belongs to.
 269  0
                 if ((this.capabilities & EL_CC) != 0)
 270  
                 {
 271  0
                     UIComponent cc = actx.getFaceletCompositionContext().getCompositeComponentFromStack();
 272  0
                     if (cc != null)
 273  
                     {
 274  0
                         Location location = (Location) cc.getAttributes().get(CompositeComponentELUtils.LOCATION_KEY);
 275  0
                         if (location != null)
 276  
                         {
 277  0
                             return new ELTextVariable(((LocationValueExpression)cached.ve).apply(
 278  
                                     actx.getFaceletCompositionContext().getCompositeComponentLevel(), location));
 279  
                         }
 280  
                     }
 281  0
                     return new ELTextVariable(((LocationValueExpression)cached.ve).apply(
 282  
                             actx.getFaceletCompositionContext().getCompositeComponentLevel()));
 283  
                 }
 284  0
                 return cached;
 285  
             }
 286  
             
 287  0
             actx.beforeConstructELExpression();
 288  
             try
 289  
             {
 290  0
                 ValueExpression valueExpression
 291  
                         = factory.createValueExpression(ctx, this.ve.getExpressionString(), String.class);
 292  
               
 293  0
                 if ((this.capabilities & EL_CC) != 0)
 294  
                 {
 295  0
                     UIComponent cc = actx.getFaceletCompositionContext().getCompositeComponentFromStack();
 296  0
                     if (cc != null)
 297  
                     {
 298  0
                         Location location = (Location) cc.getAttributes().get(CompositeComponentELUtils.LOCATION_KEY);
 299  0
                         if (location != null)
 300  
                         {
 301  0
                             if (ExternalSpecifications.isUnifiedELAvailable())
 302  
                             {
 303  0
                                 valueExpression = new LocationValueExpressionUEL(location, valueExpression,
 304  
                                         actx.getFaceletCompositionContext().getCompositeComponentLevel());
 305  
                             }
 306  
                             else
 307  
                             {
 308  0
                                 valueExpression = new LocationValueExpression(location, valueExpression,
 309  
                                         actx.getFaceletCompositionContext().getCompositeComponentLevel());
 310  
                             }
 311  
                         }
 312  
                     }
 313  0
                 }
 314  0
                 else if ((this.capabilities & EL_RESOURCE) != 0)
 315  
                 {
 316  0
                     UIComponent cc = actx.getFaceletCompositionContext().getCompositeComponentFromStack();
 317  0
                     if (cc != null)
 318  
                     {
 319  0
                         Location location = (Location) cc.getAttributes().get(CompositeComponentELUtils.LOCATION_KEY);
 320  0
                         if (location != null)
 321  
                         {
 322  0
                             if (ExternalSpecifications.isUnifiedELAvailable())
 323  
                             {
 324  0
                                 valueExpression = new ResourceLocationValueExpressionUEL(location, valueExpression);
 325  
                             }
 326  
                             else
 327  
                             {
 328  0
                                 valueExpression = new ResourceLocationValueExpression(location, valueExpression);
 329  
                             }
 330  
                         }
 331  
                     }
 332  
                 }
 333  
                 
 334  0
                 ELTextVariable eltv = new ELTextVariable(valueExpression);
 335  
                 
 336  0
                 if (actx.isAllowCacheELExpressions() && !actx.isAnyFaceletsVariableResolved())
 337  
                 {
 338  0
                      cached = eltv;
 339  
                 }
 340  0
                 return eltv;
 341  
             }
 342  
             finally
 343  
             {
 344  0
                 actx.afterConstructELExpression();
 345  
             }
 346  
         }
 347  
 
 348  
         public void write(Writer out, ELContext ctx) throws ELException, IOException
 349  
         {
 350  0
             Object v = this.ve.getValue(ctx);
 351  0
             if (v != null)
 352  
             {
 353  0
                 out.write((String) v);
 354  
             }
 355  0
         }
 356  
 
 357  
         public String toString(ELContext ctx) throws ELException
 358  
         {
 359  0
             Object v = this.ve.getValue(ctx);
 360  0
             if (v != null)
 361  
             {
 362  0
                 return v.toString();
 363  
             }
 364  
 
 365  0
             return null;
 366  
         }
 367  
 
 368  
         public void writeText(ResponseWriter out, ELContext ctx) throws ELException, IOException
 369  
         {
 370  0
             Object v = this.ve.getValue(ctx);
 371  0
             if (v != null)
 372  
             {
 373  0
                 out.writeText((String) v, null);
 374  
             }
 375  0
         }
 376  
     }
 377  
 
 378  
     protected final String literal;
 379  
 
 380  
     public ELText(String literal)
 381  0
     {
 382  0
         this.literal = literal;
 383  0
     }
 384  
 
 385  
     /**
 386  
      * If it's literal text
 387  
      * 
 388  
      * @return true if the String is literal (doesn't contain <code>#{..}</code> or <code>${..}</code>)
 389  
      */
 390  
     public boolean isLiteral()
 391  
     {
 392  0
         return true;
 393  
     }
 394  
 
 395  
     /**
 396  
      * Return an instance of <code>this</code> that is applicable given the ELContext and ExpressionFactory state.
 397  
      * 
 398  
      * @param factory
 399  
      *            the ExpressionFactory to use
 400  
      * @param ctx
 401  
      *            the ELContext to use
 402  
      * @return an ELText instance
 403  
      */
 404  
     public ELText apply(ExpressionFactory factory, ELContext ctx)
 405  
     {
 406  0
         return this;
 407  
     }
 408  
 
 409  
     /**
 410  
      * Allow this instance to write to the passed Writer, given the ELContext state
 411  
      * 
 412  
      * @param out
 413  
      *            Writer to write to
 414  
      * @param ctx
 415  
      *            current ELContext state
 416  
      * @throws ELException
 417  
      * @throws IOException
 418  
      */
 419  
     public void write(Writer out, ELContext ctx) throws ELException, IOException
 420  
     {
 421  0
         out.write(this.literal);
 422  0
     }
 423  
 
 424  
     public void writeText(ResponseWriter out, ELContext ctx) throws ELException, IOException
 425  
     {
 426  0
         out.writeText(this.literal, null);
 427  0
     }
 428  
 
 429  
     /**
 430  
      * Evaluates the ELText to a String
 431  
      * 
 432  
      * @param ctx
 433  
      *            current ELContext state
 434  
      * @throws ELException
 435  
      * @return the evaluated String
 436  
      */
 437  
     public String toString(ELContext ctx) throws ELException
 438  
     {
 439  0
         return this.literal;
 440  
     }
 441  
 
 442  
     public String toString()
 443  
     {
 444  0
         return this.literal;
 445  
     }
 446  
 
 447  
     /**
 448  
      * Parses the passed string to determine if it's literal or not
 449  
      * 
 450  
      * @param in
 451  
      *            input String
 452  
      * @return true if the String is literal (doesn't contain <code>#{..}</code> or <code>${..}</code>)
 453  
      */
 454  
     public static boolean isLiteral(String in)
 455  
     {
 456  
         //ELText txt = parse(in);
 457  
         //return txt == null || txt.isLiteral();
 458  0
         return isLiteral(null, null, in);
 459  
     }
 460  
 
 461  
     /**
 462  
      * Factory method for creating an unvalidated ELText instance. NOTE: All expressions in the passed String are
 463  
      * treated as {@link org.apache.myfaces.view.facelets.el.LiteralValueExpression LiteralValueExpressions}.
 464  
      * 
 465  
      * @param in
 466  
      *            String to parse
 467  
      * @return ELText instance that knows if the String was literal or not
 468  
      * @throws javax.el.ELException
 469  
      */
 470  
     public static ELText parse(String in) throws ELException
 471  
     {
 472  0
         return parse(null, null, in);
 473  
     }
 474  
     
 475  
     public static ELText parseAllowEmptyString(String in) throws ELException
 476  
     {
 477  0
         if (in != null && in.length() == 0)
 478  
         {
 479  0
             return new ELText(in);
 480  
         }
 481  
         else
 482  
         {
 483  0
             return parse(null, null, in);
 484  
         }
 485  
     }
 486  
 
 487  
     /**
 488  
      * Factory method for creating a validated ELText instance. When an Expression is hit, it will use the
 489  
      * ExpressionFactory to create a ValueExpression instance, resolving any functions at that time. <p/> Variables and
 490  
      * properties will not be evaluated.
 491  
      * 
 492  
      * @param fact
 493  
      *            ExpressionFactory to use
 494  
      * @param ctx
 495  
      *            ELContext to validate against
 496  
      * @param in
 497  
      *            String to parse
 498  
      * @return ELText that can be re-applied later
 499  
      * @throws javax.el.ELException
 500  
      */
 501  
     public static ELText parse(ExpressionFactory fact, ELContext ctx, String in) throws ELException
 502  
     {
 503  0
         char[] ca = in.toCharArray();
 504  0
         int i = 0;
 505  0
         char c = 0;
 506  0
         int len = ca.length;
 507  0
         int end = len - 1;
 508  0
         boolean esc = false;
 509  0
         int vlen = 0;
 510  
 
 511  0
         StringBuffer buff = new StringBuffer(128);
 512  0
         List<ELText> text = new ArrayList<ELText>();
 513  0
         ELText t = null;
 514  0
         ValueExpression ve = null;
 515  
 
 516  0
         while (i < len)
 517  
         {
 518  0
             c = ca[i];
 519  0
             if ('\\' == c)
 520  
             {
 521  0
                 esc = !esc;
 522  0
                 if (esc && i < end && (ca[i + 1] == '$' || ca[i + 1] == '#'))
 523  
                 {
 524  0
                     i++;
 525  0
                     continue;
 526  
                 }
 527  
             }
 528  0
             else if (!esc && ('$' == c || '#' == c))
 529  
             {
 530  0
                 if (i < end)
 531  
                 {
 532  0
                     if ('{' == ca[i + 1])
 533  
                     {
 534  0
                         if (buff.length() > 0)
 535  
                         {
 536  0
                             text.add(new ELText(buff.toString()));
 537  0
                             buff.setLength(0);
 538  
                         }
 539  0
                         vlen = findVarLength(ca, i);
 540  0
                         if (ctx != null && fact != null)
 541  
                         {
 542  0
                             ve = fact.createValueExpression(ctx, new String(ca, i, vlen), String.class);
 543  0
                             t = new ELCacheableTextVariable(ve);
 544  
                         }
 545  
                         else
 546  
                         {
 547  0
                             t = new ELCacheableTextVariable(new LiteralValueExpression(new String(ca, i, vlen)));
 548  
                         }
 549  0
                         text.add(t);
 550  0
                         i += vlen;
 551  0
                         continue;
 552  
                     }
 553  
                 }
 554  
             }
 555  0
             esc = false;
 556  0
             buff.append(c);
 557  0
             i++;
 558  
         }
 559  
 
 560  0
         if (buff.length() > 0)
 561  
         {
 562  0
             text.add(new ELText(buff.toString()));
 563  0
             buff.setLength(0);
 564  
         }
 565  
 
 566  0
         if (text.size() == 0)
 567  
         {
 568  0
             return null;
 569  
         }
 570  0
         else if (text.size() == 1)
 571  
         {
 572  0
             return (ELText) text.get(0);
 573  
         }
 574  
         else
 575  
         {
 576  0
             ELText[] ta = (ELText[]) text.toArray(new ELText[text.size()]);
 577  0
             return new ELTextComposite(ta);
 578  
         }
 579  
     }
 580  
 
 581  
     public static ELText[] parseAsArray(String in) throws ELException
 582  
     {
 583  0
         return parseAsArray(null, null, in);
 584  
     }
 585  
     
 586  
     public static ELText[] parseAsArray(ExpressionFactory fact, ELContext ctx, String in) throws ELException
 587  
     {
 588  0
         char[] ca = in.toCharArray();
 589  0
         int i = 0;
 590  0
         char c = 0;
 591  0
         int len = ca.length;
 592  0
         int end = len - 1;
 593  0
         boolean esc = false;
 594  0
         int vlen = 0;
 595  
 
 596  0
         StringBuffer buff = new StringBuffer(128);
 597  0
         List<ELText> text = new ArrayList<ELText>();
 598  0
         ELText t = null;
 599  0
         ValueExpression ve = null;
 600  
 
 601  0
         while (i < len)
 602  
         {
 603  0
             c = ca[i];
 604  0
             if ('\\' == c)
 605  
             {
 606  0
                 esc = !esc;
 607  0
                 if (esc && i < end && (ca[i + 1] == '$' || ca[i + 1] == '#'))
 608  
                 {
 609  0
                     i++;
 610  0
                     continue;
 611  
                 }
 612  
             }
 613  0
             else if (!esc && ('$' == c || '#' == c))
 614  
             {
 615  0
                 if (i < end)
 616  
                 {
 617  0
                     if ('{' == ca[i + 1])
 618  
                     {
 619  0
                         if (buff.length() > 0)
 620  
                         {
 621  0
                             text.add(new ELText(buff.toString()));
 622  0
                             buff.setLength(0);
 623  
                         }
 624  0
                         vlen = findVarLength(ca, i);
 625  0
                         if (ctx != null && fact != null)
 626  
                         {
 627  0
                             ve = fact.createValueExpression(ctx, new String(ca, i, vlen), String.class);
 628  0
                             t = new ELCacheableTextVariable(ve);
 629  
                         }
 630  
                         else
 631  
                         {
 632  0
                             t = new ELCacheableTextVariable(new LiteralValueExpression(new String(ca, i, vlen)));
 633  
                         }
 634  0
                         text.add(t);
 635  0
                         i += vlen;
 636  0
                         continue;
 637  
                     }
 638  
                 }
 639  
             }
 640  0
             esc = false;
 641  0
             buff.append(c);
 642  0
             i++;
 643  
         }
 644  
 
 645  0
         if (buff.length() > 0)
 646  
         {
 647  0
             text.add(new ELText(buff.toString()));
 648  0
             buff.setLength(0);
 649  
         }
 650  
 
 651  0
         if (text.size() == 0)
 652  
         {
 653  0
             return null;
 654  
         }
 655  0
         else if (text.size() == 1)
 656  
         {
 657  0
             return new ELText[]{text.get(0)};
 658  
         }
 659  
         else
 660  
         {
 661  0
             ELText[] ta = (ELText[]) text.toArray(new ELText[text.size()]);
 662  0
             return ta;
 663  
         }
 664  
     }
 665  
     
 666  
     public static boolean isLiteral(ExpressionFactory fact, ELContext ctx, String in) throws ELException
 667  
     {
 668  0
         char[] ca = in.toCharArray();
 669  0
         int i = 0;
 670  0
         char c = 0;
 671  0
         int len = ca.length;
 672  0
         int end = len - 1;
 673  0
         boolean esc = false;
 674  
         //int vlen = 0;
 675  
 
 676  0
         while (i < len)
 677  
         {
 678  0
             c = ca[i];
 679  0
             if ('\\' == c)
 680  
             {
 681  0
                 esc = !esc;
 682  0
                 if (esc && i < end && (ca[i + 1] == '$' || ca[i + 1] == '#'))
 683  
                 {
 684  0
                     i++;
 685  0
                     continue;
 686  
                 }
 687  
             }
 688  0
             else if (!esc && ('$' == c || '#' == c))
 689  
             {
 690  0
                 if (i < end)
 691  
                 {
 692  0
                     if ('{' == ca[i + 1])
 693  
                     {
 694  
                         //vlen = findVarLength(ca, i);
 695  
                         //In this point we have at least 1 EL expression, so it is not literal
 696  0
                         return false;
 697  
                     }
 698  
                 }
 699  
             }
 700  0
             esc = false;
 701  0
             i++;
 702  
         }
 703  0
         return true;
 704  
     }
 705  
 
 706  
     private static int findVarLength(char[] ca, int s) throws ELException
 707  
     {
 708  0
         int i = s;
 709  0
         int len = ca.length;
 710  0
         char c = 0;
 711  0
         int str = 0;
 712  0
         int nest = 0;
 713  0
         while (i < len)
 714  
         {
 715  0
             c = ca[i];
 716  0
             if ('\\' == c && i < len - 1)
 717  
             {
 718  0
                 i++;
 719  
             }
 720  0
             else if ('\'' == c || '"' == c)
 721  
             {
 722  0
                 if (str == c)
 723  
                 {
 724  0
                     str = 0;
 725  
                 }
 726  
                 else
 727  
                 {
 728  0
                     str = c;
 729  
                 }
 730  
             }
 731  0
             else if ('{' == c && str == 0)
 732  
             {
 733  0
                 ++nest;
 734  
             }
 735  0
             else if ('}' == c && str == 0 && nest > 1)
 736  
             {
 737  0
                 --nest;
 738  
             }
 739  0
             else if (str == 0 && ('}' == c && nest == 1))
 740  
             {
 741  0
                 return i - s + 1;
 742  
             }
 743  0
             i++;
 744  
         }
 745  0
         throw new ELException("EL Expression Unbalanced: ... " + new String(ca, s, i - s));
 746  
     }
 747  
 
 748  
 }