public int read()

in deltaspike/modules/jsf/api/src/main/java/org/apache/deltaspike/jsf/util/ValueExpressionEvaluationInputStream.java [63:165]


    public int read() throws IOException
    {
        // check for a current value
        if (currentValueIndex != -1)
        {
            if (currentValueIndex < currentValue.length())
            {
                return currentValue.charAt(currentValueIndex++);
            }
            else
            {
                // current value exhausted, reset index
                currentValueIndex = -1;
            }
        }

        // read byte and check for value expression begin
        int c1 = wrapped.read();
        if (c1 != '#')
        {
            return c1;  // can't be a value expression, just return the character
        }
        else
        {
            // could be a value expression, next character must be '{'
            int c2 = wrapped.read();
            if (c2 != '{')
            {
                wrapped.unread(c2);  // we did not find a value expression, unread byte that we read too much
                return c1;   // return original character
            }
            else
            {
                // read until '}', '\n' or eof occurs (end of value expression or data)
                List<Integer> possibleValueExpression = new LinkedList<Integer>();
                int c = wrapped.read();
                boolean insideString = (c == '\'');  // a '}' inside a string must not terminate the expression string
                while (c != -1 && c != '\n' && (insideString || c != '}'))
                {
                    possibleValueExpression.add(c);
                    c = wrapped.read();
                    if (c == '\'')
                    {
                        insideString = !insideString;
                    }
                }

                if (c != '}')
                {
                    // we did not find a value expression, unread bytes that we read too much (in reverse order)
                    if (c != -1)  // we can't unread eof
                    {
                        wrapped.unread(c);
                    }
                    ListIterator<Integer> it = possibleValueExpression.listIterator(possibleValueExpression.size());
                    while (it.hasPrevious())
                    {
                        wrapped.unread(it.previous());
                    }
                    wrapped.unread(c2);
                    return c1; // return original character
                }
                else
                {
                    // we found a value expression #{xxx} (xxx is stored in possibleValueExpression)
                    // create the expression string
                    String expressionString = createExpressionString(possibleValueExpression);

                    // evaluate it
                    String expressionValue = facesContext.getApplication()
                            .evaluateExpressionGet(facesContext, expressionString, String.class);

                    if (expressionValue == null)
                    {
                        if (log.isLoggable(Level.WARNING))
                        {
                            log.warning("ValueExpression " + expressionString + " evaluated to null.");
                        }

                        expressionValue = "null";  // fallback value for null
                    }

                    // do NOT unread the evaluated value, but rather store it in an internal buffer,
                    // because otherwise we could recursively evaluate value expressions (a value expression
                    // that resolves to a string containing "#{...}" would be re-evaluated).
                    this.currentValue = expressionValue;

                    // return first character of currentValue, if exists (not an empty string)
                    if (currentValue.length() != 0)
                    {
                        this.currentValueIndex = 0;
                        return currentValue.charAt(currentValueIndex++);
                    }
                    else  // currentValue is an empty string
                    {
                        // in this case we must recursively start a new read (incl. checks for a new value expression)
                        this.currentValueIndex = -1;
                        return read();
                    }
                }
            }
        }
    }