001: /*
002: * Copyright 2007 Dan Shellman
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.iscreen.mvel;
017:
018: import org.mvel.ExpressionParser;
019: import org.mvel.CompileException;
020: import org.mvel.PropertyAccessException;
021: import org.mvel.PropertyAccessor;
022:
023: import org.iscreen.ConfigurationException;
024:
025: /**
026: * This class handles the mapping of data from one object to another.
027: * It uses the MVEL API to perform the actual mapping.
028: *
029: * @author Shellman, Dan
030: */
031: public class MvelObjectMapping {
032: protected String getterExp;
033: protected String setterExp;
034: protected Object getterAST;
035:
036: /**
037: * Default constructor taking the 'getter' MVEL expression and the
038: * 'setter' MVEL expression. This is a fail-fast call, so if the
039: * getter or setter MVEL expressions are "invalid," then an
040: * unchecked exception (ConfigurationException) will be thrown.
041: *
042: * @param getter The 'getter' OGNL expression.
043: * @param setter The 'setter' OGNL expression.
044: */
045: public MvelObjectMapping(String getter, String setter) {
046: getterExp = getter;
047: setterExp = setter;
048:
049: if (getter == null || setter == null) {
050: //TODO: This needs more detail
051: throw new ConfigurationException(
052: "MVEL setter/getter is null.");
053: }
054:
055: //Let's verify that the getter expression is valid right off the
056: //bat. It'll make the mapping run faster, anyway.
057: try {
058: getterAST = ExpressionParser.compileExpression(getterExp);
059: } catch (CompileException e) {
060: throw new ConfigurationException(
061: "Invalid 'getter' MVEL expression. MVEL expression is "
062: + getterExp, e);
063: }
064: } //end MvelObjectMapping()
065:
066: /**
067: * Maps a property from the fromBean to the toBean using the configured
068: * OGNL getter/setter expressions. If the objects can't accept the
069: * OGNL expressions, an unchecked ConfigurationException is thrown.
070: *
071: * @param fromBean The object to copy the property from (the source).
072: * @param toBean The object to copy the property to (the destination).
073: */
074: public void map(Object fromBean, Object toBean) {
075: Object value;
076:
077: try {
078: //First, get the value via MVEL
079: value = ExpressionParser.executeExpression(getterAST,
080: fromBean);
081:
082: //Then, set the value via MVEL
083: PropertyAccessor.set(toBean, setterExp, value);
084: } catch (PropertyAccessException e) {
085: throw new ConfigurationException(
086: "Mapping from one bean to another caused an MVEL exception. Getter MVEL expression is "
087: + getterExp
088: + ". Setter MVEL expression is "
089: + setterExp + ".", e);
090: }
091: } //end map()
092:
093: /**
094: * Retrieves the 'getter' MVEL expression that this mapper is configured
095: * to use.
096: *
097: * @return Returns the 'getter' MVEL expression.
098: */
099: public String getGetter() {
100: return getterExp;
101: } //end getGetter()
102:
103: /**
104: * Retrieves the 'setter' MVEL expression that this mapper is configured
105: * to use.
106: *
107: * @return Returns the 'setter' MVEL expression.
108: */
109: public String getSetter() {
110: return setterExp;
111: } //end getSetter()
112:
113: /**
114: * The hash code is based upon the 'setter' MVEL expression.
115: *
116: * @return Returns the hash code for this mapper.
117: */
118: public int hashCode() {
119: return setterExp.hashCode();
120: } //end hashCode()
121:
122: /**
123: * Equality is based upon the 'setter' MVEL expression (not the 'getter'
124: * expression).
125: *
126: * @param obj The mapper to compare to
127: *
128: * @return Returns true only if the 'setter' MVEL expressions are identical
129: * (meaning the Strings are equal).
130: */
131: public boolean equals(Object obj) {
132: MvelObjectMapping mapping;
133:
134: mapping = (MvelObjectMapping) obj;
135: if (setterExp != null && setterExp.equals(mapping.setterExp)) {
136: return true;
137: }
138:
139: return false;
140: } //end equals()
141: } //end MvelObjectMapping
|