1 18 package org.apache.beehive.netui.script.el; 19 20 import org.apache.beehive.netui.util.internal.InternalStringBuilder; 21 22 import java.util.ArrayList ; 23 import java.util.Collections ; 24 import java.util.Iterator ; 25 import java.util.List ; 26 27 import org.apache.beehive.netui.script.Expression; 28 import org.apache.beehive.netui.script.el.tokens.ArrayIndexToken; 29 import org.apache.beehive.netui.script.el.tokens.ContextToken; 30 import org.apache.beehive.netui.script.el.tokens.ExpressionToken; 31 import org.apache.beehive.netui.script.el.tokens.IdentifierToken; 32 import org.apache.beehive.netui.script.el.tokens.MapKeyToken; 33 import org.apache.beehive.netui.script.el.util.BindingContext; 34 import org.apache.beehive.netui.script.el.util.ParseUtils; 35 import org.apache.beehive.netui.util.logging.Logger; 36 37 40 public class ExpressionTerm 41 extends Expression 42 implements Term { 43 44 private static Logger LOGGER = Logger.getInstance(ExpressionTerm.class); 45 46 private List _tokens = null; 47 private String _exprStr = null; 48 private ContextToken _context = null; 49 private ExpressionToken[] _tokenArray = null; 50 private List _noModTokens = null; 51 52 public ExpressionTerm() { 53 super(); 54 _tokens = new ArrayList (); 55 } 56 57 public void seal() { 58 _context = (ContextToken)_tokens.get(0); 59 _tokenArray = new ExpressionToken[_tokens.size()]; 60 61 InternalStringBuilder buf = new InternalStringBuilder(); 62 for(int i = 0; i < _tokens.size(); i++) { 63 buf.append(((ExpressionToken)_tokens.get(i)).getTokenString()); 64 _tokenArray[i] = (ExpressionToken)_tokens.get(i); 65 } 66 67 _exprStr = buf.toString(); 68 69 _noModTokens = Collections.unmodifiableList(_tokens); 70 } 71 72 public String getContext() { 73 return _context.getName(); 74 } 75 76 public List getTokens() { 77 return _noModTokens; 78 } 79 80 public String getExpression(int start) { 81 if(start >= _tokens.size()) 82 throw new IllegalStateException ("The index \"" + start + "\" is an invalid reference into an expression with \"" + 83 _tokens.size() + "\" _tokens."); 84 85 boolean needDot = true; 86 InternalStringBuilder buf = new InternalStringBuilder(); 87 buf.append("{"); 88 for(int i = start; i < _tokens.size(); i++) { 89 ExpressionToken tok = (ExpressionToken)_tokens.get(i); 90 if(tok instanceof ArrayIndexToken) { 91 buf.append(tok.getTokenString()); 92 needDot = false; 93 } else if(tok instanceof IdentifierToken) { 94 if(needDot && i != start) buf.append("."); 95 buf.append(tok.toString()); 96 needDot = true; 97 } else if(tok instanceof MapKeyToken) { 98 buf.append(tok.getTokenString()); 99 needDot = false; 100 } 101 } 102 buf.append("}"); 103 return buf.toString(); 104 } 105 106 public void addToken(ExpressionToken token) { 107 _tokens.add(token); 108 } 109 110 public Iterator getExpressionTokens() { 111 return _tokens.iterator(); 112 } 113 114 public int getTokenCount() { 115 return _tokenArray.length; 116 } 117 118 public ExpressionToken getToken(int index) { 119 return _tokenArray[index]; 121 } 122 123 public String getExpressionString() { 124 return _exprStr; 125 } 126 127 public Object evaluate(NetUIVariableResolver vr) { 128 return _evaluate(_tokens.size(), vr); 129 } 130 131 public void update(Object newValue, NetUIVariableResolver vr) { 132 Object branch = _evaluate(_tokens.size() - 1, vr); 134 135 ExpressionToken token = _tokenArray[_tokens.size() - 1]; 136 137 if(LOGGER.isDebugEnabled()) LOGGER.debug("Update leaf token: " + token + " on object: " + branch); 138 139 token.update(branch, newValue); 141 } 142 143 144 public String changeContext(String oldContext, String newContext, Object index) { 145 String thisExpr = getExpressionString(); 146 147 if(LOGGER.isDebugEnabled()) LOGGER.debug("oldContext: " + oldContext + " newContext: " + newContext + " thisExpr: " + thisExpr); 148 149 ParsedExpression pe = ParseUtils.parse(newContext); 151 152 if(!pe.isExpression()) { 153 String msg = "The expression can not be qualified into new _context because the new _context is not atomic."; 154 if(LOGGER.isErrorEnabled()) LOGGER.error(msg); 155 throw new RuntimeException (msg); 156 } 157 158 if(!thisExpr.startsWith(oldContext)) { 160 return "{" + thisExpr + "}"; 161 } 162 163 if(index instanceof Integer && ((Integer )index).intValue() > 32767) { 164 String msg = "Can not create an indexed expression with an array index greater than the Java array limit for the expression \"" + 165 thisExpr + "\""; 166 167 if(LOGGER.isWarnEnabled()) LOGGER.warn(msg); 168 throw new RuntimeException (msg); 169 } 170 171 String ctxStr = pe.getExpressionString(); 172 173 ctxStr = ctxStr + "[" + index + "]"; 174 175 if(LOGGER.isDebugEnabled()) LOGGER.debug("thisExpr: " + thisExpr + " ctxStr: " + ctxStr); 176 177 thisExpr = thisExpr.replaceFirst(oldContext, ctxStr); 178 179 InternalStringBuilder buf = new InternalStringBuilder(); 180 buf.append("{"); 181 buf.append(thisExpr); 182 buf.append("}"); 183 184 return buf.toString(); 185 } 186 187 public String qualify(String contextName) { 188 InternalStringBuilder buf = new InternalStringBuilder(); 189 buf.append("{"); 190 buf.append(contextName); 191 buf.append("."); 192 buf.append(getExpressionString()); 193 buf.append("}"); 194 195 return buf.toString(); 196 } 197 198 public String toString() { 199 InternalStringBuilder buf = new InternalStringBuilder(); 200 buf.append("ExpressionTerm:\n"); 201 for(int i = 0; i < _tokens.size(); i++) { 202 buf.append(" " + _tokens.get(i).toString() + "\n"); 203 } 204 return buf.toString(); 205 } 206 207 private final Object _evaluate(int index, NetUIVariableResolver vr) { 208 Object result = null; 209 210 if(_tokens.size() == 1) { 211 if(LOGGER.isDebugEnabled()) LOGGER.debug("found single term expression"); 212 213 result = vr.resolveVariable(_context.getName()); 214 215 if(result != null && result instanceof BindingContext) { 216 if(LOGGER.isDebugEnabled()) 217 LOGGER.debug("result is of type BindingContext; return type: " + (((BindingContext)result).unwrap().getClass())); 218 219 return ((BindingContext)result).unwrap(); 220 } else 221 return result; 222 } else { 223 for(int i = 0; i < index; i++) { 224 if(i == 0) { 225 result = vr.resolveVariable(_context.getName()); 226 } else 227 result = _tokenArray[i].evaluate(result); 228 } 229 230 return result; 231 } 232 } 233 } 234 | Popular Tags |