AttributeValueTemplatepublic final class AttributeValueTemplate extends AttributeValue
Fields Summary |
---|
static final int | OUT_EXPR | static final int | IN_EXPR | static final int | IN_EXPR_SQUOTES | static final int | IN_EXPR_DQUOTES | static final String | DELIMITER |
Constructors Summary |
---|
public AttributeValueTemplate(String value, Parser parser, SyntaxTreeNode parent) // A Unicode nonchar
setParent(parent);
setParser(parser);
try {
parseAVTemplate(value, parser);
}
catch (NoSuchElementException e) {
reportError(parent, parser,
ErrorMsg.ATTR_VAL_TEMPLATE_ERR, value);
}
|
Methods Summary |
---|
private void | parseAVTemplate(java.lang.String text, com.sun.org.apache.xalan.internal.xsltc.compiler.Parser parser)Two-pass parsing of ATVs. In the first pass, double curly braces are
replaced by one, and expressions are delimited using DELIMITER. The
second pass splits up the resulting buffer into literal and non-literal
expressions. Errors are reported during the first pass.
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));
}
}
| public java.lang.String | toString()
final StringBuffer buffer = new StringBuffer("AVT:[");
final int count = elementCount();
for (int i = 0; i < count; i++) {
buffer.append(elementAt(i).toString());
if (i < count - 1)
buffer.append(' ");
}
return buffer.append(']").toString();
| public void | translate(com.sun.org.apache.xalan.internal.xsltc.compiler.util.ClassGenerator classGen, com.sun.org.apache.xalan.internal.xsltc.compiler.util.MethodGenerator methodGen)
if (elementCount() == 1) {
final Expression exp = (Expression)elementAt(0);
exp.translate(classGen, methodGen);
}
else {
final ConstantPoolGen cpg = classGen.getConstantPool();
final InstructionList il = methodGen.getInstructionList();
final int initBuffer = cpg.addMethodref(STRING_BUFFER_CLASS,
"<init>", "()V");
final Instruction append =
new INVOKEVIRTUAL(cpg.addMethodref(STRING_BUFFER_CLASS,
"append",
"(" + STRING_SIG + ")"
+ STRING_BUFFER_SIG));
final int toString = cpg.addMethodref(STRING_BUFFER_CLASS,
"toString",
"()"+STRING_SIG);
il.append(new NEW(cpg.addClass(STRING_BUFFER_CLASS)));
il.append(DUP);
il.append(new INVOKESPECIAL(initBuffer));
// StringBuffer is on the stack
final Enumeration elements = elements();
while (elements.hasMoreElements()) {
final Expression exp = (Expression)elements.nextElement();
exp.translate(classGen, methodGen);
il.append(append);
}
il.append(new INVOKEVIRTUAL(toString));
}
| public com.sun.org.apache.xalan.internal.xsltc.compiler.util.Type | typeCheck(com.sun.org.apache.xalan.internal.xsltc.compiler.SymbolTable stable)
final Vector contents = getContents();
final int n = contents.size();
for (int i = 0; i < n; i++) {
final Expression exp = (Expression)contents.elementAt(i);
if (!exp.typeCheck(stable).identicalTo(Type.String)) {
contents.setElementAt(new CastExpr(exp, Type.String), i);
}
}
return _type = Type.String;
|
|