1 16 19 20 package com.sun.org.apache.xalan.internal.xsltc.compiler; 21 22 import java.util.Enumeration ; 23 import java.util.Vector ; 24 import java.util.StringTokenizer ; 25 import java.util.NoSuchElementException ; 26 27 28 import com.sun.org.apache.bcel.internal.generic.ConstantPoolGen; 29 import com.sun.org.apache.bcel.internal.generic.INVOKESPECIAL; 30 import com.sun.org.apache.bcel.internal.generic.INVOKEVIRTUAL; 31 import com.sun.org.apache.bcel.internal.generic.Instruction; 32 import com.sun.org.apache.bcel.internal.generic.InstructionList; 33 import com.sun.org.apache.bcel.internal.generic.NEW; 34 import com.sun.org.apache.xalan.internal.xsltc.compiler.util.ClassGenerator; 35 import com.sun.org.apache.xalan.internal.xsltc.compiler.util.ErrorMsg; 36 import com.sun.org.apache.xalan.internal.xsltc.compiler.util.MethodGenerator; 37 import com.sun.org.apache.xalan.internal.xsltc.compiler.util.Type; 38 import com.sun.org.apache.xalan.internal.xsltc.compiler.util.TypeCheckError; 39 40 44 final class AttributeValueTemplate extends AttributeValue { 45 46 final static int OUT_EXPR = 0; 47 final static int IN_EXPR = 1; 48 final static int IN_EXPR_SQUOTES = 2; 49 final static int IN_EXPR_DQUOTES = 3; 50 final static String DELIMITER = "\uFFFE"; 52 public AttributeValueTemplate(String value, Parser parser, 53 SyntaxTreeNode parent) 54 { 55 setParent(parent); 56 setParser(parser); 57 58 try { 59 parseAVTemplate(value, parser); 60 } 61 catch (NoSuchElementException e) { 62 reportError(parent, parser, 63 ErrorMsg.ATTR_VAL_TEMPLATE_ERR, value); 64 } 65 } 66 67 73 private void parseAVTemplate(String text, Parser parser) { 74 StringTokenizer tokenizer = 75 new StringTokenizer (text, "{}\"\'", true); 76 77 82 String t = null; 83 String lookahead = null; 84 StringBuffer buffer = new StringBuffer (); 85 int state = OUT_EXPR; 86 87 while (tokenizer.hasMoreTokens()) { 88 if (lookahead != null) { 90 t = lookahead; 91 lookahead = null; 92 } 93 else { 94 t = tokenizer.nextToken(); 95 } 96 97 if (t.length() == 1) { 98 switch (t.charAt(0)) { 99 case '{': 100 switch (state) { 101 case OUT_EXPR: 102 lookahead = tokenizer.nextToken(); 103 if (lookahead.equals("{")) { 104 buffer.append(lookahead); lookahead = null; 106 } 107 else { 108 buffer.append(DELIMITER); 109 state = IN_EXPR; 110 } 111 break; 112 case IN_EXPR: 113 case IN_EXPR_SQUOTES: 114 case IN_EXPR_DQUOTES: 115 reportError(getParent(), parser, 116 ErrorMsg.ATTR_VAL_TEMPLATE_ERR, text); 117 break; 118 } 119 break; 120 case '}': 121 switch (state) { 122 case OUT_EXPR: 123 lookahead = tokenizer.nextToken(); 124 if (lookahead.equals("}")) { 125 buffer.append(lookahead); lookahead = null; 127 } 128 else { 129 reportError(getParent(), parser, 130 ErrorMsg.ATTR_VAL_TEMPLATE_ERR, text); 131 } 132 break; 133 case IN_EXPR: 134 buffer.append(DELIMITER); 135 state = OUT_EXPR; 136 break; 137 case IN_EXPR_SQUOTES: 138 case IN_EXPR_DQUOTES: 139 buffer.append(t); 140 break; 141 } 142 break; 143 case '\'': 144 switch (state) { 145 case IN_EXPR: 146 state = IN_EXPR_SQUOTES; 147 break; 148 case IN_EXPR_SQUOTES: 149 state = IN_EXPR; 150 break; 151 case OUT_EXPR: 152 case IN_EXPR_DQUOTES: 153 break; 154 } 155 buffer.append(t); 156 break; 157 case '\"': 158 switch (state) { 159 case IN_EXPR: 160 state = IN_EXPR_DQUOTES; 161 break; 162 case IN_EXPR_DQUOTES: 163 state = IN_EXPR; 164 break; 165 case OUT_EXPR: 166 case IN_EXPR_SQUOTES: 167 break; 168 } 169 buffer.append(t); 170 break; 171 default: 172 buffer.append(t); 173 break; 174 } 175 } 176 else { 177 buffer.append(t); 178 } 179 } 180 181 if (state != OUT_EXPR) { 183 reportError(getParent(), parser, 184 ErrorMsg.ATTR_VAL_TEMPLATE_ERR, text); 185 } 186 187 190 tokenizer = new StringTokenizer (buffer.toString(), DELIMITER, true); 191 192 while (tokenizer.hasMoreTokens()) { 193 t = tokenizer.nextToken(); 194 195 if (t.equals(DELIMITER)) { 196 addElement(parser.parseExpression(this, tokenizer.nextToken())); 197 tokenizer.nextToken(); } 199 else { 200 addElement(new LiteralExpr(t)); 201 } 202 } 203 } 204 205 public Type typeCheck(SymbolTable stable) throws TypeCheckError { 206 final Vector contents = getContents(); 207 final int n = contents.size(); 208 for (int i = 0; i < n; i++) { 209 final Expression exp = (Expression)contents.elementAt(i); 210 if (!exp.typeCheck(stable).identicalTo(Type.String)) { 211 contents.setElementAt(new CastExpr(exp, Type.String), i); 212 } 213 } 214 return _type = Type.String; 215 } 216 217 public String toString() { 218 final StringBuffer buffer = new StringBuffer ("AVT:["); 219 final int count = elementCount(); 220 for (int i = 0; i < count; i++) { 221 buffer.append(elementAt(i).toString()); 222 if (i < count - 1) 223 buffer.append(' '); 224 } 225 return buffer.append(']').toString(); 226 } 227 228 public void translate(ClassGenerator classGen, MethodGenerator methodGen) { 229 if (elementCount() == 1) { 230 final Expression exp = (Expression)elementAt(0); 231 exp.translate(classGen, methodGen); 232 } 233 else { 234 final ConstantPoolGen cpg = classGen.getConstantPool(); 235 final InstructionList il = methodGen.getInstructionList(); 236 final int initBuffer = cpg.addMethodref(STRING_BUFFER_CLASS, 237 "<init>", "()V"); 238 final Instruction append = 239 new INVOKEVIRTUAL(cpg.addMethodref(STRING_BUFFER_CLASS, 240 "append", 241 "(" + STRING_SIG + ")" 242 + STRING_BUFFER_SIG)); 243 244 final int toString = cpg.addMethodref(STRING_BUFFER_CLASS, 245 "toString", 246 "()"+STRING_SIG); 247 il.append(new NEW(cpg.addClass(STRING_BUFFER_CLASS))); 248 il.append(DUP); 249 il.append(new INVOKESPECIAL(initBuffer)); 250 final Enumeration elements = elements(); 252 while (elements.hasMoreElements()) { 253 final Expression exp = (Expression)elements.nextElement(); 254 exp.translate(classGen, methodGen); 255 il.append(append); 256 } 257 il.append(new INVOKEVIRTUAL(toString)); 258 } 259 } 260 261 } 262 | Popular Tags |