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.ast;
019:
020: import static org.mvel.MVEL.compileSetExpression;
021: import static org.mvel.MVEL.eval;
022: import static org.mvel.PropertyAccessor.set;
023: import org.mvel.compiler.Accessor;
024: import org.mvel.compiler.CompiledSetExpression;
025: import org.mvel.compiler.ExecutableStatement;
026: import org.mvel.compiler.AbstractParser;
027: import org.mvel.integration.VariableResolverFactory;
028: import static org.mvel.util.ParseTools.*;
029: import static org.mvel.util.PropertyTools.find;
030:
031: /**
032: * @author Christopher Brock
033: */
034: public class DeepAssignmentNode extends ASTNode implements Assignment {
035: private String property;
036: private char[] stmt;
037:
038: private CompiledSetExpression set;
039: private transient Accessor statement;
040:
041: public DeepAssignmentNode(char[] expr, int fields, int operation,
042: String name) {
043: // super(expr, fields);
044:
045: this .name = expr;
046: int mark;
047:
048: if (operation != -1) {
049: this .egressType = ((ExecutableStatement) (statement = (ExecutableStatement) subCompileExpression(stmt = createShortFormOperativeAssignment(
050: this .property = name.trim(), expr, operation))))
051: .getKnownEgressType();
052:
053: } else if ((mark = find(expr, '=')) != -1) {
054: property = new String(expr, 0, mark).trim();
055: stmt = subset(expr, mark + 1);
056:
057: if ((fields & COMPILE_IMMEDIATE) != 0) {
058: statement = (ExecutableStatement) subCompileExpression(stmt);
059: }
060: } else {
061: property = new String(expr);
062: }
063:
064: if ((fields & COMPILE_IMMEDIATE) != 0) {
065: set = (CompiledSetExpression) compileSetExpression(property
066: .toCharArray());
067: AbstractParser.getCurrentThreadParserContext().addVariable(
068: name, egressType);
069: }
070: }
071:
072: public DeepAssignmentNode(char[] expr, int fields) {
073: this (expr, fields, -1, null);
074: }
075:
076: public Object getReducedValueAccelerated(Object ctx,
077: Object this Value, VariableResolverFactory factory) {
078: if (statement == null) {
079: statement = (ExecutableStatement) subCompileExpression(stmt);
080: set = (CompiledSetExpression) compileSetExpression(property
081: .toCharArray());
082: }
083:
084: // Object val;
085: set.setValue(ctx, factory, ctx = statement.getValue(ctx,
086: this Value, factory));
087: return ctx;
088: }
089:
090: public Object getReducedValue(Object ctx, Object this Value,
091: VariableResolverFactory factory) {
092: // Object val;
093: set(ctx, factory, property, ctx = eval(stmt, ctx, factory));
094: return ctx;
095: }
096:
097: public String getAssignmentVar() {
098: return property;
099: }
100:
101: public char[] getExpression() {
102: return stmt;
103: }
104:
105: public boolean isNewDeclaration() {
106: return false;
107: }
108: }
|