in geronimo-mail_2.1_spec/src/main/java/jakarta/mail/internet/AddressParser.java [492:570]
private AddressToken scanRouteAddress(final TokenStream tokens, final boolean inGroup) throws AddressException {
// get the first token and ensure we have something between the "<" and ">".
AddressToken token = tokens.nextRealToken();
// the last processed non-whitespace token, which is the actual address end once the
// right angle bracket is encountered.
AddressToken previous = null;
// if this route-addr has route information, the first token after the '<' must be a '@'.
// this determines if/where a colon or comma can appear.
boolean inRoute = token.type == AT_SIGN;
// now scan until we reach the terminator. The only validation is done on illegal characters.
while (true) {
switch (token.type) {
// The following tokens are all valid between the brackets, so just skip over them.
case ATOM:
case QUOTED_LITERAL:
case DOMAIN_LITERAL:
case PERIOD:
case AT_SIGN:
break;
case COLON:
// if not processing route information, this is illegal.
if (!inRoute) {
illegalAddress("Unexpected ':'", token);
}
// this is the end of the route information, the rules now change.
inRoute = false;
break;
case COMMA:
// if not processing route information, this is illegal.
if (!inRoute) {
illegalAddress("Unexpected ','", token);
}
break;
case RIGHT_ANGLE:
// if previous is null, we've had a route address which is "<>". That's illegal.
if (previous == null) {
illegalAddress("Illegal address", token);
}
// step to the next token..this had better be either a comma for another address or
// the very end of the address list .
token = tokens.nextRealToken();
// if we're scanning part of a group, then the allowed terminators are either ',' or ';'.
if (inGroup) {
if (token.type != COMMA && token.type != SEMICOLON) {
illegalAddress("Illegal address", token);
}
}
// a normal address should have either a ',' for a list or the end.
else {
if (token.type != COMMA && token.type != END_OF_TOKENS) {
illegalAddress("Illegal address", token);
}
}
// we need to push the termination token back on.
tokens.pushToken(token);
// return the previous token as the updated position.
return previous;
case END_OF_TOKENS:
illegalAddress("Missing '>'", token);
// now for the illegal ones in this context.
case SEMICOLON:
illegalAddress("Unexpected ';'", token);
case LEFT_ANGLE:
illegalAddress("Unexpected '<'", token);
}
// remember the previous token.
previous = token;
token = tokens.nextRealToken();
}
}