in trinidad-api/src/main/java/org/apache/myfaces/trinidad/convert/RGBColorFormat.java [88:264]
public Object parseObject(
String text,
ParsePosition pos)
{
// do not attempt to parse null color string
if (text == null)
return null;
int start = pos.getIndex();
int oldStart = start;
boolean inQuote = false; // inQuote set true when hits 1st single quote
char prevCh = 0;
int count = 0;
int interQuoteCount = 1; // Number of chars between quotes
int[] rgba = new int[_FIELD_COUNT];
rgba[_ALPHA_FIELD] = 255; // default alpha to full (opaque)
for (int i=0; i < _pattern.length(); i++)
{
char ch = _pattern.charAt(i);
if (inQuote)
{
if (ch == '\'')
{
// ends with 2nd single quote
inQuote = false;
// two consecutive quotes outside a quote means we have
// a quote literal we need to match.
if (count == 0)
{
if (start >= text.length() || ch != text.charAt(start))
{
pos.setIndex(oldStart);
pos.setErrorIndex(start);
return null;
}
start++;
}
count = 0;
interQuoteCount = 0;
}
else
{
// pattern uses text following from 1st single quote.
if (start >= text.length() || ch != text.charAt(start))
{
// Check for cases like: 'at' in pattern vs "xt"
// in time text, where 'a' doesn't match with 'x'.
// If fail to match, return null.
pos.setIndex(oldStart); // left unchanged
pos.setErrorIndex(start);
return null;
}
count++;
start++;
}
}
else // !inQuote
{
if (ch == '\'')
{
inQuote = true;
if (count > 0) // handle cases like: e'at'
{
int startOffset = start;
start = _subParse(rgba, text, start, prevCh, count);
if (start < 0)
{
pos.setIndex(oldStart);
pos.setErrorIndex(startOffset);
return null;
}
count = 0;
}
if (interQuoteCount == 0)
{
// This indicates two consecutive quotes inside a quote,
// for example, 'o''clock'. We need to parse this as
// representing a single quote within the quote.
int startOffset = start;
if (start >= text.length() || ch != text.charAt(start))
{
pos.setIndex(oldStart);
pos.setErrorIndex(startOffset);
return null;
}
start++;
count = 1; // Make it look like we never left
}
}
else if (ch >= 'a' && ch <= 'z' || ch >= 'A' && ch <= 'Z')
{
// ch is a color pattern
if (ch != prevCh && count > 0) // e.g., rrr
{
int startOffset = start;
start = _subParse(rgba, text, start, prevCh, count);
if (start < 0)
{
pos.setIndex(oldStart);
pos.setErrorIndex(startOffset);
return null;
}
prevCh = ch;
count = 1;
}
else
{
if (ch != prevCh)
prevCh = ch;
count++;
}
}
else if (count > 0)
{
// handle cases like: "rrr,ggg,bbb", "RR.GG.BB", "r g b", etc
// where ch = ',', '.' or ' ', repectively.
int startOffset = start;
start = _subParse(rgba, text, start, prevCh, count);
if ( start < 0 )
{
pos.setIndex(oldStart);
pos.setErrorIndex(startOffset);
return null;
}
if (start >= text.length() || ch != text.charAt(start))
{
// handle cases like: 'RR g' in pattern vs. "FFx20"
// in color text, where ' ' doesn't match with 'x'.
pos.setIndex(oldStart);
pos.setErrorIndex(start);
return null;
}
start++;
count = 0;
prevCh = 0;
}
else // any other unquoted characters
{
if (start >= text.length() || ch != text.charAt(start))
{
// handle cases like: 'RR g' in pattern vs. "FF,,,20"
// in color text, where " " doesn't match with ",,,".
pos.setIndex(oldStart);
pos.setErrorIndex(start);
return null;
}
start++;
}
interQuoteCount++;
}
}
// Parse the last item in the pattern
if (count > 0)
{
int startOffset = start;
start = _subParse(rgba, text, start, prevCh, count);
if (start < 0)
{
pos.setIndex(oldStart);
pos.setErrorIndex(startOffset);
return null;
}
}
pos.setIndex(start);
return new Color(rgba[_RED_FIELD],
rgba[_GREEN_FIELD],
rgba[_BLUE_FIELD],
rgba[_ALPHA_FIELD]);
}