001: /**
002: * MVEL (The MVFLEX Expression Language)
003: *
004: * Copyright (C) 2007 Christopher Brock, MVFLEX/Valhalla Project and the Codehaus
005: *
006: * Licensed under the Apache License, Version 2.0 (the "License");
007: * you may not use this file except in compliance with the License.
008: * You may obtain a copy of the License at
009: *
010: * http://www.apache.org/licenses/LICENSE-2.0
011: *
012: * Unless required by applicable law or agreed to in writing, software
013: * distributed under the License is distributed on an "AS IS" BASIS,
014: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
015: * See the License for the specific language governing permissions and
016: * limitations under the License.
017: *
018: */package org.mvel.compiler;
019:
020: import static org.mvel.MVELRuntime.execute;
021: import org.mvel.ParserContext;
022: import org.mvel.integration.VariableResolverFactory;
023: import org.mvel.optimizers.AccessorOptimizer;
024: import org.mvel.optimizers.OptimizerFactory;
025: import org.mvel.util.ASTIterator;
026: import org.mvel.util.ASTLinkedList;
027: import static org.mvel.util.ParseTools.handleParserEgress;
028:
029: import java.io.Serializable;
030:
031: public class CompiledExpression implements Serializable,
032: ExecutableStatement {
033: private ASTIterator tokens;
034:
035: private Class knownEgressType;
036: private Class knownIngressType;
037:
038: private boolean convertableIngressEgress;
039: private boolean optimized = false;
040: private boolean importInjectionRequired = false;
041: private boolean returnBigDecimal = false;
042: private boolean literalOnly;
043:
044: private Class<? extends AccessorOptimizer> accessorOptimizer;
045:
046: private String sourceName;
047:
048: private ParserContext parserContext;
049:
050: public CompiledExpression(ASTIterator astMap, String sourceName,
051: Class egressType, ParserContext ctx, boolean literalOnly) {
052: this .tokens = astMap;
053: this .sourceName = sourceName;
054: this .knownEgressType = egressType;
055: this .literalOnly = literalOnly;
056: setParserContext(ctx);
057: }
058:
059: public CompiledExpression(ASTIterator astMap, String sourceName,
060: boolean literalOnly) {
061: this .tokens = astMap;
062: this .sourceName = sourceName;
063: this .literalOnly = literalOnly;
064: }
065:
066: public ASTIterator getInstructions() {
067: return new ASTLinkedList(tokens.firstNode(), tokens.size());
068: }
069:
070: public void setInstructions(ASTIterator tokens) {
071: this .tokens = tokens;
072: }
073:
074: public Class getKnownEgressType() {
075: return knownEgressType;
076: }
077:
078: public void setKnownEgressType(Class knownEgressType) {
079: this .knownEgressType = knownEgressType;
080: }
081:
082: public Class getKnownIngressType() {
083: return knownIngressType;
084: }
085:
086: public void setKnownIngressType(Class knownIngressType) {
087: this .knownIngressType = knownIngressType;
088: }
089:
090: public boolean isConvertableIngressEgress() {
091: return convertableIngressEgress;
092: }
093:
094: public void setConvertableIngressEgress(
095: boolean convertableIngressEgress) {
096: this .convertableIngressEgress = convertableIngressEgress;
097: }
098:
099: public void computeTypeConversionRule() {
100: if (knownIngressType != null && knownEgressType != null) {
101: convertableIngressEgress = knownIngressType
102: .isAssignableFrom(knownEgressType);
103: }
104: }
105:
106: public Object getValue(Object ctx, Object elCtx,
107: VariableResolverFactory variableFactory) {
108: if (!optimized)
109: setupOptimizers();
110: return getValue(ctx, variableFactory);
111: }
112:
113: public Object getValue(Object staticContext,
114: VariableResolverFactory factory) {
115: if (!optimized)
116: setupOptimizers();
117: return handleParserEgress(execute(false, this , staticContext,
118: factory), returnBigDecimal);
119: }
120:
121: public Object getDirectValue(Object staticContext,
122: VariableResolverFactory factory) {
123: return execute(false, this , staticContext, factory);
124: }
125:
126: private void setupOptimizers() {
127: if (accessorOptimizer != null)
128: OptimizerFactory
129: .setThreadAccessorOptimizer(accessorOptimizer);
130: optimized = true;
131: }
132:
133: public ASTIterator getTokenIterator() {
134: //return new ASTArrayList(tokens);
135: return tokens;
136: }
137:
138: public boolean isOptimized() {
139: return optimized;
140: }
141:
142: public void setOptimized(boolean optimized) {
143: this .optimized = optimized;
144: }
145:
146: public Class<? extends AccessorOptimizer> getAccessorOptimizer() {
147: return accessorOptimizer;
148: }
149:
150: public void setAccessorOptimizer(
151: Class<? extends AccessorOptimizer> accessorOptimizer) {
152: this .accessorOptimizer = accessorOptimizer;
153: }
154:
155: public String getSourceName() {
156: return sourceName;
157: }
158:
159: public void setSourceName(String sourceName) {
160: this .sourceName = sourceName;
161: }
162:
163: public boolean intOptimized() {
164: return false;
165: }
166:
167: public ParserContext getParserContext() {
168: return parserContext;
169: }
170:
171: public void setParserContext(ParserContext parserContext) {
172: if ((this .parserContext = parserContext) != null) {
173: this .importInjectionRequired = parserContext.getImports() != null
174: && parserContext.getImports().size() != 0;
175: }
176: }
177:
178: public boolean isReturnBigDecimal() {
179: return returnBigDecimal;
180: }
181:
182: public void setReturnBigDecimal(boolean returnBigDecimal) {
183: this .returnBigDecimal = returnBigDecimal;
184: }
185:
186: public boolean isImportInjectionRequired() {
187: return importInjectionRequired;
188: }
189:
190: public void setImportInjectionRequired(
191: boolean importInjectionRequired) {
192: this .importInjectionRequired = importInjectionRequired;
193: }
194:
195: public Object setValue(Object ctx, Object elCtx,
196: VariableResolverFactory variableFactory, Object value) {
197: return null;
198: }
199:
200: public boolean isLiteralOnly() {
201: return literalOnly;
202: }
203: }
|