1 25 package com.sun.el.lang; 26 27 import java.io.StringReader ; 28 import java.lang.reflect.Method ; 29 import java.util.Map ; 30 import java.util.concurrent.ConcurrentHashMap ; 31 32 import javax.el.ELContext; 33 import javax.el.ELException; 34 import javax.el.FunctionMapper; 35 import javax.el.MethodExpression; 36 import javax.el.ValueExpression; 37 import javax.el.VariableMapper; 38 39 import com.sun.el.MethodExpressionImpl; 40 import com.sun.el.MethodExpressionLiteral; 41 import com.sun.el.ValueExpressionImpl; 42 import com.sun.el.parser.AstCompositeExpression; 43 import com.sun.el.parser.AstDeferredExpression; 44 import com.sun.el.parser.AstDynamicExpression; 45 import com.sun.el.parser.AstFunction; 46 import com.sun.el.parser.AstIdentifier; 47 import com.sun.el.parser.AstLiteralExpression; 48 import com.sun.el.parser.AstValue; 49 import com.sun.el.parser.ELParser; 50 import com.sun.el.parser.Node; 51 import com.sun.el.parser.NodeVisitor; 52 import com.sun.el.parser.ParseException; 53 import com.sun.el.util.MessageFactory; 54 55 59 public final class ExpressionBuilder implements NodeVisitor { 60 61 private static final int SIZE = 5000; 62 private static final Map cache = new ConcurrentHashMap (SIZE); 63 private static final Map cache2 = new ConcurrentHashMap (SIZE); 64 65 private FunctionMapper fnMapper; 66 67 private VariableMapper varMapper; 68 69 private String expression; 70 71 74 public ExpressionBuilder(String expression, ELContext ctx) 75 throws ELException { 76 this.expression = expression; 77 78 FunctionMapper ctxFn = ctx.getFunctionMapper(); 79 VariableMapper ctxVar = ctx.getVariableMapper(); 80 81 if (ctxFn != null) { 82 this.fnMapper = new FunctionMapperFactory(ctxFn); 83 } 84 if (ctxVar != null) { 85 this.varMapper = new VariableMapperFactory(ctxVar); 86 } 87 } 88 89 public final static Node createNode(String expr) throws ELException { 90 Node n = createNodeInternal(expr); 91 return n; 92 } 93 94 private final static Node createNodeInternal(String expr) 95 throws ELException { 96 if (expr == null) { 97 throw new ELException(MessageFactory.get("error.null")); 98 } 99 100 Node n = (Node) cache.get(expr); 101 if (n == null && (n = (Node) cache2.get(expr)) == null) { 102 try { 103 n = (new ELParser(new StringReader (expr))) 104 .CompositeExpression(); 105 106 if (n instanceof AstCompositeExpression) { 108 int numChildren = n.jjtGetNumChildren(); 109 if (numChildren == 1) { 110 n = n.jjtGetChild(0); 111 } else { 112 Class type = null; 113 Node child = null; 114 for (int i = 0; i < numChildren; i++) { 115 child = n.jjtGetChild(i); 116 if (child instanceof AstLiteralExpression) 117 continue; 118 if (type == null) 119 type = child.getClass(); 120 else { 121 if (!type.equals(child.getClass())) { 122 throw new ELException(MessageFactory.get( 123 "error.mixed", expr)); 124 } 125 } 126 } 127 } 128 } 129 if (n instanceof AstDeferredExpression 130 || n instanceof AstDynamicExpression) { 131 n = n.jjtGetChild(0); 132 } 133 if (cache.size() > SIZE) { 134 cache2.clear(); 135 cache2.putAll(cache); 136 cache.clear(); 137 } 138 cache.put(expr, n); 139 } catch (ParseException pe) { 140 throw new ELException("Error Parsing: " + expr, pe); 141 } 142 } 143 return n; 144 } 145 146 private void prepare(Node node) throws ELException { 147 node.accept(this); 148 if (this.fnMapper instanceof FunctionMapperFactory) { 149 this.fnMapper = ((FunctionMapperFactory) this.fnMapper).create(); 150 } 151 if (this.varMapper instanceof VariableMapperFactory) { 152 this.varMapper = ((VariableMapperFactory) this.varMapper).create(); 153 } 154 } 155 156 private Node build() throws ELException { 157 Node n = createNodeInternal(this.expression); 158 this.prepare(n); 159 if (n instanceof AstDeferredExpression 160 || n instanceof AstDynamicExpression) { 161 n = n.jjtGetChild(0); 162 } 163 return n; 164 } 165 166 171 public void visit(Node node) throws ELException { 172 if (node instanceof AstFunction) { 173 174 AstFunction funcNode = (AstFunction) node; 175 176 if (this.fnMapper == null) { 177 throw new ELException(MessageFactory.get("error.fnMapper.null")); 178 } 179 Method m = fnMapper.resolveFunction(funcNode.getPrefix(), funcNode 180 .getLocalName()); 181 if (m == null) { 182 throw new ELException(MessageFactory.get( 183 "error.fnMapper.method", funcNode.getOutputName())); 184 } 185 int pcnt = m.getParameterTypes().length; 186 if (node.jjtGetNumChildren() != pcnt) { 187 throw new ELException(MessageFactory.get( 188 "error.fnMapper.paramcount", funcNode.getOutputName(), 189 "" + pcnt, "" + node.jjtGetNumChildren())); 190 } 191 } else if (node instanceof AstIdentifier && this.varMapper != null) { 192 String variable = ((AstIdentifier) node).getImage(); 193 194 this.varMapper.resolveVariable(variable); 196 } 197 } 198 199 public ValueExpression createValueExpression(Class expectedType) 200 throws ELException { 201 Node n = this.build(); 202 return new ValueExpressionImpl(this.expression, n, this.fnMapper, 203 this.varMapper, expectedType); 204 } 205 206 public MethodExpression createMethodExpression(Class expectedReturnType, 207 Class [] expectedParamTypes) throws ELException { 208 Node n = this.build(); 209 if (n instanceof AstValue || n instanceof AstIdentifier) { 210 return new MethodExpressionImpl(expression, n, 211 this.fnMapper, this.varMapper, expectedReturnType, 212 expectedParamTypes); 213 } else if (n instanceof AstLiteralExpression) { 214 return new MethodExpressionLiteral(expression, expectedReturnType, 215 expectedParamTypes); 216 } else { 217 throw new ELException("Not a Valid Method Expression: " 218 + expression); 219 } 220 } 221 } 222 | Popular Tags |