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