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();
}
}
}
}
}