001: /*
002: * Copyright 2004-2007 the original author or authors.
003: *
004: * Licensed under the Apache License, Version 2.0 (the "License");
005: * you may not use this file except in compliance with the License.
006: * You may obtain a copy of the License at
007: *
008: * http://www.apache.org/licenses/LICENSE-2.0
009: *
010: * Unless required by applicable law or agreed to in writing, software
011: * distributed under the License is distributed on an "AS IS" BASIS,
012: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013: * See the License for the specific language governing permissions and
014: * limitations under the License.
015: */
016: package org.springframework.binding.expression.support;
017:
018: import java.util.Collections;
019: import java.util.Map;
020:
021: import ognl.Ognl;
022: import ognl.OgnlException;
023:
024: import org.springframework.binding.expression.EvaluationAttempt;
025: import org.springframework.binding.expression.EvaluationContext;
026: import org.springframework.binding.expression.EvaluationException;
027: import org.springframework.binding.expression.SetValueAttempt;
028: import org.springframework.binding.expression.SettableExpression;
029: import org.springframework.util.Assert;
030:
031: /**
032: * Evaluates a parsed Ognl expression.
033: * <p>
034: * IMPLEMENTATION NOTE: Ognl 2.6.7 expression objects do not respect equality
035: * properly, so the equality operations defined within this class do not
036: * function properly.
037: *
038: * @author Keith Donald
039: */
040: class OgnlExpression implements SettableExpression {
041:
042: /**
043: * The expression.
044: */
045: private Object expression;
046:
047: /**
048: * Creates a new OGNL expression.
049: * @param expression the parsed expression
050: */
051: public OgnlExpression(Object expression) {
052: this .expression = expression;
053: }
054:
055: public int hashCode() {
056: return expression.hashCode();
057: }
058:
059: public boolean equals(Object o) {
060: if (!(o instanceof OgnlExpression)) {
061: return false;
062: }
063: // as late as Ognl 2.6.7, their expression objects don't implement equals
064: // so this always returns false
065: OgnlExpression other = (OgnlExpression) o;
066: return expression.equals(other.expression);
067: }
068:
069: public Object evaluate(Object target, EvaluationContext context)
070: throws EvaluationException {
071: Assert.notNull(target,
072: "The target object to evaluate is required");
073: Map contextAttributes = (context != null ? context
074: .getAttributes() : Collections.EMPTY_MAP);
075: try {
076: return Ognl.getValue(expression, contextAttributes, target);
077: } catch (OgnlException e) {
078: if (e.getReason() != null && e.getReason() != e) {
079: // unwrap the OgnlException since the actual exception is wrapped inside it
080: // and there is not generic (getCause) way to get to it later on
081: throw new EvaluationException(new EvaluationAttempt(
082: this , target, context), e.getReason());
083: } else {
084: throw new EvaluationException(new EvaluationAttempt(
085: this , target, context), e);
086: }
087: }
088: }
089:
090: public void evaluateToSet(Object target, Object value,
091: EvaluationContext context) {
092: Assert.notNull(target,
093: "The target object to evaluate is required");
094: Map contextAttributes = (context != null ? context
095: .getAttributes() : Collections.EMPTY_MAP);
096: try {
097: Ognl.setValue(expression, contextAttributes, target, value);
098: } catch (OgnlException e) {
099: throw new EvaluationException(new SetValueAttempt(this ,
100: target, value, context), e);
101: }
102: }
103:
104: public String toString() {
105: return expression.toString();
106: }
107: }
|