in juneau-core/juneau-marshall/src/main/java/org/apache/juneau/uon/UonParserSession.java [542:629]
private <E> Collection<E> parseIntoCollection(UonReader r, Collection<E> l, ClassMeta<E> type, boolean isUrlParamValue, BeanPropertyMeta pMeta) throws IOException, ParseException, ExecutableException {
int c = r.readSkipWs();
if (c == -1 || c == AMP)
return null;
if (c == 'n')
return (Collection<E>)parseNull(r);
int argIndex = 0;
// If we're parsing a top-level parameter, we're allowed to have comma-delimited lists outside parenthesis (e.g. "&foo=1,2,3&bar=a,b,c")
// This is not allowed at lower levels since we use comma's as end delimiters.
boolean isInParens = (c == '@');
if (! isInParens) {
if (isUrlParamValue)
r.unread();
else
throw new ParseException(this, "Could not find '(' marking beginning of collection.");
} else {
r.read();
}
if (isInParens) {
final int S1=1; // Looking for starting of first entry.
final int S2=2; // Looking for starting of subsequent entries.
final int S3=3; // Looking for , or ) after first entry.
int state = S1;
while (c != -1 && c != AMP) {
c = r.read();
if (state == S1 || state == S2) {
if (c == ')') {
if (state == S2) {
l.add((E)parseAnything(type.isArgs() ? type.getArg(argIndex++) : type.getElementType(),
r.unread(), l, false, pMeta));
r.read();
}
return l;
} else if (Character.isWhitespace(c)) {
skipSpace(r);
} else {
l.add((E)parseAnything(type.isArgs() ? type.getArg(argIndex++) : type.getElementType(),
r.unread(), l, false, pMeta));
state = S3;
}
} else if (state == S3) {
if (c == ',') {
state = S2;
} else if (c == ')') {
return l;
}
}
}
if (state == S1 || state == S2)
throw new ParseException(this, "Could not find start of entry in array.");
if (state == S3)
throw new ParseException(this, "Could not find end of entry in array.");
} else {
final int S1=1; // Looking for starting of entry.
final int S2=2; // Looking for , or & or END after first entry.
int state = S1;
while (c != -1 && c != AMP) {
c = r.read();
if (state == S1) {
if (Character.isWhitespace(c)) {
skipSpace(r);
} else {
l.add((E)parseAnything(type.isArgs() ? type.getArg(argIndex++) : type.getElementType(),
r.unread(), l, false, pMeta));
state = S2;
}
} else if (state == S2) {
if (c == ',') {
state = S1;
} else if (Character.isWhitespace(c)) {
skipSpace(r);
} else if (c == AMP || c == -1) {
r.unread();
return l;
}
}
}
}
return null; // Unreachable.
}