in xalan/src/main/java/org/apache/xalan/xsltc/compiler/AttributeValueTemplate.java [74:204]
private void parseAVTemplate(String text, Parser parser) {
StringTokenizer tokenizer =
new StringTokenizer(text, "{}\"\'", true);
/*
* First pass: replace double curly braces and delimit expressions
* Simple automaton to parse ATVs, delimit expressions and report
* errors.
*/
String t = null;
String lookahead = null;
StringBuffer buffer = new StringBuffer();
int state = OUT_EXPR;
while (tokenizer.hasMoreTokens()) {
// Use lookahead if available
if (lookahead != null) {
t = lookahead;
lookahead = null;
}
else {
t = tokenizer.nextToken();
}
if (t.length() == 1) {
switch (t.charAt(0)) {
case '{':
switch (state) {
case OUT_EXPR:
lookahead = tokenizer.nextToken();
if (lookahead.equals("{")) {
buffer.append(lookahead); // replace {{ by {
lookahead = null;
}
else {
buffer.append(DELIMITER);
state = IN_EXPR;
}
break;
case IN_EXPR:
case IN_EXPR_SQUOTES:
case IN_EXPR_DQUOTES:
reportError(getParent(), parser,
ErrorMsg.ATTR_VAL_TEMPLATE_ERR, text);
break;
}
break;
case '}':
switch (state) {
case OUT_EXPR:
lookahead = tokenizer.nextToken();
if (lookahead.equals("}")) {
buffer.append(lookahead); // replace }} by }
lookahead = null;
}
else {
reportError(getParent(), parser,
ErrorMsg.ATTR_VAL_TEMPLATE_ERR, text);
}
break;
case IN_EXPR:
buffer.append(DELIMITER);
state = OUT_EXPR;
break;
case IN_EXPR_SQUOTES:
case IN_EXPR_DQUOTES:
buffer.append(t);
break;
}
break;
case '\'':
switch (state) {
case IN_EXPR:
state = IN_EXPR_SQUOTES;
break;
case IN_EXPR_SQUOTES:
state = IN_EXPR;
break;
case OUT_EXPR:
case IN_EXPR_DQUOTES:
break;
}
buffer.append(t);
break;
case '\"':
switch (state) {
case IN_EXPR:
state = IN_EXPR_DQUOTES;
break;
case IN_EXPR_DQUOTES:
state = IN_EXPR;
break;
case OUT_EXPR:
case IN_EXPR_SQUOTES:
break;
}
buffer.append(t);
break;
default:
buffer.append(t);
break;
}
}
else {
buffer.append(t);
}
}
// Must be in OUT_EXPR at the end of parsing
if (state != OUT_EXPR) {
reportError(getParent(), parser,
ErrorMsg.ATTR_VAL_TEMPLATE_ERR, text);
}
/*
* Second pass: split up buffer into literal and non-literal expressions.
*/
tokenizer = new StringTokenizer(buffer.toString(), DELIMITER, true);
while (tokenizer.hasMoreTokens()) {
t = tokenizer.nextToken();
if (t.equals(DELIMITER)) {
addElement(parser.parseExpression(this, tokenizer.nextToken()));
tokenizer.nextToken(); // consume other delimiter
}
else {
addElement(new LiteralExpr(t));
}
}
}