KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > beehive > netui > script > el > ExpressionTerm


1 /*
2  * Copyright 2004 The Apache Software Foundation.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  *
16  * $Header:$
17  */

18 package org.apache.beehive.netui.script.el;
19
20 import org.apache.beehive.netui.util.internal.InternalStringBuilder;
21
22 import java.util.ArrayList JavaDoc;
23 import java.util.Collections JavaDoc;
24 import java.util.Iterator JavaDoc;
25 import java.util.List JavaDoc;
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 /**
38  *
39  */

40 public class ExpressionTerm
41     extends Expression
42     implements Term {
43
44     private static Logger LOGGER = Logger.getInstance(ExpressionTerm.class);
45
46     private List JavaDoc _tokens = null;
47     private String JavaDoc _exprStr = null;
48     private ContextToken _context = null;
49     private ExpressionToken[] _tokenArray = null;
50     private List JavaDoc _noModTokens = null;
51
52     public ExpressionTerm() {
53         super();
54         _tokens = new ArrayList JavaDoc();
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 JavaDoc getContext() {
73         return _context.getName();
74     }
75
76     public List JavaDoc getTokens() {
77         return _noModTokens;
78     }
79
80     public String JavaDoc getExpression(int start) {
81         if(start >= _tokens.size())
82             throw new IllegalStateException JavaDoc("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 JavaDoc getExpressionTokens() {
111         return _tokens.iterator();
112     }
113
114     public int getTokenCount() {
115         return _tokenArray.length;
116     }
117
118     public ExpressionToken getToken(int index) {
119         // @TODO: error checking
120
return _tokenArray[index];
121     }
122
123     public String JavaDoc getExpressionString() {
124         return _exprStr;
125     }
126
127     public Object JavaDoc evaluate(NetUIVariableResolver vr) {
128         return _evaluate(_tokens.size(), vr);
129     }
130
131     public void update(Object JavaDoc newValue, NetUIVariableResolver vr) {
132         // find leaf
133
Object JavaDoc 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         // apply value
140
token.update(branch, newValue);
141     }
142
143     /* todo: perf. this could be done more effectively / efficiently */
144     public String JavaDoc changeContext(String JavaDoc oldContext, String JavaDoc newContext, Object JavaDoc index) {
145         String JavaDoc thisExpr = getExpressionString();
146
147         if(LOGGER.isDebugEnabled()) LOGGER.debug("oldContext: " + oldContext + " newContext: " + newContext + " thisExpr: " + thisExpr);
148
149         // needs to be checked for atomicity
150
ParsedExpression pe = ParseUtils.parse(newContext);
151
152         if(!pe.isExpression()) {
153             String JavaDoc 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 JavaDoc(msg);
156         }
157
158         // this isn't a failure; it just means that there isn't anything else to replace
159
if(!thisExpr.startsWith(oldContext)) {
160             return "{" + thisExpr + "}";
161         }
162
163         if(index instanceof Integer JavaDoc && ((Integer JavaDoc)index).intValue() > 32767) {
164             String JavaDoc 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 JavaDoc(msg);
169         }
170
171         String JavaDoc 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 JavaDoc qualify(String JavaDoc 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 JavaDoc 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 JavaDoc _evaluate(int index, NetUIVariableResolver vr) {
208         Object JavaDoc 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