1 16 19 20 package org.apache.xalan.xsltc.compiler; 21 22 import java.util.Enumeration ; 23 import java.util.Vector ; 24 25 import org.apache.bcel.generic.ConstantPoolGen; 26 import org.apache.bcel.generic.INVOKESPECIAL; 27 import org.apache.bcel.generic.INVOKEVIRTUAL; 28 import org.apache.bcel.generic.Instruction; 29 import org.apache.bcel.generic.InstructionList; 30 import org.apache.bcel.generic.NEW; 31 import org.apache.xalan.xsltc.compiler.util.ClassGenerator; 32 import org.apache.xalan.xsltc.compiler.util.ErrorMsg; 33 import org.apache.xalan.xsltc.compiler.util.MethodGenerator; 34 import org.apache.xalan.xsltc.compiler.util.Type; 35 import org.apache.xalan.xsltc.compiler.util.TypeCheckError; 36 37 41 final class AttributeValueTemplate extends AttributeValue { 42 43 public AttributeValueTemplate(String value, Parser parser, 44 SyntaxTreeNode parent) 45 { 46 setParent(parent); 47 setParser(parser); 48 if (check(value, parser)) { 49 parseAVTemplate(0, value, parser); 50 } 51 } 52 53 private void parseAVTemplate(final int start, String text, Parser parser) { 54 String str; 55 56 if (text == null) return; 57 58 int open = start - 2; 60 do { 61 open = text.indexOf('{', open+2); 62 } while ((open != -1) && 63 (open < (text.length()-1)) && 64 (text.charAt(open+1) == '{')); 65 66 if (open != -1) { 67 int close = open - 2; 69 do { 70 close = text.indexOf('}', close+2); 71 } while ((close != -1) && 72 (close < (text.length()-1)) && 73 (text.charAt(close+1) == '}')); 74 75 if (open > start) { 77 str = removeDuplicateBraces(text.substring(start, open)); 78 addElement(new LiteralExpr(str)); 79 } 80 if (close > open + 1) { 82 str = text.substring(open + 1, close); 83 str = removeDuplicateBraces(text.substring(open+1,close)); 84 addElement(parser.parseExpression(this, str)); 85 } 86 parseAVTemplate(close + 1, text, parser); 88 89 } 90 else if (start < text.length()) { 91 str = removeDuplicateBraces(text.substring(start)); 93 addElement(new LiteralExpr(str)); 94 } 95 } 96 97 public String removeDuplicateBraces(String orig) { 98 String result = orig; 99 int index; 100 101 while ((index = result.indexOf("{{")) != -1) { 102 result = result.substring(0,index) + 103 result.substring(index+1,result.length()); 104 } 105 106 while ((index = result.indexOf("}}")) != -1) { 107 result = result.substring(0,index) + 108 result.substring(index+1,result.length()); 109 } 110 111 return(result); 112 } 113 114 public Type typeCheck(SymbolTable stable) throws TypeCheckError { 115 final Vector contents = getContents(); 116 final int n = contents.size(); 117 for (int i = 0; i < n; i++) { 118 final Expression exp = (Expression)contents.elementAt(i); 119 if (!exp.typeCheck(stable).identicalTo(Type.String)) { 120 contents.setElementAt(new CastExpr(exp, Type.String), i); 121 } 122 } 123 return _type = Type.String; 124 } 125 126 public String toString() { 127 final StringBuffer buffer = new StringBuffer ("AVT:["); 128 final int count = elementCount(); 129 for (int i = 0; i < count; i++) { 130 buffer.append(elementAt(i).toString()); 131 if (i < count - 1) 132 buffer.append(' '); 133 } 134 return buffer.append(']').toString(); 135 } 136 137 public void translate(ClassGenerator classGen, MethodGenerator methodGen) { 138 if (elementCount() == 1) { 139 final Expression exp = (Expression)elementAt(0); 140 exp.translate(classGen, methodGen); 141 } 142 else { 143 final ConstantPoolGen cpg = classGen.getConstantPool(); 144 final InstructionList il = methodGen.getInstructionList(); 145 final int initBuffer = cpg.addMethodref(STRING_BUFFER_CLASS, 146 "<init>", "()V"); 147 final Instruction append = 148 new INVOKEVIRTUAL(cpg.addMethodref(STRING_BUFFER_CLASS, 149 "append", 150 "(" + STRING_SIG + ")" 151 + STRING_BUFFER_SIG)); 152 153 final int toString = cpg.addMethodref(STRING_BUFFER_CLASS, 154 "toString", 155 "()"+STRING_SIG); 156 il.append(new NEW(cpg.addClass(STRING_BUFFER_CLASS))); 157 il.append(DUP); 158 il.append(new INVOKESPECIAL(initBuffer)); 159 final Enumeration elements = elements(); 161 while (elements.hasMoreElements()) { 162 final Expression exp = (Expression)elements.nextElement(); 163 exp.translate(classGen, methodGen); 164 il.append(append); 165 } 166 il.append(new INVOKEVIRTUAL(toString)); 167 } 168 } 169 170 private boolean check(String value, Parser parser) { 171 if (value == null) return true; 173 174 final char[] chars = value.toCharArray(); 175 int level = 0; 176 for (int i = 0; i < chars.length; i++) { 177 switch (chars[i]) { 178 case '{': 179 if (((i+1) == (chars.length)) || (chars[i+1] != '{')) 180 ++level; 181 else 182 i++; 183 break; 184 case '}': 185 if (((i+1) == (chars.length)) || (chars[i+1] != '}')) 186 --level; 187 else 188 i++; 189 break; 190 default: 191 continue; 192 } 193 switch (level) { 194 case 0: 195 case 1: 196 continue; 197 default: 198 reportError(getParent(), parser, 199 ErrorMsg.ATTR_VAL_TEMPLATE_ERR, value); 200 return false; 201 } 202 } 203 if (level != 0) { 204 reportError(getParent(), parser, 205 ErrorMsg.ATTR_VAL_TEMPLATE_ERR, value); 206 return false; 207 } 208 return true; 209 } 210 } 211 | Popular Tags |